Merge "Support to get the exact task which IME is attached to" into tm-dev
diff --git a/Android.bp b/Android.bp
index 933d1af..753cefc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -25,18 +25,6 @@
 //
 // READ ME: ########################################################
 
-// TODO(b/21090328): Remove filter after we are ready to.
-soong_config_module_type {
-    name: "java_library_with_nonpublic_deps",
-    module_type: "java_library",
-    config_namespace: "ANDROID",
-    bool_variables: ["include_nonpublic_framework_api"],
-    properties: [
-        "static_libs",
-        "libs",
-    ],
-}
-
 package {
     default_applicable_licenses: ["frameworks_base_license"],
 }
@@ -132,7 +120,6 @@
         ":installd_aidl",
         ":libaudioclient_aidl",
         ":libbinder_aidl",
-        ":libbluetooth-binder-aidl",
         ":libcamera_client_aidl",
         ":libcamera_client_framework_aidl",
         ":libupdate_engine_aidl",
@@ -152,7 +139,7 @@
     ],
 }
 
-java_library_with_nonpublic_deps {
+java_library {
     name: "framework-all",
     installable: false,
     static_libs: [
@@ -273,7 +260,6 @@
     defaults: ["framework-aidl-export-defaults"],
     srcs: [
         ":framework-non-updatable-sources",
-        ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
         "core/java/**/*.logtags",
         ":apex-info-list",
     ],
@@ -287,6 +273,7 @@
             "frameworks/native/libs/permission/aidl",
             // TODO: remove when moved to the below package
             "frameworks/base/packages/ConnectivityT/framework-t/aidl-export",
+            "packages/modules/Bluetooth/framework/aidl-export",
             "packages/modules/Connectivity/framework/aidl-export",
             "packages/modules/Media/apex/aidl/stable",
             "hardware/interfaces/graphics/common/aidl",
@@ -357,7 +344,6 @@
     visibility: [
         "//frameworks/base",
         // TODO(b/147128803) remove the below lines
-        "//frameworks/base/apex/appsearch/framework",
         "//frameworks/base/apex/blobstore/framework",
         "//frameworks/base/apex/jobscheduler/framework",
         "//frameworks/base/packages/Tethering/tests/unit",
@@ -545,8 +531,9 @@
             "frameworks/native/libs/permission/aidl",
             // TODO: remove when moved to the below package
             "frameworks/base/packages/ConnectivityT/framework-t/aidl-export",
-            "packages/modules/Media/apex/aidl/stable",
+            "packages/modules/Bluetooth/framework/aidl-export",
             "packages/modules/Connectivity/framework/aidl-export",
+            "packages/modules/Media/apex/aidl/stable",
             "hardware/interfaces/graphics/common/aidl",
         ],
     },
@@ -584,6 +571,7 @@
     name: "module-classpath-stubs-defaults",
     aidl: {
         include_dirs: [
+            "packages/modules/Bluetooth/framework/aidl-export",
             "packages/modules/Connectivity/framework/aidl-export",
             "packages/modules/Media/apex/aidl/stable",
         ],
diff --git a/ApiDocs.bp b/ApiDocs.bp
index ba31161..038ee65 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -79,8 +79,8 @@
         ":conscrypt.module.public.api{.public.stubs.source}",
         ":i18n.module.public.api{.public.stubs.source}",
 
+        ":framework-adservices-sources",
         ":framework-appsearch-sources",
-        ":framework-auxiliary-sources",
         ":framework-connectivity-sources",
         ":framework-bluetooth-sources",
         ":framework-connectivity-tiramisu-updatable-sources",
@@ -93,7 +93,7 @@
         ":framework-scheduling-sources",
         ":framework-sdkextensions-sources",
         ":framework-statsd-sources",
-        ":framework-supplementalprocess-sources",
+        ":framework-sdksandbox-sources",
         ":framework-tethering-srcs",
         ":framework-uwb-updatable-sources",
         ":framework-wifi-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 94f4374..32101c7 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -23,14 +23,6 @@
 // and comparing them against the checked in API signature, and also checking compatibility
 // with the latest frozen API signature.
 
-// TODO(b/21090328): Remove filter after we are ready to.
-soong_config_module_type_import {
-    from: "frameworks/base/Android.bp",
-    module_types: [
-        "java_library_with_nonpublic_deps",
-    ],
-}
-
 /////////////////////////////////////////////////////////////////////
 // These modules provide source files for the stub libraries
 /////////////////////////////////////////////////////////////////////
@@ -216,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
@@ -232,7 +234,7 @@
     visibility: ["//visibility:private"],
 }
 
-java_library_with_nonpublic_deps {
+java_library {
     name: "android-non-updatable.stubs",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":api-stubs-docs-non-updatable"],
@@ -242,7 +244,7 @@
     },
 }
 
-java_library_with_nonpublic_deps {
+java_library {
     name: "android-non-updatable.stubs.system",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":system-api-stubs-docs-non-updatable"],
@@ -270,7 +272,7 @@
     },
 }
 
-java_library_with_nonpublic_deps {
+java_library {
     name: "android-non-updatable.stubs.test",
     defaults: ["android-non-updatable_defaults_stubs_current"],
     srcs: [":test-api-stubs-docs-non-updatable"],
@@ -290,7 +292,7 @@
     defaults_visibility: ["//frameworks/base/services"],
 }
 
-java_library_with_nonpublic_deps {
+java_library {
     name: "android_stubs_current",
     static_libs: [
         "all-modules-public-stubs",
@@ -300,7 +302,7 @@
     defaults: ["android.jar_defaults"],
 }
 
-java_library_with_nonpublic_deps {
+java_library {
     name: "android_system_stubs_current",
     static_libs: [
         "all-modules-system-stubs",
@@ -324,7 +326,7 @@
     ],
 }
 
-java_library_with_nonpublic_deps {
+java_library {
     name: "android_test_stubs_current",
     // Modules do not have test APIs, but we want to include their SystemApis, like we include
     // the SystemApi of framework-non-updatable-sources.
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index ffa534e..c83ca8c 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -1377,7 +1377,7 @@
     }
 
     private boolean isAllowedBlobAccess(int uid, String packageName) {
-        return (!Process.isSupplemental(uid) && !Process.isIsolated(uid)
+        return (!Process.isSdkSandboxUid(uid) && !Process.isIsolated(uid)
                 && !mPackageManagerInternal.isInstantApp(packageName, UserHandle.getUserId(uid)));
     }
 
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index 13ecd25..e2426c2 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -143,6 +143,11 @@
     void setAppStandbyBuckets(@NonNull List<AppStandbyInfo> appBuckets, int userId, int callingUid,
             int callingPid);
 
+    /** Return the lowest bucket this app can enter. */
+    @StandbyBuckets
+    int getAppMinStandbyBucket(String packageName, int appId, int userId,
+            boolean shouldObfuscateInstantApps);
+
     /**
      * Put the specified app in the
      * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 2b0a833..ee0f9e8 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -37,7 +37,6 @@
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.IUidObserver;
-import android.app.job.JobInfo;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStatsManagerInternal;
 import android.app.usage.UsageStatsManagerInternal.UsageEventListener;
@@ -166,28 +165,6 @@
         public long inQuotaTimeElapsed;
 
         /**
-         * The time after which the app will be under the bucket quota and can start running
-         * low priority jobs again. This is only valid if
-         * {@link #executionTimeInWindowMs} >=
-         *        {@link #mAllowedTimePerPeriodMs} * (1 - {@link #mAllowedTimeSurplusPriorityLow}),
-         * {@link #executionTimeInMaxPeriodMs} >= {@link #mMaxExecutionTimeMs},
-         * {@link #bgJobCountInWindow} >= {@link #jobCountLimit}, or
-         * {@link #sessionCountInWindow} >= {@link #sessionCountLimit}.
-         */
-        public long inQuotaTimeLowElapsed;
-
-        /**
-         * The time after which the app will be under the bucket quota and can start running
-         * min priority jobs again. This is only valid if
-         * {@link #executionTimeInWindowMs} >=
-         *        {@link #mAllowedTimePerPeriodMs} * (1 - {@link #mAllowedTimeSurplusPriorityMin}),
-         * {@link #executionTimeInMaxPeriodMs} >= {@link #mMaxExecutionTimeMs},
-         * {@link #bgJobCountInWindow} >= {@link #jobCountLimit}, or
-         * {@link #sessionCountInWindow} >= {@link #sessionCountLimit}.
-         */
-        public long inQuotaTimeMinElapsed;
-
-        /**
          * The time after which {@link #jobCountInRateLimitingWindow} should be considered invalid,
          * in the elapsed realtime timebase.
          */
@@ -227,8 +204,6 @@
                     + "bgJobCountInMaxPeriod=" + bgJobCountInMaxPeriod + ", "
                     + "sessionCountInWindow=" + sessionCountInWindow + ", "
                     + "inQuotaTime=" + inQuotaTimeElapsed + ", "
-                    + "inQuotaTimeLow=" + inQuotaTimeLowElapsed + ", "
-                    + "inQuotaTimeMin=" + inQuotaTimeMinElapsed + ", "
                     + "rateLimitJobCountExpirationTime=" + jobRateLimitExpirationTimeElapsed + ", "
                     + "rateLimitJobCountWindow=" + jobCountInRateLimitingWindow + ", "
                     + "rateLimitSessionCountExpirationTime="
@@ -385,24 +360,6 @@
      */
     private long mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
 
-    /**
-     * The percentage of {@link #mAllowedTimePerPeriodMs} that should not be used by
-     * {@link JobInfo#PRIORITY_LOW low priority} jobs. In other words, there must be a minimum
-     * surplus of this amount of remaining allowed time before we start running low priority
-     * jobs.
-     */
-    private float mAllowedTimeSurplusPriorityLow =
-            QcConstants.DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW;
-
-    /**
-     * The percentage of {@link #mAllowedTimePerPeriodMs} that should not be used by
-     * {@link JobInfo#PRIORITY_MIN min priority} jobs. In other words, there must be a minimum
-     * surplus of this amount of remaining allowed time before we start running low priority
-     * jobs.
-     */
-    private float mAllowedTimeSurplusPriorityMin =
-            QcConstants.DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN;
-
     /** The period of time used to rate limit recently run jobs. */
     private long mRateLimitingWindowMs = QcConstants.DEFAULT_RATE_LIMITING_WINDOW_MS;
 
@@ -828,8 +785,7 @@
                 return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
             }
             return getTimeUntilQuotaConsumedLocked(
-                    jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(),
-                    jobStatus.getEffectivePriority());
+                    jobStatus.getSourceUserId(), jobStatus.getSourcePackageName());
         }
 
         // Expedited job.
@@ -919,8 +875,7 @@
         return isTopStartedJobLocked(jobStatus)
                 || isUidInForeground(jobStatus.getSourceUid())
                 || isWithinQuotaLocked(
-                jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), standbyBucket,
-                jobStatus.getEffectivePriority());
+                jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), standbyBucket);
     }
 
     @GuardedBy("mLock")
@@ -937,7 +892,7 @@
     @VisibleForTesting
     @GuardedBy("mLock")
     boolean isWithinQuotaLocked(final int userId, @NonNull final String packageName,
-            final int standbyBucket, final int priority) {
+            final int standbyBucket) {
         if (!mIsEnabled) {
             return true;
         }
@@ -945,18 +900,9 @@
 
         if (isQuotaFreeLocked(standbyBucket)) return true;
 
-        final long minSurplus;
-        if (priority <= JobInfo.PRIORITY_MIN) {
-            minSurplus = (long)
-                    (mAllowedTimePerPeriodMs[standbyBucket] * mAllowedTimeSurplusPriorityMin);
-        } else if (priority <= JobInfo.PRIORITY_LOW) {
-            minSurplus = (long)
-                    (mAllowedTimePerPeriodMs[standbyBucket] * mAllowedTimeSurplusPriorityLow);
-        } else {
-            minSurplus = 0;
-        }
         ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket);
-        return getRemainingExecutionTimeLocked(stats) > minSurplus
+        // TODO: use a higher minimum remaining time for jobs with MINIMUM priority
+        return getRemainingExecutionTimeLocked(stats) > 0
                 && isUnderJobCountQuotaLocked(stats, standbyBucket)
                 && isUnderSessionCountQuotaLocked(stats, standbyBucket);
     }
@@ -1074,8 +1020,7 @@
      * job is running.
      */
     @VisibleForTesting
-    long getTimeUntilQuotaConsumedLocked(final int userId, @NonNull final String packageName,
-            @JobInfo.Priority int jobPriority) {
+    long getTimeUntilQuotaConsumedLocked(final int userId, @NonNull final String packageName) {
         final long nowElapsed = sElapsedRealtimeClock.millis();
         final int standbyBucket = JobSchedulerService.standbyBucketForPackage(
                 packageName, userId, nowElapsed);
@@ -1096,15 +1041,11 @@
 
         final long startWindowElapsed = nowElapsed - stats.windowSizeMs;
         final long startMaxElapsed = nowElapsed - MAX_PERIOD_MS;
-        final long allowedTimePerPeriodMs = getAllowedTimePerPeriodMs(standbyBucket, jobPriority);
+        final long allowedTimePerPeriodMs = mAllowedTimePerPeriodMs[standbyBucket];
         final long allowedTimeRemainingMs = allowedTimePerPeriodMs - stats.executionTimeInWindowMs;
         final long maxExecutionTimeRemainingMs =
                 mMaxExecutionTimeMs - stats.executionTimeInMaxPeriodMs;
 
-        if (maxExecutionTimeRemainingMs < 0) {
-            return 0;
-        }
-
         // Regular ACTIVE case. Since the bucket size equals the allowed time, the app jobs can
         // essentially run until they reach the maximum limit.
         if (stats.windowSizeMs == mAllowedTimePerPeriodMs[standbyBucket]) {
@@ -1112,10 +1053,6 @@
                     sessions, startMaxElapsed, maxExecutionTimeRemainingMs);
         }
 
-        if (allowedTimeRemainingMs < 0) {
-            return 0;
-        }
-
         // Need to check both max time and period time in case one is less than the other.
         // For example, max time remaining could be less than bucket time remaining, but sessions
         // contributing to the max time remaining could phase out enough that we'd want to use the
@@ -1127,21 +1064,6 @@
                         sessions, startWindowElapsed, allowedTimeRemainingMs));
     }
 
-    private long getAllowedTimePerPeriodMs(int standbyBucket, @JobInfo.Priority int jobPriority) {
-        return getAllowedTimePerPeriodMs(mAllowedTimePerPeriodMs[standbyBucket], jobPriority);
-    }
-
-    private long getAllowedTimePerPeriodMs(long initialAllowedTime,
-            @JobInfo.Priority int jobPriority) {
-        if (jobPriority <= JobInfo.PRIORITY_MIN) {
-            return (long) (initialAllowedTime * (1 - mAllowedTimeSurplusPriorityMin));
-        }
-        if (jobPriority <= JobInfo.PRIORITY_LOW) {
-            return (long) (initialAllowedTime * (1 - mAllowedTimeSurplusPriorityLow));
-        }
-        return initialAllowedTime;
-    }
-
     /**
      * Calculates how much time it will take, in milliseconds, until the quota is fully consumed.
      *
@@ -1299,15 +1221,10 @@
         stats.sessionCountInWindow = 0;
         if (stats.jobCountLimit == 0 || stats.sessionCountLimit == 0) {
             // App won't be in quota until configuration changes.
-            stats.inQuotaTimeElapsed = stats.inQuotaTimeLowElapsed = stats.inQuotaTimeMinElapsed =
-                    Long.MAX_VALUE;
+            stats.inQuotaTimeElapsed = Long.MAX_VALUE;
         } else {
             stats.inQuotaTimeElapsed = 0;
         }
-        final long allowedTimeMinMs =
-                getAllowedTimePerPeriodMs(stats.allowedTimePerPeriodMs, JobInfo.PRIORITY_MIN);
-        final long allowedTimeLowMs =
-                getAllowedTimePerPeriodMs(stats.allowedTimePerPeriodMs, JobInfo.PRIORITY_LOW);
         final long allowedTimeIntoQuotaMs = stats.allowedTimePerPeriodMs - mQuotaBufferMs;
 
         Timer timer = mPkgTimers.get(userId, packageName);
@@ -1326,25 +1243,13 @@
                 stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed,
                         nowElapsed - allowedTimeIntoQuotaMs + stats.windowSizeMs);
             }
-            if (stats.executionTimeInWindowMs >= allowedTimeLowMs) {
-                stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed,
-                        nowElapsed - allowedTimeLowMs + stats.windowSizeMs);
-            }
-            if (stats.executionTimeInWindowMs >= allowedTimeMinMs) {
-                stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed,
-                        nowElapsed - allowedTimeMinMs + stats.windowSizeMs);
-            }
             if (stats.executionTimeInMaxPeriodMs >= mMaxExecutionTimeIntoQuotaMs) {
                 final long inQuotaTime = nowElapsed - mMaxExecutionTimeIntoQuotaMs + MAX_PERIOD_MS;
                 stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime);
-                stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, inQuotaTime);
-                stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, inQuotaTime);
             }
             if (stats.bgJobCountInWindow >= stats.jobCountLimit) {
                 final long inQuotaTime = nowElapsed + stats.windowSizeMs;
                 stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime);
-                stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed, inQuotaTime);
-                stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed, inQuotaTime);
             }
         }
 
@@ -1386,23 +1291,9 @@
                             start + stats.executionTimeInWindowMs - allowedTimeIntoQuotaMs
                                     + stats.windowSizeMs);
                 }
-                if (stats.executionTimeInWindowMs >= allowedTimeLowMs) {
-                    stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed,
-                            start + stats.executionTimeInWindowMs - allowedTimeLowMs
-                                    + stats.windowSizeMs);
-                }
-                if (stats.executionTimeInWindowMs >= allowedTimeMinMs) {
-                    stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed,
-                            start + stats.executionTimeInWindowMs - allowedTimeMinMs
-                                    + stats.windowSizeMs);
-                }
                 if (stats.bgJobCountInWindow >= stats.jobCountLimit) {
                     final long inQuotaTime = session.endTimeElapsed + stats.windowSizeMs;
                     stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime);
-                    stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed,
-                            inQuotaTime);
-                    stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed,
-                            inQuotaTime);
                 }
                 if (i == loopStart
                         || (sessions.get(i + 1).startTimeElapsed - session.endTimeElapsed)
@@ -1413,10 +1304,6 @@
                     if (sessionCountInWindow >= stats.sessionCountLimit) {
                         final long inQuotaTime = session.endTimeElapsed + stats.windowSizeMs;
                         stats.inQuotaTimeElapsed = Math.max(stats.inQuotaTimeElapsed, inQuotaTime);
-                        stats.inQuotaTimeLowElapsed = Math.max(stats.inQuotaTimeLowElapsed,
-                                inQuotaTime);
-                        stats.inQuotaTimeMinElapsed = Math.max(stats.inQuotaTimeMinElapsed,
-                                inQuotaTime);
                     }
                 }
             }
@@ -1706,7 +1593,7 @@
     /**
      * Update the CONSTRAINT_WITHIN_QUOTA bit for all of the Jobs for a given package.
      *
-     * @return true if at least one job had its bit changed
+     * @return the set of jobs whose status changed
      */
     @NonNull
     private ArraySet<JobStatus> maybeUpdateConstraintForPkgLocked(final long nowElapsed,
@@ -1719,8 +1606,7 @@
 
         // Quota is the same for all jobs within a package.
         final int realStandbyBucket = jobs.valueAt(0).getStandbyBucket();
-        final boolean realInQuota = isWithinQuotaLocked(
-                userId, packageName, realStandbyBucket, JobInfo.PRIORITY_DEFAULT);
+        final boolean realInQuota = isWithinQuotaLocked(userId, packageName, realStandbyBucket);
         boolean outOfEJQuota = false;
         for (int i = jobs.size() - 1; i >= 0; --i) {
             final JobStatus js = jobs.valueAt(i);
@@ -1733,8 +1619,7 @@
                     changedJobs.add(js);
                 }
             } else if (realStandbyBucket != EXEMPTED_INDEX && realStandbyBucket != ACTIVE_INDEX
-                    && realStandbyBucket == js.getEffectiveStandbyBucket()
-                    && js.getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT) {
+                    && realStandbyBucket == js.getEffectiveStandbyBucket()) {
                 // An app in the ACTIVE bucket may be out of quota while the job could be in quota
                 // for some reason. Therefore, avoid setting the real value here and check each job
                 // individually.
@@ -1798,8 +1683,9 @@
             final String packageName = jobStatus.getSourcePackageName();
             final int realStandbyBucket = jobStatus.getStandbyBucket();
             if (isWithinEJQuota
-                    && isWithinQuotaLocked(userId, packageName, realStandbyBucket,
-                    JobInfo.PRIORITY_MIN)) {
+                    && isWithinQuotaLocked(userId, packageName, realStandbyBucket)) {
+                // TODO(141645789): we probably shouldn't cancel the alarm until we've verified
+                // that all jobs for the userId-package are within quota.
                 mInQuotaAlarmQueue.removeAlarmForKey(new Package(userId, packageName));
             } else {
                 mToScheduleStartAlarms.add(userId, packageName, realStandbyBucket);
@@ -1860,25 +1746,8 @@
                 standbyBucket);
         final long remainingEJQuota = getRemainingEJExecutionTimeLocked(userId, packageName);
 
-        int minPriority = JobInfo.PRIORITY_MAX;
-        boolean hasDefPlus = false, hasLow = false, hasMin = false;
-        for (int i = jobs.size() - 1; i >= 0; --i) {
-            final int priority = jobs.valueAt(i).getEffectivePriority();
-            minPriority = Math.min(minPriority, priority);
-            if (priority <= JobInfo.PRIORITY_MIN) {
-                hasMin = true;
-            } else if (priority <= JobInfo.PRIORITY_LOW) {
-                hasLow = true;
-            } else {
-                hasDefPlus = true;
-            }
-            if (hasMin && hasLow && hasDefPlus) {
-                break;
-            }
-        }
         final boolean inRegularQuota =
-                stats.executionTimeInWindowMs
-                        < getAllowedTimePerPeriodMs(standbyBucket, minPriority)
+                stats.executionTimeInWindowMs < mAllowedTimePerPeriodMs[standbyBucket]
                         && stats.executionTimeInMaxPeriodMs < mMaxExecutionTimeMs
                         && isUnderJobCountQuota
                         && isUnderTimingSessionCountQuota;
@@ -1900,24 +1769,7 @@
         long inEJQuotaTimeElapsed = Long.MAX_VALUE;
         if (!inRegularQuota) {
             // The time this app will have quota again.
-            long executionInQuotaTime = Long.MAX_VALUE;
-            boolean hasExecutionInQuotaTime = false;
-            if (hasMin && stats.inQuotaTimeMinElapsed > 0) {
-                executionInQuotaTime = Math.min(executionInQuotaTime, stats.inQuotaTimeMinElapsed);
-                hasExecutionInQuotaTime = true;
-            }
-            if (hasLow && stats.inQuotaTimeLowElapsed > 0) {
-                executionInQuotaTime = Math.min(executionInQuotaTime, stats.inQuotaTimeLowElapsed);
-                hasExecutionInQuotaTime = true;
-            }
-            if (hasDefPlus && stats.inQuotaTimeElapsed > 0) {
-                executionInQuotaTime = Math.min(executionInQuotaTime, stats.inQuotaTimeElapsed);
-                hasExecutionInQuotaTime = true;
-            }
-            long inQuotaTimeElapsed = 0;
-            if (hasExecutionInQuotaTime) {
-                inQuotaTimeElapsed = executionInQuotaTime;
-            }
+            long inQuotaTimeElapsed = stats.inQuotaTimeElapsed;
             if (!isUnderJobCountQuota && stats.bgJobCountInWindow < stats.jobCountLimit) {
                 // App hit the rate limit.
                 inQuotaTimeElapsed =
@@ -2130,7 +1982,6 @@
         private final ArraySet<JobStatus> mRunningBgJobs = new ArraySet<>();
         private long mStartTimeElapsed;
         private int mBgJobCount;
-        private int mLowestPriority = JobInfo.PRIORITY_MAX;
         private long mDebitAdjustment;
 
         Timer(int uid, int userId, String packageName, boolean regularJobTimer) {
@@ -2153,8 +2004,6 @@
                 Slog.v(TAG, "Starting to track " + jobStatus.toShortString());
             }
             // Always maintain list of running jobs, even when quota is free.
-            final boolean priorityLowered = mLowestPriority > jobStatus.getEffectivePriority();
-            mLowestPriority = Math.min(mLowestPriority, jobStatus.getEffectivePriority());
             if (mRunningBgJobs.add(jobStatus) && shouldTrackLocked()) {
                 mBgJobCount++;
                 if (mRegularJobTimer) {
@@ -2170,8 +2019,6 @@
                         invalidateAllExecutionStatsLocked(mPkg.userId, mPkg.packageName);
                     }
                     scheduleCutoff();
-                } else if (mRegularJobTimer && priorityLowered) {
-                    rescheduleCutoff();
                 }
             }
         }
@@ -2196,19 +2043,6 @@
                         && !isQuotaFreeLocked(standbyBucket)) {
                     emitSessionLocked(nowElapsed);
                     cancelCutoff();
-                    mLowestPriority = JobInfo.PRIORITY_MAX;
-                } else if (mRegularJobTimer
-                        && mLowestPriority == jobStatus.getEffectivePriority()) {
-                    // Lowest priority doesn't matter for EJ timers.
-                    final int oldPriority = mLowestPriority;
-                    mLowestPriority = JobInfo.PRIORITY_MAX;
-                    for (int i = mRunningBgJobs.size() - 1; i >= 0; --i) {
-                        mLowestPriority = Math.min(mLowestPriority,
-                                mRunningBgJobs.valueAt(i).getEffectivePriority());
-                    }
-                    if (mLowestPriority != oldPriority) {
-                        rescheduleCutoff();
-                    }
                 }
             }
         }
@@ -2335,14 +2169,9 @@
                 }
                 Message msg = mHandler.obtainMessage(
                         mRegularJobTimer ? MSG_REACHED_QUOTA : MSG_REACHED_EJ_QUOTA, mPkg);
-                final long timeRemainingMs;
-                if (mRegularJobTimer) {
-                    timeRemainingMs = getTimeUntilQuotaConsumedLocked(
-                            mPkg.userId, mPkg.packageName, mLowestPriority);
-                } else {
-                    timeRemainingMs =
-                            getTimeUntilEJQuotaConsumedLocked(mPkg.userId, mPkg.packageName);
-                }
+                final long timeRemainingMs = mRegularJobTimer
+                        ? getTimeUntilQuotaConsumedLocked(mPkg.userId, mPkg.packageName)
+                        : getTimeUntilEJQuotaConsumedLocked(mPkg.userId, mPkg.packageName);
                 if (DEBUG) {
                     Slog.i(TAG,
                             (mRegularJobTimer ? "Regular job" : "EJ") + " for " + mPkg + " has "
@@ -2695,19 +2524,26 @@
                             Slog.d(TAG, "Checking if " + pkg + " has reached its quota.");
                         }
 
-                        final ArraySet<JobStatus> changedJobs = maybeUpdateConstraintForPkgLocked(
-                                sElapsedRealtimeClock.millis(), pkg.userId, pkg.packageName);
-                        if (changedJobs.size() > 0) {
+                        long timeRemainingMs = getRemainingExecutionTimeLocked(pkg.userId,
+                                pkg.packageName);
+                        if (timeRemainingMs <= 50) {
+                            // Less than 50 milliseconds left. Start process of shutting down jobs.
                             if (DEBUG) Slog.d(TAG, pkg + " has reached its quota.");
-                            mStateChangedListener.onControllerStateChanged(changedJobs);
+                            mStateChangedListener.onControllerStateChanged(
+                                    maybeUpdateConstraintForPkgLocked(
+                                            sElapsedRealtimeClock.millis(),
+                                            pkg.userId, pkg.packageName));
                         } else {
                             // This could potentially happen if an old session phases out while a
                             // job is currently running.
                             // Reschedule message
+                            Message rescheduleMsg = obtainMessage(MSG_REACHED_QUOTA, pkg);
+                            timeRemainingMs = getTimeUntilQuotaConsumedLocked(pkg.userId,
+                                    pkg.packageName);
                             if (DEBUG) {
-                                Slog.d(TAG, pkg + " had early REACHED_QUOTA message");
+                                Slog.d(TAG, pkg + " has " + timeRemainingMs + "ms left.");
                             }
-                            mPkgTimers.get(pkg.userId, pkg.packageName).rescheduleCutoff();
+                            sendMessageDelayed(rescheduleMsg, timeRemainingMs);
                         }
                         break;
                     }
@@ -2717,19 +2553,25 @@
                             Slog.d(TAG, "Checking if " + pkg + " has reached its EJ quota.");
                         }
 
-                        final ArraySet<JobStatus> changedJobs = maybeUpdateConstraintForPkgLocked(
-                                sElapsedRealtimeClock.millis(), pkg.userId, pkg.packageName);
-                        if (changedJobs.size() > 0) {
+                        long timeRemainingMs = getRemainingEJExecutionTimeLocked(
+                                pkg.userId, pkg.packageName);
+                        if (timeRemainingMs <= 0) {
                             if (DEBUG) Slog.d(TAG, pkg + " has reached its EJ quota.");
-                            mStateChangedListener.onControllerStateChanged(changedJobs);
+                            mStateChangedListener.onControllerStateChanged(
+                                    maybeUpdateConstraintForPkgLocked(
+                                            sElapsedRealtimeClock.millis(),
+                                            pkg.userId, pkg.packageName));
                         } else {
                             // This could potentially happen if an old session phases out while a
                             // job is currently running.
                             // Reschedule message
+                            Message rescheduleMsg = obtainMessage(MSG_REACHED_EJ_QUOTA, pkg);
+                            timeRemainingMs = getTimeUntilEJQuotaConsumedLocked(
+                                    pkg.userId, pkg.packageName);
                             if (DEBUG) {
-                                Slog.d(TAG, pkg + " had early REACHED_EJ_QUOTA message");
+                                Slog.d(TAG, pkg + " has " + timeRemainingMs + "ms left for EJ");
                             }
-                            mEJPkgTimers.get(pkg.userId, pkg.packageName).rescheduleCutoff();
+                            sendMessageDelayed(rescheduleMsg, timeRemainingMs);
                         }
                         break;
                     }
@@ -2993,12 +2835,6 @@
         static final String KEY_IN_QUOTA_BUFFER_MS =
                 QC_CONSTANT_PREFIX + "in_quota_buffer_ms";
         @VisibleForTesting
-        static final String KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW =
-                QC_CONSTANT_PREFIX + "allowed_time_surplus_priority_low";
-        @VisibleForTesting
-        static final String KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN =
-                QC_CONSTANT_PREFIX + "allowed_time_surplus_priority_min";
-        @VisibleForTesting
         static final String KEY_WINDOW_SIZE_EXEMPTED_MS =
                 QC_CONSTANT_PREFIX + "window_size_exempted_ms";
         @VisibleForTesting
@@ -3130,8 +2966,6 @@
                 10 * 60 * 1000L; // 10 minutes
         private static final long DEFAULT_IN_QUOTA_BUFFER_MS =
                 30 * 1000L; // 30 seconds
-        private static final float DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW = .25f;
-        private static final float DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN = .5f;
         private static final long DEFAULT_WINDOW_SIZE_EXEMPTED_MS =
                 DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS; // EXEMPT apps can run jobs at any time
         private static final long DEFAULT_WINDOW_SIZE_ACTIVE_MS =
@@ -3230,22 +3064,6 @@
         public long IN_QUOTA_BUFFER_MS = DEFAULT_IN_QUOTA_BUFFER_MS;
 
         /**
-         * The percentage of ALLOWED_TIME_PER_PERIOD_*_MS that should not be used by
-         * {@link JobInfo#PRIORITY_LOW low priority} jobs. In other words, there must be a minimum
-         * surplus of this amount of remaining allowed time before we start running low priority
-         * jobs.
-         */
-        public float ALLOWED_TIME_SURPLUS_PRIORITY_LOW = DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW;
-
-        /**
-         * The percentage of ALLOWED_TIME_PER_PERIOD_*_MS that should not be used by
-         * {@link JobInfo#PRIORITY_MIN low priority} jobs. In other words, there must be a minimum
-         * surplus of this amount of remaining allowed time before we start running min priority
-         * jobs.
-         */
-        public float ALLOWED_TIME_SURPLUS_PRIORITY_MIN = DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN;
-
-        /**
          * The quota window size of the particular standby bucket. Apps in this standby bucket are
          * expected to run only {@link #ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS} within the past
          * WINDOW_SIZE_MS.
@@ -3514,8 +3332,6 @@
                 case KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS:
                 case KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS:
                 case KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS:
-                case KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW:
-                case KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN:
                 case KEY_IN_QUOTA_BUFFER_MS:
                 case KEY_MAX_EXECUTION_TIME_MS:
                 case KEY_WINDOW_SIZE_ACTIVE_MS:
@@ -3757,7 +3573,6 @@
                     KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS, KEY_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS,
                     KEY_ALLOWED_TIME_PER_PERIOD_RARE_MS, KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
                     KEY_IN_QUOTA_BUFFER_MS,
-                    KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN,
                     KEY_MAX_EXECUTION_TIME_MS,
                     KEY_WINDOW_SIZE_EXEMPTED_MS, KEY_WINDOW_SIZE_ACTIVE_MS,
                     KEY_WINDOW_SIZE_WORKING_MS,
@@ -3781,12 +3596,6 @@
             ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS =
                     properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
                             DEFAULT_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS);
-            ALLOWED_TIME_SURPLUS_PRIORITY_LOW =
-                    properties.getFloat(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW,
-                            DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_LOW);
-            ALLOWED_TIME_SURPLUS_PRIORITY_MIN =
-                    properties.getFloat(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN,
-                            DEFAULT_ALLOWED_TIME_SURPLUS_PRIORITY_MIN);
             IN_QUOTA_BUFFER_MS = properties.getLong(KEY_IN_QUOTA_BUFFER_MS,
                     DEFAULT_IN_QUOTA_BUFFER_MS);
             MAX_EXECUTION_TIME_MS = properties.getLong(KEY_MAX_EXECUTION_TIME_MS,
@@ -3865,23 +3674,6 @@
                 mMaxExecutionTimeIntoQuotaMs = mMaxExecutionTimeMs - mQuotaBufferMs;
                 mShouldReevaluateConstraints = true;
             }
-            // Low priority surplus should be in the range [0, .9]. A value of 1 would essentially
-            // mean never run low priority jobs.
-            float newAllowedTimeSurplusPriorityLow =
-                    Math.max(0f, Math.min(.9f, ALLOWED_TIME_SURPLUS_PRIORITY_LOW));
-            if (Float.compare(
-                    mAllowedTimeSurplusPriorityLow, newAllowedTimeSurplusPriorityLow) != 0) {
-                mAllowedTimeSurplusPriorityLow = newAllowedTimeSurplusPriorityLow;
-                mShouldReevaluateConstraints = true;
-            }
-            // Min priority surplus should be in the range [0, mAllowedTimeSurplusPriorityLow].
-            float newAllowedTimeSurplusPriorityMin = Math.max(0f,
-                    Math.min(mAllowedTimeSurplusPriorityLow, ALLOWED_TIME_SURPLUS_PRIORITY_MIN));
-            if (Float.compare(
-                    mAllowedTimeSurplusPriorityMin, newAllowedTimeSurplusPriorityMin) != 0) {
-                mAllowedTimeSurplusPriorityMin = newAllowedTimeSurplusPriorityMin;
-                mShouldReevaluateConstraints = true;
-            }
             long newExemptedPeriodMs = Math.max(mAllowedTimePerPeriodMs[EXEMPTED_INDEX],
                     Math.min(MAX_PERIOD_MS, WINDOW_SIZE_EXEMPTED_MS));
             if (mBucketPeriodsMs[EXEMPTED_INDEX] != newExemptedPeriodMs) {
@@ -4081,10 +3873,6 @@
                     .println();
             pw.print(KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
                     ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS).println();
-            pw.print(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, ALLOWED_TIME_SURPLUS_PRIORITY_LOW)
-                    .println();
-            pw.print(KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, ALLOWED_TIME_SURPLUS_PRIORITY_MIN)
-                    .println();
             pw.print(KEY_IN_QUOTA_BUFFER_MS, IN_QUOTA_BUFFER_MS).println();
             pw.print(KEY_WINDOW_SIZE_EXEMPTED_MS, WINDOW_SIZE_EXEMPTED_MS).println();
             pw.print(KEY_WINDOW_SIZE_ACTIVE_MS, WINDOW_SIZE_ACTIVE_MS).println();
@@ -4210,16 +3998,6 @@
     }
 
     @VisibleForTesting
-    float getAllowedTimeSurplusPriorityLow() {
-        return mAllowedTimeSurplusPriorityLow;
-    }
-
-    @VisibleForTesting
-    float getAllowedTimeSurplusPriorityMin() {
-        return mAllowedTimeSurplusPriorityMin;
-    }
-
-    @VisibleForTesting
     @NonNull
     int[] getBucketMaxJobCounts() {
         return mMaxBucketJobCounts;
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/tare/PowerSaveModeModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
index 764a3a8..4aaa9f4 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
@@ -17,27 +17,48 @@
 package com.android.server.tare;
 
 import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.PowerManager;
+import android.os.SystemClock;
 import android.util.IndentingPrintWriter;
+import android.util.Log;
+import android.util.Slog;
 
 /** Modifier that makes things more expensive in adaptive and full battery saver are active. */
 class PowerSaveModeModifier extends Modifier {
+    private static final String TAG = "TARE-" + PowerSaveModeModifier.class.getSimpleName();
+    private static final boolean DEBUG = InternalResourceService.DEBUG
+            || Log.isLoggable(TAG, Log.DEBUG);
+
     private final InternalResourceService mIrs;
-    private final PowerManager mPowerManager;
+    private final PowerSaveModeTracker mPowerSaveModeTracker;
 
     PowerSaveModeModifier(@NonNull InternalResourceService irs) {
         super();
         mIrs = irs;
-        mPowerManager = irs.getContext().getSystemService(PowerManager.class);
+        mPowerSaveModeTracker = new PowerSaveModeTracker();
+    }
+
+    @Override
+    public void setup() {
+        mPowerSaveModeTracker.startTracking(mIrs.getContext());
+    }
+
+    @Override
+    public void tearDown() {
+        mPowerSaveModeTracker.stopTracking(mIrs.getContext());
     }
 
     @Override
     long getModifiedCostToProduce(long ctp) {
-        if (mPowerManager.isPowerSaveMode()) {
+        if (mPowerSaveModeTracker.mPowerSaveModeEnabled) {
             return (long) (1.5 * ctp);
         }
         // TODO: get adaptive power save mode
-        if (mPowerManager.isPowerSaveMode()) {
+        if (mPowerSaveModeTracker.mPowerSaveModeEnabled) {
             return (long) (1.25 * ctp);
         }
         return ctp;
@@ -46,6 +67,45 @@
     @Override
     void dump(IndentingPrintWriter pw) {
         pw.print("power save=");
-        pw.println(mPowerManager.isPowerSaveMode());
+        pw.println(mPowerSaveModeTracker.mPowerSaveModeEnabled);
+    }
+
+    // TODO: migrate to relying on PowerSaveState and ServiceType.TARE
+    private final class PowerSaveModeTracker extends BroadcastReceiver {
+        private final PowerManager mPowerManager;
+        private volatile boolean mPowerSaveModeEnabled;
+
+        private PowerSaveModeTracker() {
+            mPowerManager = mIrs.getContext().getSystemService(PowerManager.class);
+        }
+
+        public void startTracking(@NonNull Context context) {
+            final IntentFilter filter = new IntentFilter();
+            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
+            context.registerReceiver(this, filter);
+
+            // Initialise tracker state.
+            mPowerSaveModeEnabled = mPowerManager.isPowerSaveMode();
+        }
+
+        public void stopTracking(@NonNull Context context) {
+            context.unregisterReceiver(this);
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
+                final boolean enabled = mPowerManager.isPowerSaveMode();
+                if (DEBUG) {
+                    Slog.d(TAG, "Power save mode changed to " + enabled
+                            + ", fired @ " + SystemClock.elapsedRealtime());
+                }
+                if (mPowerSaveModeEnabled != enabled) {
+                    mPowerSaveModeEnabled = enabled;
+                    mIrs.onDeviceStateChanged();
+                }
+            }
+        }
     }
 }
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 b843dca..849354b 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -25,6 +25,7 @@
 import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
 import static android.app.usage.UsageStatsManager.REASON_SUB_DEFAULT_APP_UPDATE;
 import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY;
+import static android.app.usage.UsageStatsManager.REASON_SUB_FORCED_USER_FLAG_INTERACTION;
 import static android.app.usage.UsageStatsManager.REASON_SUB_MASK;
 import static android.app.usage.UsageStatsManager.REASON_SUB_PREDICTED_RESTORED;
 import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_ACTIVE_TIMEOUT;
@@ -103,6 +104,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
+import android.util.SparseLongArray;
 import android.util.TimeUtils;
 import android.view.Display;
 import android.widget.Toast;
@@ -259,6 +261,13 @@
 
     private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
 
+    /**
+     * Set of user IDs and the next time (in the elapsed realtime timebase) when we should check the
+     * apps' idle states.
+     */
+    @GuardedBy("mPendingIdleStateChecks")
+    private final SparseLongArray mPendingIdleStateChecks = new SparseLongArray();
+
     // Cache the active network scorer queried from the network scorer service
     private volatile String mCachedNetworkScorer = null;
     // The last time the network scorer service was queried
@@ -721,7 +730,14 @@
 
     @Override
     public void postCheckIdleStates(int userId) {
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
+        if (userId == UserHandle.USER_ALL) {
+            postOneTimeCheckIdleStates();
+        } else {
+            synchronized (mPendingIdleStateChecks) {
+                mPendingIdleStateChecks.put(userId, mInjector.elapsedRealtime());
+            }
+            mHandler.obtainMessage(MSG_CHECK_IDLE_STATES).sendToTarget();
+        }
     }
 
     @Override
@@ -1421,6 +1437,18 @@
     }
 
     @Override
+    @StandbyBuckets
+    public int getAppMinStandbyBucket(String packageName, int appId, int userId,
+            boolean shouldObfuscateInstantApps) {
+        if (shouldObfuscateInstantApps && mInjector.isPackageEphemeral(userId, packageName)) {
+            return STANDBY_BUCKET_NEVER;
+        }
+        synchronized (mAppIdleLock) {
+            return getAppMinBucket(packageName, appId, userId);
+        }
+    }
+
+    @Override
     public void restrictApp(@NonNull String packageName, int userId,
             @ForcedReasons int restrictReason) {
         restrictApp(packageName, userId, REASON_MAIN_FORCED_BY_SYSTEM, restrictReason);
@@ -1581,7 +1609,11 @@
                     // Only user force can bypass the delay restriction. If the user forced the
                     // app into the RESTRICTED bucket, then a toast confirming the action
                     // shouldn't be surprising.
-                    if (Build.IS_DEBUGGABLE) {
+                    // Exclude REASON_SUB_FORCED_USER_FLAG_INTERACTION since the RESTRICTED bucket
+                    // isn't directly visible in that flow.
+                    if (Build.IS_DEBUGGABLE
+                            && (reason & REASON_SUB_MASK)
+                            != REASON_SUB_FORCED_USER_FLAG_INTERACTION) {
                         Toast.makeText(mContext,
                                 // Since AppStandbyController sits low in the lock hierarchy,
                                 // make sure not to call out with the lock held.
@@ -2369,10 +2401,32 @@
                     break;
 
                 case MSG_CHECK_IDLE_STATES:
-                    if (checkIdleStates(msg.arg1) && mAppIdleEnabled) {
-                        mHandler.sendMessageDelayed(mHandler.obtainMessage(
-                                MSG_CHECK_IDLE_STATES, msg.arg1, 0),
-                                mCheckIdleIntervalMillis);
+                    removeMessages(MSG_CHECK_IDLE_STATES);
+
+                    long earliestCheck = Long.MAX_VALUE;
+                    final long nowElapsed = mInjector.elapsedRealtime();
+                    synchronized (mPendingIdleStateChecks) {
+                        for (int i = mPendingIdleStateChecks.size() - 1; i >= 0; --i) {
+                            long expirationTime = mPendingIdleStateChecks.valueAt(i);
+
+                            if (expirationTime <= nowElapsed) {
+                                final int userId = mPendingIdleStateChecks.keyAt(i);
+                                if (checkIdleStates(userId) && mAppIdleEnabled) {
+                                    expirationTime = nowElapsed + mCheckIdleIntervalMillis;
+                                    mPendingIdleStateChecks.put(userId, expirationTime);
+                                } else {
+                                    mPendingIdleStateChecks.removeAt(i);
+                                    continue;
+                                }
+                            }
+
+                            earliestCheck = Math.min(earliestCheck, expirationTime);
+                        }
+                    }
+                    if (earliestCheck != Long.MAX_VALUE) {
+                        mHandler.sendMessageDelayed(
+                                mHandler.obtainMessage(MSG_CHECK_IDLE_STATES),
+                                earliestCheck - nowElapsed);
                     }
                     break;
 
diff --git a/api/Android.bp b/api/Android.bp
index bbe26b7..89993e7 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -93,7 +93,6 @@
 // Silence reflection warnings. See b/168689341
 metalava_cmd += " -J--add-opens=java.base/java.util=ALL-UNNAMED "
 metalava_cmd += " --quiet --no-banner --format=v2 "
-metalava_cmd += " --hide ChangedThrows "
 
 genrule {
     name: "current-api-xml",
@@ -110,6 +109,7 @@
         "android.net.ipsec.ike",
         "art.module.public.api",
         "conscrypt.module.public.api",
+        "framework-adservices",
         "framework-appsearch",
         "framework-bluetooth",
         "framework-connectivity",
@@ -123,20 +123,16 @@
         "framework-scheduling",
         "framework-sdkextensions",
         "framework-statsd",
-        "framework-supplementalprocess",
+        "framework-sdksandbox",
         "framework-tethering",
         "framework-uwb",
         "framework-wifi",
         "i18n.module.public.api",
     ],
-    conditional_bootclasspath: [
-        "framework-auxiliary",
-        "framework-supplementalapi",
-    ],
     system_server_classpath: [
         "service-media-s",
         "service-permission",
-        "service-supplementalprocess",
+        "service-sdksandbox",
     ],
 }
 
@@ -187,8 +183,10 @@
     cmd: metalava_cmd +
         "--check-compatibility:api:released $(location :android.api.module-lib.latest) " +
         // Note: having "public" be the base of module-lib is not perfect -- it should
-        // ideally be a merged public+system), but this will  help when migrating from
-        // MODULE_LIBS -> public.
+        // ideally be a merged public+system (which metalava is not currently able to generate).
+        // This "base" will help when migrating from MODULE_LIBS -> public, but not when
+        // migrating from MODULE_LIBS -> system (where it needs to instead be listed as
+        // an incompatibility).
         "--check-compatibility:base $(location :frameworks-base-api-current.txt) " +
         "--baseline:compatibility:released $(location :android-incompatibilities.api.module-lib.latest) " +
         "--update-baseline:compatibility:released $(genDir)/updated-baseline.txt " +
diff --git a/api/api.go b/api/api.go
index 5e5f60e..94bccaa 100644
--- a/api/api.go
+++ b/api/api.go
@@ -203,8 +203,6 @@
 func createMergedFrameworkImpl(ctx android.LoadHookContext, modules []string) {
 	// This module is for the "framework-all" module, which should not include the core libraries.
 	modules = removeAll(modules, core_libraries_modules)
-	// TODO(b/214988855): remove the line below when framework-bluetooth has an impl jar.
-	modules = remove(modules, "framework-bluetooth")
 	props := libraryProps{}
 	props.Name = proptools.StringPtr("all-framework-module-impl")
 	props.Static_libs = transformArray(modules, "", ".impl")
diff --git a/boot/Android.bp b/boot/Android.bp
index aa22532..5b265a5 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -48,6 +48,10 @@
     // bootclasspath.
     fragments: [
         {
+            apex: "com.android.adservices",
+            module: "com.android.adservices-bootclasspath-fragment",
+        },
+        {
             apex: "com.android.appsearch",
             module: "com.android.appsearch-bootclasspath-fragment",
         },
@@ -56,8 +60,8 @@
             module: "art-bootclasspath-fragment",
         },
         {
-            apex: "com.android.auxiliary",
-            module: "com.android.auxiliary-bootclasspath-fragment",
+            apex: "com.android.bluetooth",
+            module: "com.android.bluetooth-bootclasspath-fragment",
         },
         {
             apex: "com.android.conscrypt",
@@ -100,10 +104,6 @@
             module: "com.android.sdkext-bootclasspath-fragment",
         },
         {
-            apex: "com.android.supplementalprocess",
-            module: "com.android.supplementalprocess-bootclasspath-fragment",
-        },
-        {
             apex: "com.android.tethering",
             module: "com.android.tethering-bootclasspath-fragment",
         },
diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt
index e346ebf..d3b5be9 100644
--- a/boot/hiddenapi/hiddenapi-max-target-o.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-o.txt
@@ -9733,2812 +9733,6 @@
 Landroid/appwidget/PendingHostUpdate;->views:Landroid/widget/RemoteViews;
 Landroid/appwidget/PendingHostUpdate;->widgetInfo:Landroid/appwidget/AppWidgetProviderInfo;
 Landroid/appwidget/PendingHostUpdate;->writeNullParcelable(Landroid/os/Parcelable;Landroid/os/Parcel;I)V
-Landroid/bluetooth/BluetoothA2dp;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothA2dp;->ACTION_AVRCP_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dp;->DBG:Z
-Landroid/bluetooth/BluetoothA2dp;->doBind()Z
-Landroid/bluetooth/BluetoothA2dp;->enableDisableOptionalCodecs(Landroid/bluetooth/BluetoothDevice;Z)V
-Landroid/bluetooth/BluetoothA2dp;->isAvrcpAbsoluteVolumeSupported()Z
-Landroid/bluetooth/BluetoothA2dp;->isEnabled()Z
-Landroid/bluetooth/BluetoothA2dp;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothA2dp;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothA2dp;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothA2dp;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothA2dp;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothA2dp;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothA2dp;->mService:Landroid/bluetooth/IBluetoothA2dp;
-Landroid/bluetooth/BluetoothA2dp;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothA2dp;->mServiceLock:Ljava/util/concurrent/locks/ReentrantReadWriteLock;
-Landroid/bluetooth/BluetoothA2dp;->setAvrcpAbsoluteVolume(I)V
-Landroid/bluetooth/BluetoothA2dp;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothA2dp;->shouldSendVolumeKeys(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothA2dp;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dp;->VDBG:Z
-Landroid/bluetooth/BluetoothA2dpSink;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothA2dpSink;->ACTION_AUDIO_CONFIG_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dpSink;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dpSink;->ACTION_PLAYING_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dpSink;->close()V
-Landroid/bluetooth/BluetoothA2dpSink;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothA2dpSink;->DBG:Z
-Landroid/bluetooth/BluetoothA2dpSink;->doBind()Z
-Landroid/bluetooth/BluetoothA2dpSink;->EXTRA_AUDIO_CONFIG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dpSink;->getAudioConfig(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothAudioConfig;
-Landroid/bluetooth/BluetoothA2dpSink;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothA2dpSink;->isA2dpPlaying(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothA2dpSink;->isEnabled()Z
-Landroid/bluetooth/BluetoothA2dpSink;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothA2dpSink;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothA2dpSink;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothA2dpSink;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothA2dpSink;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothA2dpSink;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothA2dpSink;->mService:Landroid/bluetooth/IBluetoothA2dpSink;
-Landroid/bluetooth/BluetoothA2dpSink;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothA2dpSink;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothA2dpSink;->stateToString(I)Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dpSink;->STATE_NOT_PLAYING:I
-Landroid/bluetooth/BluetoothA2dpSink;->STATE_PLAYING:I
-Landroid/bluetooth/BluetoothA2dpSink;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothA2dpSink;->VDBG:Z
-Landroid/bluetooth/BluetoothActivityEnergyInfo;-><init>(JIJJJJ)V
-Landroid/bluetooth/BluetoothActivityEnergyInfo;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->BT_STACK_STATE_INVALID:I
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->BT_STACK_STATE_STATE_ACTIVE:I
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->BT_STACK_STATE_STATE_IDLE:I
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->BT_STACK_STATE_STATE_SCANNING:I
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->getBluetoothStackState()I
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->getControllerEnergyUsed()J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->getControllerIdleTimeMillis()J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->getControllerRxTimeMillis()J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->getControllerTxTimeMillis()J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->getTimeStamp()J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->getUidTraffic()[Landroid/bluetooth/UidTraffic;
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->isValid()Z
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->mBluetoothStackState:I
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->mControllerEnergyUsed:J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->mControllerIdleTimeMs:J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->mControllerRxTimeMs:J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->mControllerTxTimeMs:J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->mTimestamp:J
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->mUidTraffic:[Landroid/bluetooth/UidTraffic;
-Landroid/bluetooth/BluetoothActivityEnergyInfo;->setUidTraffic([Landroid/bluetooth/UidTraffic;)V
-Landroid/bluetooth/BluetoothAdapter$BluetoothStateChangeCallback;->onBluetoothStateChange(Z)V
-Landroid/bluetooth/BluetoothAdapter$StateChangeCallbackWrapper;->mCallback:Landroid/bluetooth/BluetoothAdapter$BluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothAdapter$StateChangeCallbackWrapper;->onBluetoothStateChange(Z)V
-Landroid/bluetooth/BluetoothAdapter;-><init>(Landroid/bluetooth/IBluetoothManager;)V
-Landroid/bluetooth/BluetoothAdapter;->ACTION_BLE_ACL_CONNECTED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->ACTION_BLE_ACL_DISCONNECTED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->ACTION_BLUETOOTH_ADDRESS_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->ACTION_REQUEST_DISABLE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->ADDRESS_LENGTH:I
-Landroid/bluetooth/BluetoothAdapter;->BLUETOOTH_MANAGER_SERVICE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->changeApplicationBluetoothState(ZLandroid/bluetooth/BluetoothAdapter$BluetoothStateChangeCallback;)Z
-Landroid/bluetooth/BluetoothAdapter;->createNewRfcommSocketAndRecord(Ljava/lang/String;Ljava/util/UUID;ZZ)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->DBG:Z
-Landroid/bluetooth/BluetoothAdapter;->DEFAULT_MAC_ADDRESS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->EXTRA_BLUETOOTH_ADDRESS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->getBluetoothClass()Landroid/bluetooth/BluetoothClass;
-Landroid/bluetooth/BluetoothAdapter;->getControllerActivityEnergyInfo(I)Landroid/bluetooth/BluetoothActivityEnergyInfo;
-Landroid/bluetooth/BluetoothAdapter;->getDiscoveryEndMillis()J
-Landroid/bluetooth/BluetoothAdapter;->getLeAccess()Z
-Landroid/bluetooth/BluetoothAdapter;->getMaxConnectedAudioDevices()I
-Landroid/bluetooth/BluetoothAdapter;->getPeriodicAdvertisingManager()Landroid/bluetooth/le/PeriodicAdvertisingManager;
-Landroid/bluetooth/BluetoothAdapter;->getSupportedProfiles()Ljava/util/List;
-Landroid/bluetooth/BluetoothAdapter;->isHardwareTrackingFiltersAvailable()Z
-Landroid/bluetooth/BluetoothAdapter;->LE_PSM_CHARACTERISTIC_UUID:Ljava/util/UUID;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingEncryptedRfcommOn(I)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingInsecureL2capCoc(I)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingInsecureL2capOn(I)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingInsecureRfcommOn(I)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingL2capCoc(I)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingL2capOn(I)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingL2capOn(IZZ)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingRfcommOn(I)Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->listenUsingScoOn()Landroid/bluetooth/BluetoothServerSocket;
-Landroid/bluetooth/BluetoothAdapter;->mLeScanClients:Ljava/util/Map;
-Landroid/bluetooth/BluetoothAdapter;->mLock:Ljava/lang/Object;
-Landroid/bluetooth/BluetoothAdapter;->mManagerCallback:Landroid/bluetooth/IBluetoothManagerCallback;
-Landroid/bluetooth/BluetoothAdapter;->mManagerService:Landroid/bluetooth/IBluetoothManager;
-Landroid/bluetooth/BluetoothAdapter;->mProxyServiceStateCallbacks:Ljava/util/ArrayList;
-Landroid/bluetooth/BluetoothAdapter;->mServiceLock:Ljava/util/concurrent/locks/ReentrantReadWriteLock;
-Landroid/bluetooth/BluetoothAdapter;->mToken:Landroid/os/IBinder;
-Landroid/bluetooth/BluetoothAdapter;->nameForState(I)Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->readOutOfBandData()Landroid/util/Pair;
-Landroid/bluetooth/BluetoothAdapter;->removeServiceStateCallback(Landroid/bluetooth/IBluetoothManagerCallback;)V
-Landroid/bluetooth/BluetoothAdapter;->requestControllerActivityEnergyInfo(Landroid/os/ResultReceiver;)V
-Landroid/bluetooth/BluetoothAdapter;->sAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothAdapter;->sBluetoothLeAdvertiser:Landroid/bluetooth/le/BluetoothLeAdvertiser;
-Landroid/bluetooth/BluetoothAdapter;->sBluetoothLeScanner:Landroid/bluetooth/le/BluetoothLeScanner;
-Landroid/bluetooth/BluetoothAdapter;->setBluetoothClass(Landroid/bluetooth/BluetoothClass;)Z
-Landroid/bluetooth/BluetoothAdapter;->SOCKET_CHANNEL_AUTO_STATIC_NO_SDP:I
-Landroid/bluetooth/BluetoothAdapter;->sPeriodicAdvertisingManager:Landroid/bluetooth/le/PeriodicAdvertisingManager;
-Landroid/bluetooth/BluetoothAdapter;->STATE_BLE_ON:I
-Landroid/bluetooth/BluetoothAdapter;->STATE_BLE_TURNING_OFF:I
-Landroid/bluetooth/BluetoothAdapter;->STATE_BLE_TURNING_ON:I
-Landroid/bluetooth/BluetoothAdapter;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAdapter;->toDeviceSet([Landroid/bluetooth/BluetoothDevice;)Ljava/util/Set;
-Landroid/bluetooth/BluetoothAdapter;->VDBG:Z
-Landroid/bluetooth/BluetoothAssignedNumbers;-><init>()V
-Landroid/bluetooth/BluetoothAudioConfig;-><init>(III)V
-Landroid/bluetooth/BluetoothAudioConfig;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothAudioConfig;->getAudioFormat()I
-Landroid/bluetooth/BluetoothAudioConfig;->getChannelConfig()I
-Landroid/bluetooth/BluetoothAudioConfig;->getSampleRate()I
-Landroid/bluetooth/BluetoothAudioConfig;->mAudioFormat:I
-Landroid/bluetooth/BluetoothAudioConfig;->mChannelConfig:I
-Landroid/bluetooth/BluetoothAudioConfig;->mSampleRate:I
-Landroid/bluetooth/BluetoothAvrcp;-><init>()V
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_0:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_1:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_2:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_3:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_4:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_5:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_6:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_7:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_8:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_9:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_ANGLE:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_BACKWARD:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_CHAN_DOWN:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_CHAN_UP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_CLEAR:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_CONT_MENU:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_DISP_INFO:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_DOT:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_DOWN:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_EJECT:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_ENTER:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_EXIT:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_F1:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_F2:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_F3:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_F4:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_F5:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_FAST_FOR:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_FAV_MENU:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_FORWARD:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_HELP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_INPUT_SEL:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_LEFT:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_LEFT_DOWN:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_LEFT_UP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_MUTE:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_PAGE_DOWN:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_PAGE_UP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_PAUSE:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_PLAY:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_POWER:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_PREV_CHAN:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_RECORD:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_REWIND:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_RIGHT:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_RIGHT_DOWN:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_RIGHT_UP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_ROOT_MENU:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_SELECT:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_SETUP_MENU:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_SOUND_SEL:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_STOP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_SUBPICT:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_UP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_VENDOR:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_VOL_DOWN:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_ID_VOL_UP:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_KEYPRESSED_RELEASE:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_STATE_PRESS:I
-Landroid/bluetooth/BluetoothAvrcp;->PASSTHROUGH_STATE_RELEASE:I
-Landroid/bluetooth/BluetoothAvrcpController;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothAvrcpController;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAvrcpController;->ACTION_PLAYER_SETTING:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAvrcpController;->close()V
-Landroid/bluetooth/BluetoothAvrcpController;->DBG:Z
-Landroid/bluetooth/BluetoothAvrcpController;->doBind()Z
-Landroid/bluetooth/BluetoothAvrcpController;->EXTRA_PLAYER_SETTING:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAvrcpController;->getPlayerSettings(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothAvrcpPlayerSettings;
-Landroid/bluetooth/BluetoothAvrcpController;->isEnabled()Z
-Landroid/bluetooth/BluetoothAvrcpController;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothAvrcpController;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothAvrcpController;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothAvrcpController;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothAvrcpController;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothAvrcpController;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothAvrcpController;->mService:Landroid/bluetooth/IBluetoothAvrcpController;
-Landroid/bluetooth/BluetoothAvrcpController;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothAvrcpController;->sendGroupNavigationCmd(Landroid/bluetooth/BluetoothDevice;II)V
-Landroid/bluetooth/BluetoothAvrcpController;->setPlayerApplicationSetting(Landroid/bluetooth/BluetoothAvrcpPlayerSettings;)Z
-Landroid/bluetooth/BluetoothAvrcpController;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothAvrcpController;->VDBG:Z
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;-><init>(I)V
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->addSettingValue(II)V
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->getSettings()I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->getSettingValue(I)I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->mSettings:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->mSettingsValue:Ljava/util/Map;
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->SETTING_EQUALIZER:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->SETTING_REPEAT:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->SETTING_SCAN:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->SETTING_SHUFFLE:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->STATE_ALL_TRACK:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->STATE_GROUP:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->STATE_INVALID:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->STATE_OFF:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->STATE_ON:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->STATE_SINGLE_TRACK:I
-Landroid/bluetooth/BluetoothAvrcpPlayerSettings;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothClass$Device$Major;->BITMASK:I
-Landroid/bluetooth/BluetoothClass$Device;->BITMASK:I
-Landroid/bluetooth/BluetoothClass$Device;->PERIPHERAL_KEYBOARD:I
-Landroid/bluetooth/BluetoothClass$Device;->PERIPHERAL_KEYBOARD_POINTING:I
-Landroid/bluetooth/BluetoothClass$Device;->PERIPHERAL_NON_KEYBOARD_NON_POINTING:I
-Landroid/bluetooth/BluetoothClass$Device;->PERIPHERAL_POINTING:I
-Landroid/bluetooth/BluetoothClass$Service;->BITMASK:I
-Landroid/bluetooth/BluetoothClass;->ERROR:I
-Landroid/bluetooth/BluetoothClass;->getClassOfDevice()I
-Landroid/bluetooth/BluetoothClass;->getClassOfDeviceBytes()[B
-Landroid/bluetooth/BluetoothClass;->mClass:I
-Landroid/bluetooth/BluetoothClass;->PROFILE_A2DP_SINK:I
-Landroid/bluetooth/BluetoothClass;->PROFILE_HID:I
-Landroid/bluetooth/BluetoothClass;->PROFILE_NAP:I
-Landroid/bluetooth/BluetoothClass;->PROFILE_OPP:I
-Landroid/bluetooth/BluetoothClass;->PROFILE_PANU:I
-Landroid/bluetooth/BluetoothCodecConfig;->appendCapabilityToString(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
-Landroid/bluetooth/BluetoothCodecConfig;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothCodecConfig;->getCodecName()Ljava/lang/String;
-Landroid/bluetooth/BluetoothCodecConfig;->isMandatoryCodec()Z
-Landroid/bluetooth/BluetoothCodecConfig;->isValid()Z
-Landroid/bluetooth/BluetoothCodecConfig;->mBitsPerSample:I
-Landroid/bluetooth/BluetoothCodecConfig;->mChannelMode:I
-Landroid/bluetooth/BluetoothCodecConfig;->mCodecPriority:I
-Landroid/bluetooth/BluetoothCodecConfig;->mCodecSpecific1:J
-Landroid/bluetooth/BluetoothCodecConfig;->mCodecSpecific2:J
-Landroid/bluetooth/BluetoothCodecConfig;->mCodecSpecific3:J
-Landroid/bluetooth/BluetoothCodecConfig;->mCodecSpecific4:J
-Landroid/bluetooth/BluetoothCodecConfig;->mCodecType:I
-Landroid/bluetooth/BluetoothCodecConfig;->mSampleRate:I
-Landroid/bluetooth/BluetoothCodecConfig;->sameAudioFeedingParameters(Landroid/bluetooth/BluetoothCodecConfig;)Z
-Landroid/bluetooth/BluetoothCodecStatus;-><init>(Landroid/bluetooth/BluetoothCodecConfig;[Landroid/bluetooth/BluetoothCodecConfig;[Landroid/bluetooth/BluetoothCodecConfig;)V
-Landroid/bluetooth/BluetoothCodecStatus;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothCodecStatus;->mCodecConfig:Landroid/bluetooth/BluetoothCodecConfig;
-Landroid/bluetooth/BluetoothCodecStatus;->mCodecsLocalCapabilities:[Landroid/bluetooth/BluetoothCodecConfig;
-Landroid/bluetooth/BluetoothCodecStatus;->mCodecsSelectableCapabilities:[Landroid/bluetooth/BluetoothCodecConfig;
-Landroid/bluetooth/BluetoothCodecStatus;->sameCapabilities([Landroid/bluetooth/BluetoothCodecConfig;[Landroid/bluetooth/BluetoothCodecConfig;)Z
-Landroid/bluetooth/BluetoothDevice;->ACTION_BATTERY_LEVEL_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->ACTION_CONNECTION_ACCESS_CANCEL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->ACTION_CONNECTION_ACCESS_REPLY:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->ACTION_CONNECTION_ACCESS_REQUEST:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->ACTION_MAS_INSTANCE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->ACTION_NAME_FAILED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->BATTERY_LEVEL_UNKNOWN:I
-Landroid/bluetooth/BluetoothDevice;->BOND_SUCCESS:I
-Landroid/bluetooth/BluetoothDevice;->CONNECTION_ACCESS_NO:I
-Landroid/bluetooth/BluetoothDevice;->CONNECTION_ACCESS_YES:I
-Landroid/bluetooth/BluetoothDevice;->CONNECTION_STATE_CONNECTED:I
-Landroid/bluetooth/BluetoothDevice;->CONNECTION_STATE_DISCONNECTED:I
-Landroid/bluetooth/BluetoothDevice;->CONNECTION_STATE_ENCRYPTED_BREDR:I
-Landroid/bluetooth/BluetoothDevice;->CONNECTION_STATE_ENCRYPTED_LE:I
-Landroid/bluetooth/BluetoothDevice;->createBondOutOfBand(ILandroid/bluetooth/OobData;)Z
-Landroid/bluetooth/BluetoothDevice;->createInsecureL2capCocSocket(II)Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothDevice;->createInsecureL2capSocket(I)Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothDevice;->createL2capCocSocket(II)Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothDevice;->createL2capSocket(I)Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothDevice;->DBG:Z
-Landroid/bluetooth/BluetoothDevice;->EXTRA_ACCESS_REQUEST_TYPE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->EXTRA_ALWAYS_ALLOWED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->EXTRA_BATTERY_LEVEL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->EXTRA_CLASS_NAME:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->EXTRA_CONNECTION_ACCESS_RESULT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->EXTRA_MAS_INSTANCE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->EXTRA_PACKAGE_NAME:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->EXTRA_SDP_RECORD:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->getSimAccessPermission()I
-Landroid/bluetooth/BluetoothDevice;->isBluetoothEnabled()Z
-Landroid/bluetooth/BluetoothDevice;->mAddress:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->PAIRING_VARIANT_CONSENT:I
-Landroid/bluetooth/BluetoothDevice;->PAIRING_VARIANT_DISPLAY_PASSKEY:I
-Landroid/bluetooth/BluetoothDevice;->PAIRING_VARIANT_DISPLAY_PIN:I
-Landroid/bluetooth/BluetoothDevice;->PAIRING_VARIANT_OOB_CONSENT:I
-Landroid/bluetooth/BluetoothDevice;->PAIRING_VARIANT_PASSKEY:I
-Landroid/bluetooth/BluetoothDevice;->PAIRING_VARIANT_PIN_16_DIGITS:I
-Landroid/bluetooth/BluetoothDevice;->REQUEST_TYPE_MESSAGE_ACCESS:I
-Landroid/bluetooth/BluetoothDevice;->REQUEST_TYPE_PHONEBOOK_ACCESS:I
-Landroid/bluetooth/BluetoothDevice;->REQUEST_TYPE_PROFILE_CONNECTION:I
-Landroid/bluetooth/BluetoothDevice;->REQUEST_TYPE_SIM_ACCESS:I
-Landroid/bluetooth/BluetoothDevice;->sdpSearch(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothDevice;->setDeviceOutOfBandData([B[B)Z
-Landroid/bluetooth/BluetoothDevice;->setRemoteOutOfBandData()Z
-Landroid/bluetooth/BluetoothDevice;->sService:Landroid/bluetooth/IBluetooth;
-Landroid/bluetooth/BluetoothDevice;->sStateChangeCallback:Landroid/bluetooth/IBluetoothManagerCallback;
-Landroid/bluetooth/BluetoothDevice;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevice;->UNBOND_REASON_AUTH_CANCELED:I
-Landroid/bluetooth/BluetoothDevice;->UNBOND_REASON_REMOVED:I
-Landroid/bluetooth/BluetoothDevicePicker;->ACTION_DEVICE_SELECTED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevicePicker;->ACTION_LAUNCH:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevicePicker;->EXTRA_FILTER_TYPE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevicePicker;->EXTRA_LAUNCH_CLASS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevicePicker;->EXTRA_LAUNCH_PACKAGE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevicePicker;->EXTRA_NEED_AUTH:Ljava/lang/String;
-Landroid/bluetooth/BluetoothDevicePicker;->FILTER_TYPE_ALL:I
-Landroid/bluetooth/BluetoothDevicePicker;->FILTER_TYPE_AUDIO:I
-Landroid/bluetooth/BluetoothDevicePicker;->FILTER_TYPE_NAP:I
-Landroid/bluetooth/BluetoothDevicePicker;->FILTER_TYPE_PANU:I
-Landroid/bluetooth/BluetoothDevicePicker;->FILTER_TYPE_TRANSFER:I
-Landroid/bluetooth/BluetoothGatt;-><init>(Landroid/bluetooth/IBluetoothGatt;Landroid/bluetooth/BluetoothDevice;IZI)V
-Landroid/bluetooth/BluetoothGatt;->AUTHENTICATION_MITM:I
-Landroid/bluetooth/BluetoothGatt;->AUTHENTICATION_NONE:I
-Landroid/bluetooth/BluetoothGatt;->AUTHENTICATION_NO_MITM:I
-Landroid/bluetooth/BluetoothGatt;->AUTH_RETRY_STATE_IDLE:I
-Landroid/bluetooth/BluetoothGatt;->AUTH_RETRY_STATE_MITM:I
-Landroid/bluetooth/BluetoothGatt;->AUTH_RETRY_STATE_NO_MITM:I
-Landroid/bluetooth/BluetoothGatt;->CONN_STATE_CLOSED:I
-Landroid/bluetooth/BluetoothGatt;->CONN_STATE_CONNECTED:I
-Landroid/bluetooth/BluetoothGatt;->CONN_STATE_CONNECTING:I
-Landroid/bluetooth/BluetoothGatt;->CONN_STATE_DISCONNECTING:I
-Landroid/bluetooth/BluetoothGatt;->CONN_STATE_IDLE:I
-Landroid/bluetooth/BluetoothGatt;->DBG:Z
-Landroid/bluetooth/BluetoothGatt;->discoverServiceByUuid(Ljava/util/UUID;)Z
-Landroid/bluetooth/BluetoothGatt;->getCharacteristicById(Landroid/bluetooth/BluetoothDevice;I)Landroid/bluetooth/BluetoothGattCharacteristic;
-Landroid/bluetooth/BluetoothGatt;->getDescriptorById(Landroid/bluetooth/BluetoothDevice;I)Landroid/bluetooth/BluetoothGattDescriptor;
-Landroid/bluetooth/BluetoothGatt;->getService(Landroid/bluetooth/BluetoothDevice;Ljava/util/UUID;I)Landroid/bluetooth/BluetoothGattService;
-Landroid/bluetooth/BluetoothGatt;->mBluetoothGattCallback:Landroid/bluetooth/IBluetoothGattCallback;
-Landroid/bluetooth/BluetoothGatt;->mConnState:I
-Landroid/bluetooth/BluetoothGatt;->mDevice:Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothGatt;->mHandler:Landroid/os/Handler;
-Landroid/bluetooth/BluetoothGatt;->mOpportunistic:Z
-Landroid/bluetooth/BluetoothGatt;->mPhy:I
-Landroid/bluetooth/BluetoothGatt;->mServices:Ljava/util/List;
-Landroid/bluetooth/BluetoothGatt;->mStateLock:Ljava/lang/Object;
-Landroid/bluetooth/BluetoothGatt;->readUsingCharacteristicUuid(Ljava/util/UUID;II)Z
-Landroid/bluetooth/BluetoothGatt;->registerApp(Landroid/bluetooth/BluetoothGattCallback;Landroid/os/Handler;)Z
-Landroid/bluetooth/BluetoothGatt;->requestLeConnectionUpdate(IIIIII)Z
-Landroid/bluetooth/BluetoothGatt;->runOrQueueCallback(Ljava/lang/Runnable;)V
-Landroid/bluetooth/BluetoothGatt;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothGatt;->VDBG:Z
-Landroid/bluetooth/BluetoothGattCallback;->onConnectionUpdated(Landroid/bluetooth/BluetoothGatt;IIII)V
-Landroid/bluetooth/BluetoothGattCharacteristic;-><init>(Landroid/bluetooth/BluetoothGattService;Ljava/util/UUID;III)V
-Landroid/bluetooth/BluetoothGattCharacteristic;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/BluetoothGattCharacteristic;-><init>(Ljava/util/UUID;III)V
-Landroid/bluetooth/BluetoothGattCharacteristic;->bytesToFloat(BB)F
-Landroid/bluetooth/BluetoothGattCharacteristic;->bytesToFloat(BBBB)F
-Landroid/bluetooth/BluetoothGattCharacteristic;->getDescriptor(Ljava/util/UUID;I)Landroid/bluetooth/BluetoothGattDescriptor;
-Landroid/bluetooth/BluetoothGattCharacteristic;->getKeySize()I
-Landroid/bluetooth/BluetoothGattCharacteristic;->getTypeLen(I)I
-Landroid/bluetooth/BluetoothGattCharacteristic;->initCharacteristic(Landroid/bluetooth/BluetoothGattService;Ljava/util/UUID;III)V
-Landroid/bluetooth/BluetoothGattCharacteristic;->intToSignedBits(II)I
-Landroid/bluetooth/BluetoothGattCharacteristic;->mKeySize:I
-Landroid/bluetooth/BluetoothGattCharacteristic;->mPermissions:I
-Landroid/bluetooth/BluetoothGattCharacteristic;->mProperties:I
-Landroid/bluetooth/BluetoothGattCharacteristic;->mUuid:Ljava/util/UUID;
-Landroid/bluetooth/BluetoothGattCharacteristic;->mValue:[B
-Landroid/bluetooth/BluetoothGattCharacteristic;->mWriteType:I
-Landroid/bluetooth/BluetoothGattCharacteristic;->setInstanceId(I)V
-Landroid/bluetooth/BluetoothGattCharacteristic;->unsignedBytesToInt(BB)I
-Landroid/bluetooth/BluetoothGattCharacteristic;->unsignedBytesToInt(BBBB)I
-Landroid/bluetooth/BluetoothGattCharacteristic;->unsignedByteToInt(B)I
-Landroid/bluetooth/BluetoothGattCharacteristic;->unsignedToSigned(II)I
-Landroid/bluetooth/BluetoothGattDescriptor;-><init>(Landroid/bluetooth/BluetoothGattCharacteristic;Ljava/util/UUID;II)V
-Landroid/bluetooth/BluetoothGattDescriptor;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/BluetoothGattDescriptor;-><init>(Ljava/util/UUID;II)V
-Landroid/bluetooth/BluetoothGattDescriptor;->getInstanceId()I
-Landroid/bluetooth/BluetoothGattDescriptor;->initDescriptor(Landroid/bluetooth/BluetoothGattCharacteristic;Ljava/util/UUID;II)V
-Landroid/bluetooth/BluetoothGattDescriptor;->mPermissions:I
-Landroid/bluetooth/BluetoothGattDescriptor;->mUuid:Ljava/util/UUID;
-Landroid/bluetooth/BluetoothGattDescriptor;->mValue:[B
-Landroid/bluetooth/BluetoothGattDescriptor;->setInstanceId(I)V
-Landroid/bluetooth/BluetoothGattIncludedService;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/BluetoothGattIncludedService;-><init>(Ljava/util/UUID;II)V
-Landroid/bluetooth/BluetoothGattIncludedService;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothGattIncludedService;->getInstanceId()I
-Landroid/bluetooth/BluetoothGattIncludedService;->getType()I
-Landroid/bluetooth/BluetoothGattIncludedService;->getUuid()Ljava/util/UUID;
-Landroid/bluetooth/BluetoothGattIncludedService;->mInstanceId:I
-Landroid/bluetooth/BluetoothGattIncludedService;->mServiceType:I
-Landroid/bluetooth/BluetoothGattIncludedService;->mUuid:Ljava/util/UUID;
-Landroid/bluetooth/BluetoothGattServer;-><init>(Landroid/bluetooth/IBluetoothGatt;I)V
-Landroid/bluetooth/BluetoothGattServer;->CALLBACK_REG_TIMEOUT:I
-Landroid/bluetooth/BluetoothGattServer;->DBG:Z
-Landroid/bluetooth/BluetoothGattServer;->getCharacteristicByHandle(I)Landroid/bluetooth/BluetoothGattCharacteristic;
-Landroid/bluetooth/BluetoothGattServer;->getDescriptorByHandle(I)Landroid/bluetooth/BluetoothGattDescriptor;
-Landroid/bluetooth/BluetoothGattServer;->getService(Ljava/util/UUID;II)Landroid/bluetooth/BluetoothGattService;
-Landroid/bluetooth/BluetoothGattServer;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothGattServer;->mBluetoothGattServerCallback:Landroid/bluetooth/IBluetoothGattServerCallback;
-Landroid/bluetooth/BluetoothGattServer;->mCallback:Landroid/bluetooth/BluetoothGattServerCallback;
-Landroid/bluetooth/BluetoothGattServer;->mPendingService:Landroid/bluetooth/BluetoothGattService;
-Landroid/bluetooth/BluetoothGattServer;->mServerIf:I
-Landroid/bluetooth/BluetoothGattServer;->mServerIfLock:Ljava/lang/Object;
-Landroid/bluetooth/BluetoothGattServer;->mService:Landroid/bluetooth/IBluetoothGatt;
-Landroid/bluetooth/BluetoothGattServer;->mServices:Ljava/util/List;
-Landroid/bluetooth/BluetoothGattServer;->mTransport:I
-Landroid/bluetooth/BluetoothGattServer;->registerCallback(Landroid/bluetooth/BluetoothGattServerCallback;)Z
-Landroid/bluetooth/BluetoothGattServer;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothGattServer;->unregisterCallback()V
-Landroid/bluetooth/BluetoothGattServer;->VDBG:Z
-Landroid/bluetooth/BluetoothGattServerCallback;->onConnectionUpdated(Landroid/bluetooth/BluetoothDevice;IIII)V
-Landroid/bluetooth/BluetoothGattService;-><init>(Landroid/bluetooth/BluetoothDevice;Ljava/util/UUID;II)V
-Landroid/bluetooth/BluetoothGattService;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/BluetoothGattService;-><init>(Ljava/util/UUID;II)V
-Landroid/bluetooth/BluetoothGattService;->addIncludedService(Landroid/bluetooth/BluetoothGattService;)V
-Landroid/bluetooth/BluetoothGattService;->getCharacteristic(Ljava/util/UUID;I)Landroid/bluetooth/BluetoothGattCharacteristic;
-Landroid/bluetooth/BluetoothGattService;->getDevice()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothGattService;->getHandles()I
-Landroid/bluetooth/BluetoothGattService;->isAdvertisePreferred()Z
-Landroid/bluetooth/BluetoothGattService;->mAdvertisePreferred:Z
-Landroid/bluetooth/BluetoothGattService;->mHandles:I
-Landroid/bluetooth/BluetoothGattService;->mInstanceId:I
-Landroid/bluetooth/BluetoothGattService;->mServiceType:I
-Landroid/bluetooth/BluetoothGattService;->mUuid:Ljava/util/UUID;
-Landroid/bluetooth/BluetoothGattService;->setDevice(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/BluetoothGattService;->setHandles(I)V
-Landroid/bluetooth/BluetoothHeadset;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothHeadset;->ACTION_HF_INDICATORS_VALUE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadset;->clccResponse(IIIIZLjava/lang/String;I)V
-Landroid/bluetooth/BluetoothHeadset;->DBG:Z
-Landroid/bluetooth/BluetoothHeadset;->doBind()Z
-Landroid/bluetooth/BluetoothHeadset;->doUnbind()V
-Landroid/bluetooth/BluetoothHeadset;->EXTRA_HF_INDICATORS_IND_ID:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadset;->EXTRA_HF_INDICATORS_IND_VALUE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadset;->getAudioRouteAllowed()Z
-Landroid/bluetooth/BluetoothHeadset;->isAudioOn()Z
-Landroid/bluetooth/BluetoothHeadset;->isBluetoothVoiceDialingEnabled(Landroid/content/Context;)Z
-Landroid/bluetooth/BluetoothHeadset;->isDisabled()Z
-Landroid/bluetooth/BluetoothHeadset;->isInbandRingingEnabled()Z
-Landroid/bluetooth/BluetoothHeadset;->isInbandRingingSupported(Landroid/content/Context;)Z
-Landroid/bluetooth/BluetoothHeadset;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadset;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothHeadset;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothHeadset;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothHeadset;->mConnection:Landroid/bluetooth/IBluetoothProfileServiceConnection;
-Landroid/bluetooth/BluetoothHeadset;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothHeadset;->MESSAGE_HEADSET_SERVICE_CONNECTED:I
-Landroid/bluetooth/BluetoothHeadset;->MESSAGE_HEADSET_SERVICE_DISCONNECTED:I
-Landroid/bluetooth/BluetoothHeadset;->mHandler:Landroid/os/Handler;
-Landroid/bluetooth/BluetoothHeadset;->mService:Landroid/bluetooth/IBluetoothHeadset;
-Landroid/bluetooth/BluetoothHeadset;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothHeadset;->setAudioRouteAllowed(Z)V
-Landroid/bluetooth/BluetoothHeadset;->setForceScoAudio(Z)V
-Landroid/bluetooth/BluetoothHeadset;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadset;->VDBG:Z
-Landroid/bluetooth/BluetoothHeadset;->VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadset;->VENDOR_SPECIFIC_HEADSET_EVENT_IPHONEACCEV_BATTERY_LEVEL:I
-Landroid/bluetooth/BluetoothHeadset;->VENDOR_SPECIFIC_HEADSET_EVENT_XAPL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadset;->VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadset;->VENDOR_SPECIFIC_HEADSET_EVENT_XEVENT_BATTERY_LEVEL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_AG_EVENT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_AUDIO_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_CALL_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_LAST_VTAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_ERROR:I
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_ERROR_BLACKLISTED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_ERROR_BUSY:I
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_ERROR_CME:I
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_ERROR_DELAYED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_ERROR_NO_ANSWER:I
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_ERROR_NO_CARRIER:I
-Landroid/bluetooth/BluetoothHeadsetClient;->ACTION_RESULT_OK:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CALL_ACCEPT_HOLD:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CALL_ACCEPT_NONE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CALL_ACCEPT_TERMINATE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->close()V
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_CORPORATE_PERSONALIZATION_PIN_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_CORPORATE_PERSONALIZATION_PUK_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_DIAL_STRING_TOO_LONG:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_EAP_NOT_SUPPORTED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_EMERGENCY_SERVICE_ONLY:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_HIDDEN_KEY_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_INCORRECT_PARAMETERS:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_INCORRECT_PASSWORD:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_INVALID_CHARACTER_IN_DIAL_STRING:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_INVALID_CHARACTER_IN_TEXT_STRING:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_INVALID_INDEX:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_MEMORY_FAILURE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_MEMORY_FULL:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NETWORK_PERSONALIZATION_PIN_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NETWORK_PERSONALIZATION_PUK_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NETWORK_SUBSET_PERSONALIZATION_PIN_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NETWORK_SUBSET_PERSONALIZATION_PUK_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NETWORK_TIMEOUT:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NOT_FOUND:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NOT_SUPPORTED_FOR_VOIP:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NO_CONNECTION_TO_PHONE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NO_NETWORK_SERVICE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_NO_SIMULTANOUS_VOIP_CS_CALLS:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_OPERATION_NOT_ALLOWED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_OPERATION_NOT_SUPPORTED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_PHFSIM_PIN_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_PHFSIM_PUK_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_PHONE_FAILURE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_PHSIM_PIN_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SERVICE_PROVIDER_PERSONALIZATION_PIN_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SERVICE_PROVIDER_PERSONALIZATION_PUK_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_BUSY:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_FAILURE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_NOT_INSERTED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_PIN2_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_PIN_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_PUK2_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_PUK_REQUIRED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIM_WRONG:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_SIP_RESPONSE_CODE:I
-Landroid/bluetooth/BluetoothHeadsetClient;->CME_TEXT_STRING_TOO_LONG:I
-Landroid/bluetooth/BluetoothHeadsetClient;->connectAudio(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->DBG:Z
-Landroid/bluetooth/BluetoothHeadsetClient;->dial(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Landroid/bluetooth/BluetoothHeadsetClientCall;
-Landroid/bluetooth/BluetoothHeadsetClient;->disconnectAudio(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->doBind()Z
-Landroid/bluetooth/BluetoothHeadsetClient;->enterPrivateMode(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->explicitCallTransfer(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_3WAY_CALLING:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_ACCEPT_HELD_OR_WAITING_CALL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_ECC:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_MERGE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_MERGE_AND_DETACH:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_REJECT_CALL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_RELEASE_AND_ACCEPT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_RELEASE_HELD_OR_WAITING_CALL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_RESPONSE_AND_HOLD:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AG_FEATURE_VOICE_RECOGNITION:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_AUDIO_WBS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_BATTERY_LEVEL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_CALL:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_CME_CODE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_IN_BAND_RING:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_NETWORK_ROAMING:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_NETWORK_SIGNAL_STRENGTH:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_NETWORK_STATUS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_NUMBER:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_OPERATOR_NAME:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_RESULT_CODE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_SUBSCRIBER_INFO:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->EXTRA_VOICE_RECOGNITION:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->getAudioRouteAllowed(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->getCurrentAgEvents(Landroid/bluetooth/BluetoothDevice;)Landroid/os/Bundle;
-Landroid/bluetooth/BluetoothHeadsetClient;->getCurrentAgFeatures(Landroid/bluetooth/BluetoothDevice;)Landroid/os/Bundle;
-Landroid/bluetooth/BluetoothHeadsetClient;->getCurrentCalls(Landroid/bluetooth/BluetoothDevice;)Ljava/util/List;
-Landroid/bluetooth/BluetoothHeadsetClient;->getLastVoiceTagNumber(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothHeadsetClient;->holdCall(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->isEnabled()Z
-Landroid/bluetooth/BluetoothHeadsetClient;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothHeadsetClient;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothHeadsetClient;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothHeadsetClient;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothHeadsetClient;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothHeadsetClient;->mService:Landroid/bluetooth/IBluetoothHeadsetClient;
-Landroid/bluetooth/BluetoothHeadsetClient;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothHeadsetClient;->sendDTMF(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->setAudioRouteAllowed(Landroid/bluetooth/BluetoothDevice;Z)V
-Landroid/bluetooth/BluetoothHeadsetClient;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->startVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->STATE_AUDIO_CONNECTED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->STATE_AUDIO_CONNECTING:I
-Landroid/bluetooth/BluetoothHeadsetClient;->STATE_AUDIO_DISCONNECTED:I
-Landroid/bluetooth/BluetoothHeadsetClient;->stopVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClient;->terminateCall(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHeadsetClientCall;)Z
-Landroid/bluetooth/BluetoothHeadsetClient;->VDBG:Z
-Landroid/bluetooth/BluetoothHeadsetClientCall;-><init>(Landroid/bluetooth/BluetoothDevice;IILjava/lang/String;ZZZ)V
-Landroid/bluetooth/BluetoothHeadsetClientCall;-><init>(Landroid/bluetooth/BluetoothDevice;ILjava/util/UUID;ILjava/lang/String;ZZZ)V
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_ACTIVE:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_ALERTING:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_DIALING:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_HELD:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_HELD_BY_RESPONSE_AND_HOLD:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_INCOMING:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_TERMINATED:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CALL_STATE_WAITING:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothHeadsetClientCall;->getCreationElapsedMilli()J
-Landroid/bluetooth/BluetoothHeadsetClientCall;->getDevice()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothHeadsetClientCall;->getUUID()Ljava/util/UUID;
-Landroid/bluetooth/BluetoothHeadsetClientCall;->isInBandRing()Z
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mCreationElapsedMilli:J
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mDevice:Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mId:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mInBandRing:Z
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mMultiParty:Z
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mNumber:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mOutgoing:Z
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mState:I
-Landroid/bluetooth/BluetoothHeadsetClientCall;->mUUID:Ljava/util/UUID;
-Landroid/bluetooth/BluetoothHeadsetClientCall;->setMultiParty(Z)V
-Landroid/bluetooth/BluetoothHeadsetClientCall;->setNumber(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothHeadsetClientCall;->setState(I)V
-Landroid/bluetooth/BluetoothHeadsetClientCall;->toString(Z)Ljava/lang/String;
-Landroid/bluetooth/BluetoothHealth$BluetoothHealthCallbackWrapper;-><init>(Landroid/bluetooth/BluetoothHealthCallback;)V
-Landroid/bluetooth/BluetoothHealth$BluetoothHealthCallbackWrapper;->mCallback:Landroid/bluetooth/BluetoothHealthCallback;
-Landroid/bluetooth/BluetoothHealth$BluetoothHealthCallbackWrapper;->onHealthAppConfigurationStatusChange(Landroid/bluetooth/BluetoothHealthAppConfiguration;I)V
-Landroid/bluetooth/BluetoothHealth$BluetoothHealthCallbackWrapper;->onHealthChannelStateChange(Landroid/bluetooth/BluetoothHealthAppConfiguration;Landroid/bluetooth/BluetoothDevice;IILandroid/os/ParcelFileDescriptor;I)V
-Landroid/bluetooth/BluetoothHealth;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothHealth;->CHANNEL_TYPE_ANY:I
-Landroid/bluetooth/BluetoothHealth;->checkAppParam(Ljava/lang/String;IILandroid/bluetooth/BluetoothHealthCallback;)Z
-Landroid/bluetooth/BluetoothHealth;->close()V
-Landroid/bluetooth/BluetoothHealth;->connectChannelToSink(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;I)Z
-Landroid/bluetooth/BluetoothHealth;->DBG:Z
-Landroid/bluetooth/BluetoothHealth;->doBind()Z
-Landroid/bluetooth/BluetoothHealth;->HEALTH_OPERATION_ERROR:I
-Landroid/bluetooth/BluetoothHealth;->HEALTH_OPERATION_GENERIC_FAILURE:I
-Landroid/bluetooth/BluetoothHealth;->HEALTH_OPERATION_INVALID_ARGS:I
-Landroid/bluetooth/BluetoothHealth;->HEALTH_OPERATION_NOT_ALLOWED:I
-Landroid/bluetooth/BluetoothHealth;->HEALTH_OPERATION_NOT_FOUND:I
-Landroid/bluetooth/BluetoothHealth;->HEALTH_OPERATION_SUCCESS:I
-Landroid/bluetooth/BluetoothHealth;->isEnabled()Z
-Landroid/bluetooth/BluetoothHealth;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHealth;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothHealth;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothHealth;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothHealth;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothHealth;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothHealth;->mService:Landroid/bluetooth/IBluetoothHealth;
-Landroid/bluetooth/BluetoothHealth;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothHealth;->registerAppConfiguration(Ljava/lang/String;IIILandroid/bluetooth/BluetoothHealthCallback;)Z
-Landroid/bluetooth/BluetoothHealth;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHealth;->VDBG:Z
-Landroid/bluetooth/BluetoothHealthAppConfiguration;-><init>(Ljava/lang/String;I)V
-Landroid/bluetooth/BluetoothHealthAppConfiguration;-><init>(Ljava/lang/String;III)V
-Landroid/bluetooth/BluetoothHealthAppConfiguration;->getChannelType()I
-Landroid/bluetooth/BluetoothHealthAppConfiguration;->mChannelType:I
-Landroid/bluetooth/BluetoothHealthAppConfiguration;->mDataType:I
-Landroid/bluetooth/BluetoothHealthAppConfiguration;->mName:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHealthAppConfiguration;->mRole:I
-Landroid/bluetooth/BluetoothHealthCallback;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHearingAid;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothHearingAid;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHearingAid;->ACTION_PLAYING_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHearingAid;->adjustVolume(I)V
-Landroid/bluetooth/BluetoothHearingAid;->close()V
-Landroid/bluetooth/BluetoothHearingAid;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHearingAid;->DBG:Z
-Landroid/bluetooth/BluetoothHearingAid;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHearingAid;->doBind()V
-Landroid/bluetooth/BluetoothHearingAid;->getDeviceMode(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothHearingAid;->getDeviceSide(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothHearingAid;->getHiSyncId(Landroid/bluetooth/BluetoothDevice;)J
-Landroid/bluetooth/BluetoothHearingAid;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothHearingAid;->getVolume()I
-Landroid/bluetooth/BluetoothHearingAid;->HI_SYNC_ID_INVALID:J
-Landroid/bluetooth/BluetoothHearingAid;->isEnabled()Z
-Landroid/bluetooth/BluetoothHearingAid;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHearingAid;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothHearingAid;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothHearingAid;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothHearingAid;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothHearingAid;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothHearingAid;->MODE_BINAURAL:I
-Landroid/bluetooth/BluetoothHearingAid;->MODE_MONAURAL:I
-Landroid/bluetooth/BluetoothHearingAid;->mService:Landroid/bluetooth/IBluetoothHearingAid;
-Landroid/bluetooth/BluetoothHearingAid;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothHearingAid;->mServiceLock:Ljava/util/concurrent/locks/ReentrantReadWriteLock;
-Landroid/bluetooth/BluetoothHearingAid;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothHearingAid;->setVolume(I)V
-Landroid/bluetooth/BluetoothHearingAid;->SIDE_LEFT:I
-Landroid/bluetooth/BluetoothHearingAid;->SIDE_RIGHT:I
-Landroid/bluetooth/BluetoothHearingAid;->stateToString(I)Ljava/lang/String;
-Landroid/bluetooth/BluetoothHearingAid;->STATE_NOT_PLAYING:I
-Landroid/bluetooth/BluetoothHearingAid;->STATE_PLAYING:I
-Landroid/bluetooth/BluetoothHearingAid;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHearingAid;->VDBG:Z
-Landroid/bluetooth/BluetoothHidDevice$Callback;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;-><init>(Ljava/util/concurrent/Executor;Landroid/bluetooth/BluetoothHidDevice$Callback;)V
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->mCallback:Landroid/bluetooth/BluetoothHidDevice$Callback;
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->mExecutor:Ljava/util/concurrent/Executor;
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->onAppStatusChanged(Landroid/bluetooth/BluetoothDevice;Z)V
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->onConnectionStateChanged(Landroid/bluetooth/BluetoothDevice;I)V
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->onGetReport(Landroid/bluetooth/BluetoothDevice;BBI)V
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->onInterruptData(Landroid/bluetooth/BluetoothDevice;B[B)V
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->onSetProtocol(Landroid/bluetooth/BluetoothDevice;B)V
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->onSetReport(Landroid/bluetooth/BluetoothDevice;BB[B)V
-Landroid/bluetooth/BluetoothHidDevice$CallbackWrapper;->onVirtualCableUnplug(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/BluetoothHidDevice;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothHidDevice;->close()V
-Landroid/bluetooth/BluetoothHidDevice;->doBind()Z
-Landroid/bluetooth/BluetoothHidDevice;->doUnbind()V
-Landroid/bluetooth/BluetoothHidDevice;->getUserAppName()Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidDevice;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothHidDevice;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothHidDevice;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothHidDevice;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothHidDevice;->mService:Landroid/bluetooth/IBluetoothHidDevice;
-Landroid/bluetooth/BluetoothHidDevice;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothHidDevice;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;->mDelayVariation:I
-Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;->mLatency:I
-Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;->mPeakBandwidth:I
-Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;->mServiceType:I
-Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;->mTokenBucketSize:I
-Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;->mTokenRate:I
-Landroid/bluetooth/BluetoothHidDeviceAppSdpSettings;->mDescription:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidDeviceAppSdpSettings;->mDescriptors:[B
-Landroid/bluetooth/BluetoothHidDeviceAppSdpSettings;->mName:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidDeviceAppSdpSettings;->mProvider:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidDeviceAppSdpSettings;->mSubclass:B
-Landroid/bluetooth/BluetoothHidHost;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothHidHost;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->ACTION_HANDSHAKE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->ACTION_IDLE_TIME_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->ACTION_PROTOCOL_MODE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->ACTION_REPORT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->ACTION_VIRTUAL_UNPLUG_STATUS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->close()V
-Landroid/bluetooth/BluetoothHidHost;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHidHost;->DBG:Z
-Landroid/bluetooth/BluetoothHidHost;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHidHost;->doBind()Z
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_IDLE_TIME:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_PROTOCOL_MODE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_REPORT:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_REPORT_BUFFER_SIZE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_REPORT_ID:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_REPORT_TYPE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_STATUS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->EXTRA_VIRTUAL_UNPLUG_STATUS:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->getIdleTime(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHidHost;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothHidHost;->getProtocolMode(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHidHost;->getReport(Landroid/bluetooth/BluetoothDevice;BBI)Z
-Landroid/bluetooth/BluetoothHidHost;->INPUT_CONNECT_FAILED_ALREADY_CONNECTED:I
-Landroid/bluetooth/BluetoothHidHost;->INPUT_CONNECT_FAILED_ATTEMPT_FAILED:I
-Landroid/bluetooth/BluetoothHidHost;->INPUT_DISCONNECT_FAILED_NOT_CONNECTED:I
-Landroid/bluetooth/BluetoothHidHost;->INPUT_OPERATION_GENERIC_FAILURE:I
-Landroid/bluetooth/BluetoothHidHost;->INPUT_OPERATION_SUCCESS:I
-Landroid/bluetooth/BluetoothHidHost;->isEnabled()Z
-Landroid/bluetooth/BluetoothHidHost;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHidHost;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothHidHost;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothHidHost;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothHidHost;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothHidHost;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothHidHost;->mService:Landroid/bluetooth/IBluetoothHidHost;
-Landroid/bluetooth/BluetoothHidHost;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothHidHost;->PROTOCOL_BOOT_MODE:I
-Landroid/bluetooth/BluetoothHidHost;->PROTOCOL_REPORT_MODE:I
-Landroid/bluetooth/BluetoothHidHost;->PROTOCOL_UNSUPPORTED_MODE:I
-Landroid/bluetooth/BluetoothHidHost;->REPORT_TYPE_FEATURE:B
-Landroid/bluetooth/BluetoothHidHost;->REPORT_TYPE_INPUT:B
-Landroid/bluetooth/BluetoothHidHost;->REPORT_TYPE_OUTPUT:B
-Landroid/bluetooth/BluetoothHidHost;->sendData(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Z
-Landroid/bluetooth/BluetoothHidHost;->setIdleTime(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/BluetoothHidHost;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothHidHost;->setProtocolMode(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothHidHost;->setReport(Landroid/bluetooth/BluetoothDevice;BLjava/lang/String;)Z
-Landroid/bluetooth/BluetoothHidHost;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothHidHost;->VDBG:Z
-Landroid/bluetooth/BluetoothHidHost;->virtualUnplug(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothHidHost;->VIRTUAL_UNPLUG_STATUS_FAIL:I
-Landroid/bluetooth/BluetoothHidHost;->VIRTUAL_UNPLUG_STATUS_SUCCESS:I
-Landroid/bluetooth/BluetoothInputStream;-><init>(Landroid/bluetooth/BluetoothSocket;)V
-Landroid/bluetooth/BluetoothInputStream;->mSocket:Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothManager;-><init>(Landroid/content/Context;)V
-Landroid/bluetooth/BluetoothManager;->DBG:Z
-Landroid/bluetooth/BluetoothManager;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothManager;->openGattServer(Landroid/content/Context;Landroid/bluetooth/BluetoothGattServerCallback;I)Landroid/bluetooth/BluetoothGattServer;
-Landroid/bluetooth/BluetoothManager;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothManager;->VDBG:Z
-Landroid/bluetooth/BluetoothMap;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothMap;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMap;->close()V
-Landroid/bluetooth/BluetoothMap;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMap;->DBG:Z
-Landroid/bluetooth/BluetoothMap;->doBind()Z
-Landroid/bluetooth/BluetoothMap;->doesClassMatchSink(Landroid/bluetooth/BluetoothClass;)Z
-Landroid/bluetooth/BluetoothMap;->getClient()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothMap;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothMap;->getState()I
-Landroid/bluetooth/BluetoothMap;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMap;->isEnabled()Z
-Landroid/bluetooth/BluetoothMap;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMap;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothMap;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothMap;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothMap;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothMap;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothMap;->mService:Landroid/bluetooth/IBluetoothMap;
-Landroid/bluetooth/BluetoothMap;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothMap;->RESULT_CANCELED:I
-Landroid/bluetooth/BluetoothMap;->RESULT_FAILURE:I
-Landroid/bluetooth/BluetoothMap;->RESULT_SUCCESS:I
-Landroid/bluetooth/BluetoothMap;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothMap;->STATE_ERROR:I
-Landroid/bluetooth/BluetoothMap;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMap;->VDBG:Z
-Landroid/bluetooth/BluetoothMapClient;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothMapClient;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->ACTION_MESSAGE_DELIVERED_SUCCESSFULLY:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->ACTION_MESSAGE_RECEIVED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->ACTION_MESSAGE_SENT_SUCCESSFULLY:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->close()V
-Landroid/bluetooth/BluetoothMapClient;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMapClient;->DBG:Z
-Landroid/bluetooth/BluetoothMapClient;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMapClient;->doBind()Z
-Landroid/bluetooth/BluetoothMapClient;->EXTRA_MESSAGE_HANDLE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->EXTRA_SENDER_CONTACT_NAME:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->EXTRA_SENDER_CONTACT_URI:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothMapClient;->getUnreadMessages(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMapClient;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMapClient;->isEnabled()Z
-Landroid/bluetooth/BluetoothMapClient;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothMapClient;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothMapClient;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothMapClient;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothMapClient;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothMapClient;->mService:Landroid/bluetooth/IBluetoothMapClient;
-Landroid/bluetooth/BluetoothMapClient;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothMapClient;->RESULT_CANCELED:I
-Landroid/bluetooth/BluetoothMapClient;->RESULT_FAILURE:I
-Landroid/bluetooth/BluetoothMapClient;->RESULT_SUCCESS:I
-Landroid/bluetooth/BluetoothMapClient;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothMapClient;->STATE_ERROR:I
-Landroid/bluetooth/BluetoothMapClient;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMapClient;->VDBG:Z
-Landroid/bluetooth/BluetoothMasInstance$MessageType;-><init>()V
-Landroid/bluetooth/BluetoothMasInstance$MessageType;->EMAIL:I
-Landroid/bluetooth/BluetoothMasInstance$MessageType;->MMS:I
-Landroid/bluetooth/BluetoothMasInstance$MessageType;->SMS_CDMA:I
-Landroid/bluetooth/BluetoothMasInstance$MessageType;->SMS_GSM:I
-Landroid/bluetooth/BluetoothMasInstance;-><init>(ILjava/lang/String;II)V
-Landroid/bluetooth/BluetoothMasInstance;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/BluetoothMasInstance;->getChannel()I
-Landroid/bluetooth/BluetoothMasInstance;->getId()I
-Landroid/bluetooth/BluetoothMasInstance;->getMsgTypes()I
-Landroid/bluetooth/BluetoothMasInstance;->getName()Ljava/lang/String;
-Landroid/bluetooth/BluetoothMasInstance;->mChannel:I
-Landroid/bluetooth/BluetoothMasInstance;->mId:I
-Landroid/bluetooth/BluetoothMasInstance;->mMsgTypes:I
-Landroid/bluetooth/BluetoothMasInstance;->mName:Ljava/lang/String;
-Landroid/bluetooth/BluetoothMasInstance;->msgSupported(I)Z
-Landroid/bluetooth/BluetoothOutputStream;-><init>(Landroid/bluetooth/BluetoothSocket;)V
-Landroid/bluetooth/BluetoothOutputStream;->mSocket:Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothPan;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothPan;->DBG:Z
-Landroid/bluetooth/BluetoothPan;->EXTRA_LOCAL_ROLE:Ljava/lang/String;
-Landroid/bluetooth/BluetoothPan;->LOCAL_NAP_ROLE:I
-Landroid/bluetooth/BluetoothPan;->LOCAL_PANU_ROLE:I
-Landroid/bluetooth/BluetoothPan;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothPan;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothPan;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothPan;->mPanService:Landroid/bluetooth/IBluetoothPan;
-Landroid/bluetooth/BluetoothPan;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothPan;->mStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothPan;->PAN_CONNECT_FAILED_ALREADY_CONNECTED:I
-Landroid/bluetooth/BluetoothPan;->PAN_CONNECT_FAILED_ATTEMPT_FAILED:I
-Landroid/bluetooth/BluetoothPan;->PAN_DISCONNECT_FAILED_NOT_CONNECTED:I
-Landroid/bluetooth/BluetoothPan;->PAN_OPERATION_GENERIC_FAILURE:I
-Landroid/bluetooth/BluetoothPan;->PAN_OPERATION_SUCCESS:I
-Landroid/bluetooth/BluetoothPan;->PAN_ROLE_NONE:I
-Landroid/bluetooth/BluetoothPan;->REMOTE_NAP_ROLE:I
-Landroid/bluetooth/BluetoothPan;->REMOTE_PANU_ROLE:I
-Landroid/bluetooth/BluetoothPan;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothPan;->VDBG:Z
-Landroid/bluetooth/BluetoothPbap$ServiceListener;->onServiceConnected(Landroid/bluetooth/BluetoothPbap;)V
-Landroid/bluetooth/BluetoothPbap$ServiceListener;->onServiceDisconnected()V
-Landroid/bluetooth/BluetoothPbap;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothPbap$ServiceListener;)V
-Landroid/bluetooth/BluetoothPbap;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothPbap;->close()V
-Landroid/bluetooth/BluetoothPbap;->DBG:Z
-Landroid/bluetooth/BluetoothPbap;->doBind()Z
-Landroid/bluetooth/BluetoothPbap;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothPbap;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothPbap;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothPbap;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothPbap;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothPbap;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothPbap;->mService:Landroid/bluetooth/IBluetoothPbap;
-Landroid/bluetooth/BluetoothPbap;->mServiceListener:Landroid/bluetooth/BluetoothPbap$ServiceListener;
-Landroid/bluetooth/BluetoothPbap;->RESULT_CANCELED:I
-Landroid/bluetooth/BluetoothPbap;->RESULT_FAILURE:I
-Landroid/bluetooth/BluetoothPbap;->RESULT_SUCCESS:I
-Landroid/bluetooth/BluetoothPbap;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothPbapClient;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothPbapClient;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothPbapClient;->close()V
-Landroid/bluetooth/BluetoothPbapClient;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothPbapClient;->DBG:Z
-Landroid/bluetooth/BluetoothPbapClient;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothPbapClient;->doBind()Z
-Landroid/bluetooth/BluetoothPbapClient;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothPbapClient;->isEnabled()Z
-Landroid/bluetooth/BluetoothPbapClient;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothPbapClient;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothPbapClient;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothPbapClient;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothPbapClient;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothPbapClient;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothPbapClient;->mService:Landroid/bluetooth/IBluetoothPbapClient;
-Landroid/bluetooth/BluetoothPbapClient;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothPbapClient;->RESULT_CANCELED:I
-Landroid/bluetooth/BluetoothPbapClient;->RESULT_FAILURE:I
-Landroid/bluetooth/BluetoothPbapClient;->RESULT_SUCCESS:I
-Landroid/bluetooth/BluetoothPbapClient;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothPbapClient;->STATE_ERROR:I
-Landroid/bluetooth/BluetoothPbapClient;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothPbapClient;->VDBG:Z
-Landroid/bluetooth/BluetoothProfile;->AVRCP:I
-Landroid/bluetooth/BluetoothProfile;->getConnectionStateName(I)Ljava/lang/String;
-Landroid/bluetooth/BluetoothProfile;->HEADSET_CLIENT:I
-Landroid/bluetooth/BluetoothProfile;->HEARING_AID:I
-Landroid/bluetooth/BluetoothProfile;->HID_HOST:I
-Landroid/bluetooth/BluetoothProfile;->MAP:I
-Landroid/bluetooth/BluetoothProfile;->MAP_CLIENT:I
-Landroid/bluetooth/BluetoothProfile;->MAX_PROFILE_ID:I
-Landroid/bluetooth/BluetoothProfile;->OPP:I
-Landroid/bluetooth/BluetoothProfile;->PBAP:I
-Landroid/bluetooth/BluetoothProfile;->PBAP_CLIENT:I
-Landroid/bluetooth/BluetoothProtoEnums;-><init>()V
-Landroid/bluetooth/BluetoothProtoEnums;->CONNECTION_STATE_CONNECTED:I
-Landroid/bluetooth/BluetoothProtoEnums;->CONNECTION_STATE_CONNECTING:I
-Landroid/bluetooth/BluetoothProtoEnums;->CONNECTION_STATE_DISCONNECTED:I
-Landroid/bluetooth/BluetoothProtoEnums;->CONNECTION_STATE_DISCONNECTING:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_AIRPLANE_MODE:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_APPLICATION_REQUEST:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_CRASH:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_DISALLOWED:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_RESTARTED:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_START_ERROR:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_SYSTEM_BOOT:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_UNSPECIFIED:I
-Landroid/bluetooth/BluetoothProtoEnums;->ENABLE_DISABLE_REASON_USER_SWITCH:I
-Landroid/bluetooth/BluetoothSap;-><init>(Landroid/content/Context;Landroid/bluetooth/BluetoothProfile$ServiceListener;)V
-Landroid/bluetooth/BluetoothSap;->ACTION_CONNECTION_STATE_CHANGED:Ljava/lang/String;
-Landroid/bluetooth/BluetoothSap;->close()V
-Landroid/bluetooth/BluetoothSap;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothSap;->DBG:Z
-Landroid/bluetooth/BluetoothSap;->doBind()Z
-Landroid/bluetooth/BluetoothSap;->getClient()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothSap;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/BluetoothSap;->getState()I
-Landroid/bluetooth/BluetoothSap;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothSap;->isEnabled()Z
-Landroid/bluetooth/BluetoothSap;->isValidDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/BluetoothSap;->log(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothSap;->mAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/BluetoothSap;->mBluetoothStateChangeCallback:Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/BluetoothSap;->mConnection:Landroid/content/ServiceConnection;
-Landroid/bluetooth/BluetoothSap;->mContext:Landroid/content/Context;
-Landroid/bluetooth/BluetoothSap;->mService:Landroid/bluetooth/IBluetoothSap;
-Landroid/bluetooth/BluetoothSap;->mServiceListener:Landroid/bluetooth/BluetoothProfile$ServiceListener;
-Landroid/bluetooth/BluetoothSap;->RESULT_CANCELED:I
-Landroid/bluetooth/BluetoothSap;->RESULT_SUCCESS:I
-Landroid/bluetooth/BluetoothSap;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/BluetoothSap;->STATE_ERROR:I
-Landroid/bluetooth/BluetoothSap;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothSap;->VDBG:Z
-Landroid/bluetooth/BluetoothServerSocket;-><init>(IZZI)V
-Landroid/bluetooth/BluetoothServerSocket;-><init>(IZZIZZ)V
-Landroid/bluetooth/BluetoothServerSocket;-><init>(IZZLandroid/os/ParcelUuid;)V
-Landroid/bluetooth/BluetoothServerSocket;->DBG:Z
-Landroid/bluetooth/BluetoothServerSocket;->getChannel()I
-Landroid/bluetooth/BluetoothServerSocket;->getPsm()I
-Landroid/bluetooth/BluetoothServerSocket;->mChannel:I
-Landroid/bluetooth/BluetoothServerSocket;->mHandler:Landroid/os/Handler;
-Landroid/bluetooth/BluetoothServerSocket;->mMessage:I
-Landroid/bluetooth/BluetoothServerSocket;->setChannel(I)V
-Landroid/bluetooth/BluetoothServerSocket;->setCloseHandler(Landroid/os/Handler;I)V
-Landroid/bluetooth/BluetoothServerSocket;->setServiceName(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothServerSocket;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothSocket$SocketState;->CLOSED:Landroid/bluetooth/BluetoothSocket$SocketState;
-Landroid/bluetooth/BluetoothSocket$SocketState;->CONNECTED:Landroid/bluetooth/BluetoothSocket$SocketState;
-Landroid/bluetooth/BluetoothSocket$SocketState;->INIT:Landroid/bluetooth/BluetoothSocket$SocketState;
-Landroid/bluetooth/BluetoothSocket$SocketState;->LISTENING:Landroid/bluetooth/BluetoothSocket$SocketState;
-Landroid/bluetooth/BluetoothSocket$SocketState;->valueOf(Ljava/lang/String;)Landroid/bluetooth/BluetoothSocket$SocketState;
-Landroid/bluetooth/BluetoothSocket$SocketState;->values()[Landroid/bluetooth/BluetoothSocket$SocketState;
-Landroid/bluetooth/BluetoothSocket;-><init>(IIZZLandroid/bluetooth/BluetoothDevice;ILandroid/os/ParcelUuid;)V
-Landroid/bluetooth/BluetoothSocket;-><init>(IIZZLandroid/bluetooth/BluetoothDevice;ILandroid/os/ParcelUuid;ZZ)V
-Landroid/bluetooth/BluetoothSocket;-><init>(IIZZLjava/lang/String;I)V
-Landroid/bluetooth/BluetoothSocket;-><init>(Landroid/bluetooth/BluetoothSocket;)V
-Landroid/bluetooth/BluetoothSocket;->accept(I)Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothSocket;->acceptSocket(Ljava/lang/String;)Landroid/bluetooth/BluetoothSocket;
-Landroid/bluetooth/BluetoothSocket;->available()I
-Landroid/bluetooth/BluetoothSocket;->bindListen()I
-Landroid/bluetooth/BluetoothSocket;->BTSOCK_FLAG_NO_SDP:I
-Landroid/bluetooth/BluetoothSocket;->convertAddr([B)Ljava/lang/String;
-Landroid/bluetooth/BluetoothSocket;->createL2capRxBuffer()V
-Landroid/bluetooth/BluetoothSocket;->DBG:Z
-Landroid/bluetooth/BluetoothSocket;->EBADFD:I
-Landroid/bluetooth/BluetoothSocket;->fillL2capRxBuffer()I
-Landroid/bluetooth/BluetoothSocket;->getPort()I
-Landroid/bluetooth/BluetoothSocket;->getSecurityFlags()I
-Landroid/bluetooth/BluetoothSocket;->mAddress:Ljava/lang/String;
-Landroid/bluetooth/BluetoothSocket;->mAuth:Z
-Landroid/bluetooth/BluetoothSocket;->mAuthMitm:Z
-Landroid/bluetooth/BluetoothSocket;->MAX_L2CAP_PACKAGE_SIZE:I
-Landroid/bluetooth/BluetoothSocket;->MAX_RFCOMM_CHANNEL:I
-Landroid/bluetooth/BluetoothSocket;->mDevice:Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/BluetoothSocket;->mEncrypt:Z
-Landroid/bluetooth/BluetoothSocket;->mExcludeSdp:Z
-Landroid/bluetooth/BluetoothSocket;->mFd:I
-Landroid/bluetooth/BluetoothSocket;->mInputStream:Landroid/bluetooth/BluetoothInputStream;
-Landroid/bluetooth/BluetoothSocket;->mL2capBuffer:Ljava/nio/ByteBuffer;
-Landroid/bluetooth/BluetoothSocket;->mMaxRxPacketSize:I
-Landroid/bluetooth/BluetoothSocket;->mMaxTxPacketSize:I
-Landroid/bluetooth/BluetoothSocket;->mMin16DigitPin:Z
-Landroid/bluetooth/BluetoothSocket;->mOutputStream:Landroid/bluetooth/BluetoothOutputStream;
-Landroid/bluetooth/BluetoothSocket;->mServiceName:Ljava/lang/String;
-Landroid/bluetooth/BluetoothSocket;->mSocketIS:Ljava/io/InputStream;
-Landroid/bluetooth/BluetoothSocket;->mSocketOS:Ljava/io/OutputStream;
-Landroid/bluetooth/BluetoothSocket;->mSocketState:Landroid/bluetooth/BluetoothSocket$SocketState;
-Landroid/bluetooth/BluetoothSocket;->mType:I
-Landroid/bluetooth/BluetoothSocket;->mUuid:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothSocket;->PROXY_CONNECTION_TIMEOUT:I
-Landroid/bluetooth/BluetoothSocket;->read([BII)I
-Landroid/bluetooth/BluetoothSocket;->readAll(Ljava/io/InputStream;[B)I
-Landroid/bluetooth/BluetoothSocket;->readInt(Ljava/io/InputStream;)I
-Landroid/bluetooth/BluetoothSocket;->removeChannel()V
-Landroid/bluetooth/BluetoothSocket;->requestMaximumTxDataLength()V
-Landroid/bluetooth/BluetoothSocket;->SEC_FLAG_AUTH:I
-Landroid/bluetooth/BluetoothSocket;->SEC_FLAG_AUTH_16_DIGIT:I
-Landroid/bluetooth/BluetoothSocket;->SEC_FLAG_AUTH_MITM:I
-Landroid/bluetooth/BluetoothSocket;->SEC_FLAG_ENCRYPT:I
-Landroid/bluetooth/BluetoothSocket;->setExcludeSdp(Z)V
-Landroid/bluetooth/BluetoothSocket;->setServiceName(Ljava/lang/String;)V
-Landroid/bluetooth/BluetoothSocket;->SOCK_SIGNAL_SIZE:I
-Landroid/bluetooth/BluetoothSocket;->TAG:Ljava/lang/String;
-Landroid/bluetooth/BluetoothSocket;->TYPE_L2CAP_BREDR:I
-Landroid/bluetooth/BluetoothSocket;->TYPE_L2CAP_LE:I
-Landroid/bluetooth/BluetoothSocket;->VDBG:Z
-Landroid/bluetooth/BluetoothSocket;->waitSocketSignal(Ljava/io/InputStream;)Ljava/lang/String;
-Landroid/bluetooth/BluetoothSocket;->write([BII)I
-Landroid/bluetooth/BluetoothUuid;-><init>()V
-Landroid/bluetooth/BluetoothUuid;->AudioSource:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->AvrcpController:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->AvrcpTarget:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->BASE_UUID:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->BNEP:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->containsAllUuids([Landroid/os/ParcelUuid;[Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->getServiceIdentifierFromParcelUuid(Landroid/os/ParcelUuid;)I
-Landroid/bluetooth/BluetoothUuid;->Handsfree_AG:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->HearingAid:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->Hid:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->HSP_AG:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->isAudioSink(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isAvrcpController(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isBnep(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isHandsfree(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isHeadset(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isInputDevice(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isMap(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isMas(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isMns(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isNap(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isPanu(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->isSap(Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/BluetoothUuid;->MAP:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->MAS:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->MNS:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->PANU:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->parseUuidFrom([B)Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->PBAP_PCE:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->SAP:Landroid/os/ParcelUuid;
-Landroid/bluetooth/BluetoothUuid;->uuidToBytes(Landroid/os/ParcelUuid;)[B
-Landroid/bluetooth/BluetoothUuid;->UUID_BYTES_128_BIT:I
-Landroid/bluetooth/BluetoothUuid;->UUID_BYTES_16_BIT:I
-Landroid/bluetooth/BluetoothUuid;->UUID_BYTES_32_BIT:I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->cancelBondProcess(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->cancelDiscovery()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->createBond(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->createBondOutOfBand(Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/OobData;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->disable()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->enable()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->enableNoAutoConnect()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->factoryReset()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->fetchRemoteUuids(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAdapterConnectionState()I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getBatteryLevel(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getBluetoothClass()Landroid/bluetooth/BluetoothClass;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getBondedDevices()[Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getBondState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getDiscoverableTimeout()I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getDiscoveryEndMillis()J
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getLeMaximumAdvertisingDataLength()I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getMaxConnectedAudioDevices()I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getMessageAccessPermission(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getName()Ljava/lang/String;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getPhonebookAccessPermission(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getProfileConnectionState(I)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getRemoteAlias(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getRemoteClass(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getRemoteName(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getRemoteType(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getRemoteUuids(Landroid/bluetooth/BluetoothDevice;)[Landroid/os/ParcelUuid;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getScanMode()I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getSimAccessPermission(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getSocketManager()Landroid/bluetooth/IBluetoothSocketManager;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getState()I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getSupportedProfiles()J
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getUuids()[Landroid/os/ParcelUuid;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isActivityAndEnergyReportingSupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isBondingInitiatedLocally(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isDiscovering()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isEnabled()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isLe2MPhySupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isLeCodedPhySupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isLeExtendedAdvertisingSupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isLePeriodicAdvertisingSupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isMultiAdvertisementSupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isOffloadedFilteringSupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->isOffloadedScanBatchingSupported()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->onBrEdrDown()V
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->onLeServiceUp()V
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->registerCallback(Landroid/bluetooth/IBluetoothCallback;)V
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->removeBond(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->reportActivityInfo()Landroid/bluetooth/BluetoothActivityEnergyInfo;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->requestActivityInfo(Landroid/os/ResultReceiver;)V
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->sdpSearch(Landroid/bluetooth/BluetoothDevice;Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setBluetoothClass(Landroid/bluetooth/BluetoothClass;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setDiscoverableTimeout(I)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setMessageAccessPermission(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setName(Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setPairingConfirmation(Landroid/bluetooth/BluetoothDevice;Z)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setPasskey(Landroid/bluetooth/BluetoothDevice;ZI[B)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setPhonebookAccessPermission(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setPin(Landroid/bluetooth/BluetoothDevice;ZI[B)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setRemoteAlias(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setScanMode(II)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->setSimAccessPermission(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->startDiscovery()Z
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->unregisterCallback(Landroid/bluetooth/IBluetoothCallback;)V
-Landroid/bluetooth/IBluetooth$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_cancelBondProcess:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_cancelDiscovery:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_createBond:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_createBondOutOfBand:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_disable:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_enableNoAutoConnect:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_factoryReset:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_fetchRemoteUuids:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getAdapterConnectionState:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getAddress:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getBatteryLevel:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getBluetoothClass:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getBondedDevices:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getBondState:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getDiscoverableTimeout:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getDiscoveryEndMillis:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getLeMaximumAdvertisingDataLength:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getMaxConnectedAudioDevices:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getMessageAccessPermission:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getName:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getPhonebookAccessPermission:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getProfileConnectionState:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getRemoteAlias:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getRemoteClass:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getRemoteName:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getRemoteType:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getRemoteUuids:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getScanMode:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getSimAccessPermission:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getSocketManager:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getState:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getSupportedProfiles:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_getUuids:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isActivityAndEnergyReportingSupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isBondingInitiatedLocally:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isDiscovering:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isEnabled:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isLe2MPhySupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isLeCodedPhySupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isLeExtendedAdvertisingSupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isLePeriodicAdvertisingSupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isMultiAdvertisementSupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isOffloadedFilteringSupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_isOffloadedScanBatchingSupported:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_onBrEdrDown:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_onLeServiceUp:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_registerCallback:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_removeBond:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_reportActivityInfo:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_requestActivityInfo:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_sdpSearch:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_sendConnectionStateChange:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setBluetoothClass:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setDiscoverableTimeout:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setMessageAccessPermission:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setName:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setPairingConfirmation:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setPasskey:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setPhonebookAccessPermission:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setPin:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setRemoteAlias:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setScanMode:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_setSimAccessPermission:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_startDiscovery:I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_unregisterCallback:I
-Landroid/bluetooth/IBluetooth;->cancelBondProcess(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetooth;->cancelDiscovery()Z
-Landroid/bluetooth/IBluetooth;->createBond(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth;->createBondOutOfBand(Landroid/bluetooth/BluetoothDevice;ILandroid/bluetooth/OobData;)Z
-Landroid/bluetooth/IBluetooth;->disable()Z
-Landroid/bluetooth/IBluetooth;->enable()Z
-Landroid/bluetooth/IBluetooth;->enableNoAutoConnect()Z
-Landroid/bluetooth/IBluetooth;->factoryReset()Z
-Landroid/bluetooth/IBluetooth;->getAdapterConnectionState()I
-Landroid/bluetooth/IBluetooth;->getBatteryLevel(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getBluetoothClass()Landroid/bluetooth/BluetoothClass;
-Landroid/bluetooth/IBluetooth;->getBondedDevices()[Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetooth;->getBondState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getDiscoverableTimeout()I
-Landroid/bluetooth/IBluetooth;->getDiscoveryEndMillis()J
-Landroid/bluetooth/IBluetooth;->getLeMaximumAdvertisingDataLength()I
-Landroid/bluetooth/IBluetooth;->getMaxConnectedAudioDevices()I
-Landroid/bluetooth/IBluetooth;->getMessageAccessPermission(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getName()Ljava/lang/String;
-Landroid/bluetooth/IBluetooth;->getPhonebookAccessPermission(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getProfileConnectionState(I)I
-Landroid/bluetooth/IBluetooth;->getRemoteClass(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getRemoteName(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
-Landroid/bluetooth/IBluetooth;->getRemoteType(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getRemoteUuids(Landroid/bluetooth/BluetoothDevice;)[Landroid/os/ParcelUuid;
-Landroid/bluetooth/IBluetooth;->getScanMode()I
-Landroid/bluetooth/IBluetooth;->getSimAccessPermission(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth;->getSocketManager()Landroid/bluetooth/IBluetoothSocketManager;
-Landroid/bluetooth/IBluetooth;->getState()I
-Landroid/bluetooth/IBluetooth;->getSupportedProfiles()J
-Landroid/bluetooth/IBluetooth;->getUuids()[Landroid/os/ParcelUuid;
-Landroid/bluetooth/IBluetooth;->isActivityAndEnergyReportingSupported()Z
-Landroid/bluetooth/IBluetooth;->isBondingInitiatedLocally(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetooth;->isDiscovering()Z
-Landroid/bluetooth/IBluetooth;->isLe2MPhySupported()Z
-Landroid/bluetooth/IBluetooth;->isLeCodedPhySupported()Z
-Landroid/bluetooth/IBluetooth;->isLeExtendedAdvertisingSupported()Z
-Landroid/bluetooth/IBluetooth;->isLePeriodicAdvertisingSupported()Z
-Landroid/bluetooth/IBluetooth;->isMultiAdvertisementSupported()Z
-Landroid/bluetooth/IBluetooth;->isOffloadedFilteringSupported()Z
-Landroid/bluetooth/IBluetooth;->isOffloadedScanBatchingSupported()Z
-Landroid/bluetooth/IBluetooth;->onBrEdrDown()V
-Landroid/bluetooth/IBluetooth;->onLeServiceUp()V
-Landroid/bluetooth/IBluetooth;->registerCallback(Landroid/bluetooth/IBluetoothCallback;)V
-Landroid/bluetooth/IBluetooth;->removeBond(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetooth;->reportActivityInfo()Landroid/bluetooth/BluetoothActivityEnergyInfo;
-Landroid/bluetooth/IBluetooth;->requestActivityInfo(Landroid/os/ResultReceiver;)V
-Landroid/bluetooth/IBluetooth;->sdpSearch(Landroid/bluetooth/BluetoothDevice;Landroid/os/ParcelUuid;)Z
-Landroid/bluetooth/IBluetooth;->setBluetoothClass(Landroid/bluetooth/BluetoothClass;)Z
-Landroid/bluetooth/IBluetooth;->setDiscoverableTimeout(I)Z
-Landroid/bluetooth/IBluetooth;->setMessageAccessPermission(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth;->setName(Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetooth;->setPairingConfirmation(Landroid/bluetooth/BluetoothDevice;Z)Z
-Landroid/bluetooth/IBluetooth;->setPasskey(Landroid/bluetooth/BluetoothDevice;ZI[B)Z
-Landroid/bluetooth/IBluetooth;->setPhonebookAccessPermission(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth;->setPin(Landroid/bluetooth/BluetoothDevice;ZI[B)Z
-Landroid/bluetooth/IBluetooth;->setRemoteAlias(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetooth;->setScanMode(II)Z
-Landroid/bluetooth/IBluetooth;->setSimAccessPermission(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetooth;->startDiscovery()Z
-Landroid/bluetooth/IBluetooth;->unregisterCallback(Landroid/bluetooth/IBluetoothCallback;)V
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->disableOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->enableOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getCodecStatus(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothCodecStatus;
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getOptionalCodecsEnabled(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->isA2dpPlaying(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->isAvrcpAbsoluteVolumeSupported()Z
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->setActiveDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->setAvrcpAbsoluteVolume(I)V
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->setCodecConfigPreference(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothCodecConfig;)V
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->setOptionalCodecsEnabled(Landroid/bluetooth/BluetoothDevice;I)V
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothA2dp$Stub$Proxy;->supportsOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_disableOptionalCodecs:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_enableOptionalCodecs:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_getActiveDevice:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_getCodecStatus:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_getOptionalCodecsEnabled:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_isA2dpPlaying:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_isAvrcpAbsoluteVolumeSupported:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_setActiveDevice:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_setAvrcpAbsoluteVolume:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_setCodecConfigPreference:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_setOptionalCodecsEnabled:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothA2dp$Stub;->TRANSACTION_supportsOptionalCodecs:I
-Landroid/bluetooth/IBluetoothA2dp;->disableOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothA2dp;->enableOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothA2dp;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothA2dp;->getCodecStatus(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothCodecStatus;
-Landroid/bluetooth/IBluetoothA2dp;->getOptionalCodecsEnabled(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dp;->isA2dpPlaying(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dp;->isAvrcpAbsoluteVolumeSupported()Z
-Landroid/bluetooth/IBluetoothA2dp;->setActiveDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dp;->setAvrcpAbsoluteVolume(I)V
-Landroid/bluetooth/IBluetoothA2dp;->setCodecConfigPreference(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothCodecConfig;)V
-Landroid/bluetooth/IBluetoothA2dp;->setOptionalCodecsEnabled(Landroid/bluetooth/BluetoothDevice;I)V
-Landroid/bluetooth/IBluetoothA2dp;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothA2dp;->supportsOptionalCodecs(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->getAudioConfig(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothAudioConfig;
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->isA2dpPlaying(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothA2dpSink$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dpSink;
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_getAudioConfig:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_isA2dpPlaying:I
-Landroid/bluetooth/IBluetoothA2dpSink$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothA2dpSink;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dpSink;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dpSink;->getAudioConfig(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothAudioConfig;
-Landroid/bluetooth/IBluetoothA2dpSink;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothA2dpSink;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dpSink;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothA2dpSink;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothA2dpSink;->isA2dpPlaying(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothA2dpSink;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->getPlayerSettings(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothAvrcpPlayerSettings;
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->sendGroupNavigationCmd(Landroid/bluetooth/BluetoothDevice;II)V
-Landroid/bluetooth/IBluetoothAvrcpController$Stub$Proxy;->setPlayerApplicationSetting(Landroid/bluetooth/BluetoothAvrcpPlayerSettings;)Z
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothAvrcpController;
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->TRANSACTION_getPlayerSettings:I
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->TRANSACTION_sendGroupNavigationCmd:I
-Landroid/bluetooth/IBluetoothAvrcpController$Stub;->TRANSACTION_setPlayerApplicationSetting:I
-Landroid/bluetooth/IBluetoothAvrcpController;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothAvrcpController;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothAvrcpController;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothAvrcpController;->getPlayerSettings(Landroid/bluetooth/BluetoothDevice;)Landroid/bluetooth/BluetoothAvrcpPlayerSettings;
-Landroid/bluetooth/IBluetoothAvrcpController;->sendGroupNavigationCmd(Landroid/bluetooth/BluetoothDevice;II)V
-Landroid/bluetooth/IBluetoothAvrcpController;->setPlayerApplicationSetting(Landroid/bluetooth/BluetoothAvrcpPlayerSettings;)Z
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub$Proxy;->sendVolumeChanged(I)V
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothAvrcpTarget;
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothAvrcpTarget$Stub;->TRANSACTION_sendVolumeChanged:I
-Landroid/bluetooth/IBluetoothAvrcpTarget;->sendVolumeChanged(I)V
-Landroid/bluetooth/IBluetoothCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothCallback$Stub$Proxy;->onBluetoothStateChange(II)V
-Landroid/bluetooth/IBluetoothCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothCallback;
-Landroid/bluetooth/IBluetoothCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothCallback$Stub;->TRANSACTION_onBluetoothStateChange:I
-Landroid/bluetooth/IBluetoothCallback;->onBluetoothStateChange(II)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->addService(ILandroid/bluetooth/BluetoothGattService;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->beginReliableWrite(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->clearServices(I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->clientConnect(ILjava/lang/String;ZIZI)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->clientDisconnect(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->clientReadPhy(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->clientSetPreferredPhy(ILjava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->configureMTU(ILjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->connectionParameterUpdate(ILjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->disconnectAll()V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->discoverServiceByUuid(ILjava/lang/String;Landroid/os/ParcelUuid;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->discoverServices(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->enableAdvertisingSet(IZII)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->endReliableWrite(ILjava/lang/String;Z)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->flushPendingBatchResults(I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->getOwnAddress(I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->leConnectionUpdate(ILjava/lang/String;IIIIII)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->numHwTrackFiltersAvailable()I
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->readCharacteristic(ILjava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->readDescriptor(ILjava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->readRemoteRssi(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->readUsingCharacteristicUuid(ILjava/lang/String;Landroid/os/ParcelUuid;III)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->refreshDevice(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->registerClient(Landroid/os/ParcelUuid;Landroid/bluetooth/IBluetoothGattCallback;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->registerForNotification(ILjava/lang/String;IZ)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->registerScanner(Landroid/bluetooth/le/IScannerCallback;Landroid/os/WorkSource;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->registerServer(Landroid/os/ParcelUuid;Landroid/bluetooth/IBluetoothGattServerCallback;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->registerSync(Landroid/bluetooth/le/ScanResult;IILandroid/bluetooth/le/IPeriodicAdvertisingCallback;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->removeService(II)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->sendNotification(ILjava/lang/String;IZ[B)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->sendResponse(ILjava/lang/String;III[B)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->serverConnect(ILjava/lang/String;ZI)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->serverDisconnect(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->serverReadPhy(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->serverSetPreferredPhy(ILjava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->setAdvertisingData(ILandroid/bluetooth/le/AdvertiseData;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->setAdvertisingParameters(ILandroid/bluetooth/le/AdvertisingSetParameters;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->setPeriodicAdvertisingData(ILandroid/bluetooth/le/AdvertiseData;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->setPeriodicAdvertisingEnable(IZ)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->setPeriodicAdvertisingParameters(ILandroid/bluetooth/le/PeriodicAdvertisingParameters;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->setScanResponseData(ILandroid/bluetooth/le/AdvertiseData;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->startAdvertisingSet(Landroid/bluetooth/le/AdvertisingSetParameters;Landroid/bluetooth/le/AdvertiseData;Landroid/bluetooth/le/AdvertiseData;Landroid/bluetooth/le/PeriodicAdvertisingParameters;Landroid/bluetooth/le/AdvertiseData;IILandroid/bluetooth/le/IAdvertisingSetCallback;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->startScan(ILandroid/bluetooth/le/ScanSettings;Ljava/util/List;Ljava/util/List;Ljava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->startScanForIntent(Landroid/app/PendingIntent;Landroid/bluetooth/le/ScanSettings;Ljava/util/List;Ljava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->stopAdvertisingSet(Landroid/bluetooth/le/IAdvertisingSetCallback;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->stopScan(I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->stopScanForIntent(Landroid/app/PendingIntent;Ljava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->unregAll()V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->unregisterClient(I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->unregisterScanner(I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->unregisterServer(I)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->unregisterSync(Landroid/bluetooth/le/IPeriodicAdvertisingCallback;)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->writeCharacteristic(ILjava/lang/String;III[B)V
-Landroid/bluetooth/IBluetoothGatt$Stub$Proxy;->writeDescriptor(ILjava/lang/String;II[B)V
-Landroid/bluetooth/IBluetoothGatt$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothGatt$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothGatt;
-Landroid/bluetooth/IBluetoothGatt$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_addService:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_beginReliableWrite:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_clearServices:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_clientConnect:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_clientDisconnect:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_clientReadPhy:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_clientSetPreferredPhy:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_configureMTU:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_connectionParameterUpdate:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_disconnectAll:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_discoverServiceByUuid:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_discoverServices:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_enableAdvertisingSet:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_endReliableWrite:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_flushPendingBatchResults:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_getOwnAddress:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_leConnectionUpdate:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_numHwTrackFiltersAvailable:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_readCharacteristic:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_readDescriptor:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_readRemoteRssi:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_readUsingCharacteristicUuid:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_refreshDevice:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_registerClient:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_registerForNotification:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_registerScanner:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_registerServer:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_registerSync:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_removeService:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_sendNotification:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_sendResponse:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_serverConnect:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_serverDisconnect:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_serverReadPhy:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_serverSetPreferredPhy:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_setAdvertisingData:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_setAdvertisingParameters:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_setPeriodicAdvertisingData:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_setPeriodicAdvertisingEnable:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_setPeriodicAdvertisingParameters:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_setScanResponseData:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_startAdvertisingSet:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_startScan:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_startScanForIntent:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_stopAdvertisingSet:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_stopScan:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_stopScanForIntent:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_unregAll:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_unregisterClient:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_unregisterScanner:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_unregisterServer:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_unregisterSync:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_writeCharacteristic:I
-Landroid/bluetooth/IBluetoothGatt$Stub;->TRANSACTION_writeDescriptor:I
-Landroid/bluetooth/IBluetoothGatt;->addService(ILandroid/bluetooth/BluetoothGattService;)V
-Landroid/bluetooth/IBluetoothGatt;->beginReliableWrite(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->clearServices(I)V
-Landroid/bluetooth/IBluetoothGatt;->clientConnect(ILjava/lang/String;ZIZI)V
-Landroid/bluetooth/IBluetoothGatt;->clientDisconnect(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->clientReadPhy(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->clientSetPreferredPhy(ILjava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGatt;->configureMTU(ILjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGatt;->connectionParameterUpdate(ILjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGatt;->disconnectAll()V
-Landroid/bluetooth/IBluetoothGatt;->discoverServiceByUuid(ILjava/lang/String;Landroid/os/ParcelUuid;)V
-Landroid/bluetooth/IBluetoothGatt;->discoverServices(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->enableAdvertisingSet(IZII)V
-Landroid/bluetooth/IBluetoothGatt;->endReliableWrite(ILjava/lang/String;Z)V
-Landroid/bluetooth/IBluetoothGatt;->flushPendingBatchResults(I)V
-Landroid/bluetooth/IBluetoothGatt;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothGatt;->getOwnAddress(I)V
-Landroid/bluetooth/IBluetoothGatt;->leConnectionUpdate(ILjava/lang/String;IIIIII)V
-Landroid/bluetooth/IBluetoothGatt;->numHwTrackFiltersAvailable()I
-Landroid/bluetooth/IBluetoothGatt;->readCharacteristic(ILjava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGatt;->readDescriptor(ILjava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGatt;->readRemoteRssi(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->readUsingCharacteristicUuid(ILjava/lang/String;Landroid/os/ParcelUuid;III)V
-Landroid/bluetooth/IBluetoothGatt;->refreshDevice(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->registerForNotification(ILjava/lang/String;IZ)V
-Landroid/bluetooth/IBluetoothGatt;->registerScanner(Landroid/bluetooth/le/IScannerCallback;Landroid/os/WorkSource;)V
-Landroid/bluetooth/IBluetoothGatt;->registerServer(Landroid/os/ParcelUuid;Landroid/bluetooth/IBluetoothGattServerCallback;)V
-Landroid/bluetooth/IBluetoothGatt;->registerSync(Landroid/bluetooth/le/ScanResult;IILandroid/bluetooth/le/IPeriodicAdvertisingCallback;)V
-Landroid/bluetooth/IBluetoothGatt;->removeService(II)V
-Landroid/bluetooth/IBluetoothGatt;->sendNotification(ILjava/lang/String;IZ[B)V
-Landroid/bluetooth/IBluetoothGatt;->sendResponse(ILjava/lang/String;III[B)V
-Landroid/bluetooth/IBluetoothGatt;->serverConnect(ILjava/lang/String;ZI)V
-Landroid/bluetooth/IBluetoothGatt;->serverDisconnect(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->serverReadPhy(ILjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->serverSetPreferredPhy(ILjava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGatt;->setAdvertisingData(ILandroid/bluetooth/le/AdvertiseData;)V
-Landroid/bluetooth/IBluetoothGatt;->setAdvertisingParameters(ILandroid/bluetooth/le/AdvertisingSetParameters;)V
-Landroid/bluetooth/IBluetoothGatt;->setPeriodicAdvertisingData(ILandroid/bluetooth/le/AdvertiseData;)V
-Landroid/bluetooth/IBluetoothGatt;->setPeriodicAdvertisingEnable(IZ)V
-Landroid/bluetooth/IBluetoothGatt;->setPeriodicAdvertisingParameters(ILandroid/bluetooth/le/PeriodicAdvertisingParameters;)V
-Landroid/bluetooth/IBluetoothGatt;->setScanResponseData(ILandroid/bluetooth/le/AdvertiseData;)V
-Landroid/bluetooth/IBluetoothGatt;->startAdvertisingSet(Landroid/bluetooth/le/AdvertisingSetParameters;Landroid/bluetooth/le/AdvertiseData;Landroid/bluetooth/le/AdvertiseData;Landroid/bluetooth/le/PeriodicAdvertisingParameters;Landroid/bluetooth/le/AdvertiseData;IILandroid/bluetooth/le/IAdvertisingSetCallback;)V
-Landroid/bluetooth/IBluetoothGatt;->startScan(ILandroid/bluetooth/le/ScanSettings;Ljava/util/List;Ljava/util/List;Ljava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->startScanForIntent(Landroid/app/PendingIntent;Landroid/bluetooth/le/ScanSettings;Ljava/util/List;Ljava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->stopAdvertisingSet(Landroid/bluetooth/le/IAdvertisingSetCallback;)V
-Landroid/bluetooth/IBluetoothGatt;->stopScan(I)V
-Landroid/bluetooth/IBluetoothGatt;->stopScanForIntent(Landroid/app/PendingIntent;Ljava/lang/String;)V
-Landroid/bluetooth/IBluetoothGatt;->unregAll()V
-Landroid/bluetooth/IBluetoothGatt;->unregisterScanner(I)V
-Landroid/bluetooth/IBluetoothGatt;->unregisterServer(I)V
-Landroid/bluetooth/IBluetoothGatt;->unregisterSync(Landroid/bluetooth/le/IPeriodicAdvertisingCallback;)V
-Landroid/bluetooth/IBluetoothGatt;->writeCharacteristic(ILjava/lang/String;III[B)V
-Landroid/bluetooth/IBluetoothGatt;->writeDescriptor(ILjava/lang/String;II[B)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onCharacteristicRead(Ljava/lang/String;II[B)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onCharacteristicWrite(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onClientConnectionState(IIZLjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onClientRegistered(II)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onConfigureMTU(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onConnectionUpdated(Ljava/lang/String;IIII)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onDescriptorRead(Ljava/lang/String;II[B)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onDescriptorWrite(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onExecuteWrite(Ljava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onNotify(Ljava/lang/String;I[B)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onPhyRead(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onPhyUpdate(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onReadRemoteRssi(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub$Proxy;->onSearchComplete(Ljava/lang/String;Ljava/util/List;I)V
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onCharacteristicRead:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onCharacteristicWrite:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onClientConnectionState:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onClientRegistered:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onConfigureMTU:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onConnectionUpdated:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onDescriptorRead:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onDescriptorWrite:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onExecuteWrite:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onNotify:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onPhyRead:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onPhyUpdate:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onReadRemoteRssi:I
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->TRANSACTION_onSearchComplete:I
-Landroid/bluetooth/IBluetoothGattCallback;->onCharacteristicRead(Ljava/lang/String;II[B)V
-Landroid/bluetooth/IBluetoothGattCallback;->onCharacteristicWrite(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback;->onClientConnectionState(IIZLjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGattCallback;->onClientRegistered(II)V
-Landroid/bluetooth/IBluetoothGattCallback;->onConfigureMTU(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback;->onConnectionUpdated(Ljava/lang/String;IIII)V
-Landroid/bluetooth/IBluetoothGattCallback;->onDescriptorRead(Ljava/lang/String;II[B)V
-Landroid/bluetooth/IBluetoothGattCallback;->onDescriptorWrite(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback;->onExecuteWrite(Ljava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGattCallback;->onNotify(Ljava/lang/String;I[B)V
-Landroid/bluetooth/IBluetoothGattCallback;->onPhyRead(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattCallback;->onPhyUpdate(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattCallback;->onReadRemoteRssi(Ljava/lang/String;II)V
-Landroid/bluetooth/IBluetoothGattCallback;->onSearchComplete(Ljava/lang/String;Ljava/util/List;I)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onCharacteristicReadRequest(Ljava/lang/String;IIZI)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onCharacteristicWriteRequest(Ljava/lang/String;IIIZZI[B)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onConnectionUpdated(Ljava/lang/String;IIII)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onDescriptorReadRequest(Ljava/lang/String;IIZI)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onDescriptorWriteRequest(Ljava/lang/String;IIIZZI[B)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onExecuteWrite(Ljava/lang/String;IZ)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onMtuChanged(Ljava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onNotificationSent(Ljava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onPhyRead(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onPhyUpdate(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onServerConnectionState(IIZLjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onServerRegistered(II)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub$Proxy;->onServiceAdded(ILandroid/bluetooth/BluetoothGattService;)V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothGattServerCallback;
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onCharacteristicReadRequest:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onCharacteristicWriteRequest:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onConnectionUpdated:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onDescriptorReadRequest:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onDescriptorWriteRequest:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onExecuteWrite:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onMtuChanged:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onNotificationSent:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onPhyRead:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onPhyUpdate:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onServerConnectionState:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onServerRegistered:I
-Landroid/bluetooth/IBluetoothGattServerCallback$Stub;->TRANSACTION_onServiceAdded:I
-Landroid/bluetooth/IBluetoothGattServerCallback;->onCharacteristicReadRequest(Ljava/lang/String;IIZI)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onCharacteristicWriteRequest(Ljava/lang/String;IIIZZI[B)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onConnectionUpdated(Ljava/lang/String;IIII)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onDescriptorReadRequest(Ljava/lang/String;IIZI)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onDescriptorWriteRequest(Ljava/lang/String;IIIZZI[B)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onExecuteWrite(Ljava/lang/String;IZ)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onMtuChanged(Ljava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onNotificationSent(Ljava/lang/String;I)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onPhyRead(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onPhyUpdate(Ljava/lang/String;III)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onServerConnectionState(IIZLjava/lang/String;)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onServerRegistered(II)V
-Landroid/bluetooth/IBluetoothGattServerCallback;->onServiceAdded(ILandroid/bluetooth/BluetoothGattService;)V
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->clccResponse(IIIIZLjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->connectAudio()Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->disconnectAudio()Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getAudioRouteAllowed()Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getAudioState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->isAudioConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->isAudioOn()Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->isInbandRingingEnabled()Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->phoneStateChanged(IIILjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->sendVendorSpecificResultCode(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->setActiveDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->setAudioRouteAllowed(Z)V
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->setForceScoAudio(Z)V
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->startScoUsingVirtualVoiceCall()Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->startVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->stopScoUsingVirtualVoiceCall()Z
-Landroid/bluetooth/IBluetoothHeadset$Stub$Proxy;->stopVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHeadset$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_clccResponse:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_connectAudio:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_disconnectAudio:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_getActiveDevice:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_getAudioRouteAllowed:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_getAudioState:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_isAudioConnected:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_isAudioOn:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_isInbandRingingEnabled:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_phoneStateChanged:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_sendVendorSpecificResultCode:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_setActiveDevice:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_setAudioRouteAllowed:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_setForceScoAudio:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_startScoUsingVirtualVoiceCall:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_startVoiceRecognition:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_stopScoUsingVirtualVoiceCall:I
-Landroid/bluetooth/IBluetoothHeadset$Stub;->TRANSACTION_stopVoiceRecognition:I
-Landroid/bluetooth/IBluetoothHeadset;->clccResponse(IIIIZLjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothHeadset;->connectAudio()Z
-Landroid/bluetooth/IBluetoothHeadset;->disconnectAudio()Z
-Landroid/bluetooth/IBluetoothHeadset;->getActiveDevice()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothHeadset;->getAudioRouteAllowed()Z
-Landroid/bluetooth/IBluetoothHeadset;->getAudioState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadset;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadset;->isAudioConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset;->isAudioOn()Z
-Landroid/bluetooth/IBluetoothHeadset;->isInbandRingingEnabled()Z
-Landroid/bluetooth/IBluetoothHeadset;->phoneStateChanged(IIILjava/lang/String;I)V
-Landroid/bluetooth/IBluetoothHeadset;->sendVendorSpecificResultCode(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothHeadset;->setActiveDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset;->setAudioRouteAllowed(Z)V
-Landroid/bluetooth/IBluetoothHeadset;->setForceScoAudio(Z)V
-Landroid/bluetooth/IBluetoothHeadset;->startScoUsingVirtualVoiceCall()Z
-Landroid/bluetooth/IBluetoothHeadset;->startVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadset;->stopScoUsingVirtualVoiceCall()Z
-Landroid/bluetooth/IBluetoothHeadset;->stopVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->acceptCall(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->connectAudio(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->dial(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Landroid/bluetooth/BluetoothHeadsetClientCall;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->disconnectAudio(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->enterPrivateMode(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->explicitCallTransfer(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getAudioRouteAllowed(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getAudioState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getCurrentAgEvents(Landroid/bluetooth/BluetoothDevice;)Landroid/os/Bundle;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getCurrentAgFeatures(Landroid/bluetooth/BluetoothDevice;)Landroid/os/Bundle;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getCurrentCalls(Landroid/bluetooth/BluetoothDevice;)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getLastVoiceTagNumber(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->holdCall(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->rejectCall(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->sendDTMF(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->setAudioRouteAllowed(Landroid/bluetooth/BluetoothDevice;Z)V
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->startVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->stopVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub$Proxy;->terminateCall(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHeadsetClientCall;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHeadsetClient;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_acceptCall:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_connectAudio:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_dial:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_disconnectAudio:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_enterPrivateMode:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_explicitCallTransfer:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getAudioRouteAllowed:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getAudioState:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getCurrentAgEvents:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getCurrentAgFeatures:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getCurrentCalls:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getLastVoiceTagNumber:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_holdCall:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_rejectCall:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_sendDTMF:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_setAudioRouteAllowed:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_startVoiceRecognition:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_stopVoiceRecognition:I
-Landroid/bluetooth/IBluetoothHeadsetClient$Stub;->TRANSACTION_terminateCall:I
-Landroid/bluetooth/IBluetoothHeadsetClient;->acceptCall(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->connectAudio(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->dial(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Landroid/bluetooth/BluetoothHeadsetClientCall;
-Landroid/bluetooth/IBluetoothHeadsetClient;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->disconnectAudio(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->enterPrivateMode(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->explicitCallTransfer(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->getAudioRouteAllowed(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->getAudioState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadsetClient;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadsetClient;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadsetClient;->getCurrentAgEvents(Landroid/bluetooth/BluetoothDevice;)Landroid/os/Bundle;
-Landroid/bluetooth/IBluetoothHeadsetClient;->getCurrentAgFeatures(Landroid/bluetooth/BluetoothDevice;)Landroid/os/Bundle;
-Landroid/bluetooth/IBluetoothHeadsetClient;->getCurrentCalls(Landroid/bluetooth/BluetoothDevice;)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadsetClient;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHeadsetClient;->getLastVoiceTagNumber(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHeadsetClient;->holdCall(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->rejectCall(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->sendDTMF(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->setAudioRouteAllowed(Landroid/bluetooth/BluetoothDevice;Z)V
-Landroid/bluetooth/IBluetoothHeadsetClient;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->startVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->stopVoiceRecognition(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHeadsetClient;->terminateCall(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHeadsetClientCall;)Z
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->answerCall()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->cdmaSetSecondCallState(Z)V
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->cdmaSwapSecondCallState()V
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->getNetworkOperator()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->getSubscriberNumber()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->hangupCall()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->listCurrentCalls()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->processChld(I)Z
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->queryPhoneState()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->sendDtmf(I)Z
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub$Proxy;->updateBtHandsfreeAfterRadioTechnologyChange()V
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHeadsetPhone;
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_answerCall:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_cdmaSetSecondCallState:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_cdmaSwapSecondCallState:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_getNetworkOperator:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_getSubscriberNumber:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_hangupCall:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_listCurrentCalls:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_processChld:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_queryPhoneState:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_sendDtmf:I
-Landroid/bluetooth/IBluetoothHeadsetPhone$Stub;->TRANSACTION_updateBtHandsfreeAfterRadioTechnologyChange:I
-Landroid/bluetooth/IBluetoothHeadsetPhone;->answerCall()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone;->cdmaSetSecondCallState(Z)V
-Landroid/bluetooth/IBluetoothHeadsetPhone;->cdmaSwapSecondCallState()V
-Landroid/bluetooth/IBluetoothHeadsetPhone;->getNetworkOperator()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetPhone;->getSubscriberNumber()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHeadsetPhone;->hangupCall()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone;->listCurrentCalls()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone;->processChld(I)Z
-Landroid/bluetooth/IBluetoothHeadsetPhone;->queryPhoneState()Z
-Landroid/bluetooth/IBluetoothHeadsetPhone;->sendDtmf(I)Z
-Landroid/bluetooth/IBluetoothHeadsetPhone;->updateBtHandsfreeAfterRadioTechnologyChange()V
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->connectChannelToSink(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;I)Z
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->connectChannelToSource(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;)Z
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->disconnectChannel(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;I)Z
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->getConnectedHealthDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->getHealthDeviceConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->getHealthDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->getMainChannelFd(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;)Landroid/os/ParcelFileDescriptor;
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->registerAppConfiguration(Landroid/bluetooth/BluetoothHealthAppConfiguration;Landroid/bluetooth/IBluetoothHealthCallback;)Z
-Landroid/bluetooth/IBluetoothHealth$Stub$Proxy;->unregisterAppConfiguration(Landroid/bluetooth/BluetoothHealthAppConfiguration;)Z
-Landroid/bluetooth/IBluetoothHealth$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHealth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHealth;
-Landroid/bluetooth/IBluetoothHealth$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_connectChannelToSink:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_connectChannelToSource:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_disconnectChannel:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_getConnectedHealthDevices:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_getHealthDeviceConnectionState:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_getHealthDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_getMainChannelFd:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_registerAppConfiguration:I
-Landroid/bluetooth/IBluetoothHealth$Stub;->TRANSACTION_unregisterAppConfiguration:I
-Landroid/bluetooth/IBluetoothHealth;->connectChannelToSink(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;I)Z
-Landroid/bluetooth/IBluetoothHealth;->connectChannelToSource(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;)Z
-Landroid/bluetooth/IBluetoothHealth;->disconnectChannel(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;I)Z
-Landroid/bluetooth/IBluetoothHealth;->getConnectedHealthDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHealth;->getHealthDeviceConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHealth;->getHealthDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHealth;->getMainChannelFd(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothHealthAppConfiguration;)Landroid/os/ParcelFileDescriptor;
-Landroid/bluetooth/IBluetoothHealth;->registerAppConfiguration(Landroid/bluetooth/BluetoothHealthAppConfiguration;Landroid/bluetooth/IBluetoothHealthCallback;)Z
-Landroid/bluetooth/IBluetoothHealth;->unregisterAppConfiguration(Landroid/bluetooth/BluetoothHealthAppConfiguration;)Z
-Landroid/bluetooth/IBluetoothHealthCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHealthCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHealthCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHealthCallback$Stub$Proxy;->onHealthAppConfigurationStatusChange(Landroid/bluetooth/BluetoothHealthAppConfiguration;I)V
-Landroid/bluetooth/IBluetoothHealthCallback$Stub$Proxy;->onHealthChannelStateChange(Landroid/bluetooth/BluetoothHealthAppConfiguration;Landroid/bluetooth/BluetoothDevice;IILandroid/os/ParcelFileDescriptor;I)V
-Landroid/bluetooth/IBluetoothHealthCallback$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHealthCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHealthCallback;
-Landroid/bluetooth/IBluetoothHealthCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHealthCallback$Stub;->TRANSACTION_onHealthAppConfigurationStatusChange:I
-Landroid/bluetooth/IBluetoothHealthCallback$Stub;->TRANSACTION_onHealthChannelStateChange:I
-Landroid/bluetooth/IBluetoothHealthCallback;->onHealthAppConfigurationStatusChange(Landroid/bluetooth/BluetoothHealthAppConfiguration;I)V
-Landroid/bluetooth/IBluetoothHealthCallback;->onHealthChannelStateChange(Landroid/bluetooth/BluetoothHealthAppConfiguration;Landroid/bluetooth/BluetoothDevice;IILandroid/os/ParcelFileDescriptor;I)V
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->adjustVolume(I)V
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getActiveDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getDeviceMode(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getDeviceSide(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getHiSyncId(Landroid/bluetooth/BluetoothDevice;)J
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->getVolume()I
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->setActiveDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHearingAid$Stub$Proxy;->setVolume(I)V
-Landroid/bluetooth/IBluetoothHearingAid$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHearingAid;
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_adjustVolume:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getActiveDevices:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getDeviceMode:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getDeviceSide:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getHiSyncId:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_getVolume:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_setActiveDevice:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothHearingAid$Stub;->TRANSACTION_setVolume:I
-Landroid/bluetooth/IBluetoothHearingAid;->adjustVolume(I)V
-Landroid/bluetooth/IBluetoothHearingAid;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHearingAid;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHearingAid;->getActiveDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHearingAid;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHearingAid;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid;->getDeviceMode(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid;->getDeviceSide(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHearingAid;->getHiSyncId(Landroid/bluetooth/BluetoothDevice;)J
-Landroid/bluetooth/IBluetoothHearingAid;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHearingAid;->getVolume()I
-Landroid/bluetooth/IBluetoothHearingAid;->HI_SYNC_ID_INVALID:I
-Landroid/bluetooth/IBluetoothHearingAid;->MODE_BINAURAL:I
-Landroid/bluetooth/IBluetoothHearingAid;->MODE_MONAURAL:I
-Landroid/bluetooth/IBluetoothHearingAid;->setActiveDevice(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHearingAid;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHearingAid;->setVolume(I)V
-Landroid/bluetooth/IBluetoothHearingAid;->SIDE_LEFT:I
-Landroid/bluetooth/IBluetoothHearingAid;->SIDE_RIGHT:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->getUserAppName()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->registerApp(Landroid/bluetooth/BluetoothHidDeviceAppSdpSettings;Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;Landroid/bluetooth/IBluetoothHidDeviceCallback;)Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->replyReport(Landroid/bluetooth/BluetoothDevice;BB[B)Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->reportError(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->sendReport(Landroid/bluetooth/BluetoothDevice;I[B)Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->unplug(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub$Proxy;->unregisterApp()Z
-Landroid/bluetooth/IBluetoothHidDevice$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHidDevice;
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_getUserAppName:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_registerApp:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_replyReport:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_reportError:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_sendReport:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_unplug:I
-Landroid/bluetooth/IBluetoothHidDevice$Stub;->TRANSACTION_unregisterApp:I
-Landroid/bluetooth/IBluetoothHidDevice;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidDevice;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidDevice;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidDevice;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHidDevice;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidDevice;->getUserAppName()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidDevice;->registerApp(Landroid/bluetooth/BluetoothHidDeviceAppSdpSettings;Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;Landroid/bluetooth/BluetoothHidDeviceAppQosSettings;Landroid/bluetooth/IBluetoothHidDeviceCallback;)Z
-Landroid/bluetooth/IBluetoothHidDevice;->replyReport(Landroid/bluetooth/BluetoothDevice;BB[B)Z
-Landroid/bluetooth/IBluetoothHidDevice;->reportError(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/IBluetoothHidDevice;->sendReport(Landroid/bluetooth/BluetoothDevice;I[B)Z
-Landroid/bluetooth/IBluetoothHidDevice;->unplug(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidDevice;->unregisterApp()Z
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->onAppStatusChanged(Landroid/bluetooth/BluetoothDevice;Z)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->onConnectionStateChanged(Landroid/bluetooth/BluetoothDevice;I)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->onGetReport(Landroid/bluetooth/BluetoothDevice;BBI)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->onInterruptData(Landroid/bluetooth/BluetoothDevice;B[B)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->onSetProtocol(Landroid/bluetooth/BluetoothDevice;B)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->onSetReport(Landroid/bluetooth/BluetoothDevice;BB[B)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub$Proxy;->onVirtualCableUnplug(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHidDeviceCallback;
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->TRANSACTION_onAppStatusChanged:I
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->TRANSACTION_onConnectionStateChanged:I
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->TRANSACTION_onGetReport:I
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->TRANSACTION_onInterruptData:I
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->TRANSACTION_onSetProtocol:I
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->TRANSACTION_onSetReport:I
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;->TRANSACTION_onVirtualCableUnplug:I
-Landroid/bluetooth/IBluetoothHidDeviceCallback;->onAppStatusChanged(Landroid/bluetooth/BluetoothDevice;Z)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback;->onConnectionStateChanged(Landroid/bluetooth/BluetoothDevice;I)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback;->onGetReport(Landroid/bluetooth/BluetoothDevice;BBI)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback;->onInterruptData(Landroid/bluetooth/BluetoothDevice;B[B)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback;->onSetProtocol(Landroid/bluetooth/BluetoothDevice;B)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback;->onSetReport(Landroid/bluetooth/BluetoothDevice;BB[B)V
-Landroid/bluetooth/IBluetoothHidDeviceCallback;->onVirtualCableUnplug(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getIdleTime(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getProtocolMode(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->getReport(Landroid/bluetooth/BluetoothDevice;BBI)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->sendData(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->setIdleTime(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->setProtocolMode(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->setReport(Landroid/bluetooth/BluetoothDevice;BLjava/lang/String;)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub$Proxy;->virtualUnplug(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothHidHost$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHidHost;
-Landroid/bluetooth/IBluetoothHidHost$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_getIdleTime:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_getProtocolMode:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_getReport:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_sendData:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_setIdleTime:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_setProtocolMode:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_setReport:I
-Landroid/bluetooth/IBluetoothHidHost$Stub;->TRANSACTION_virtualUnplug:I
-Landroid/bluetooth/IBluetoothHidHost;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidHost;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHidHost;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothHidHost;->getIdleTime(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothHidHost;->getProtocolMode(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothHidHost;->getReport(Landroid/bluetooth/BluetoothDevice;BBI)Z
-Landroid/bluetooth/IBluetoothHidHost;->sendData(Landroid/bluetooth/BluetoothDevice;Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothHidHost;->setIdleTime(Landroid/bluetooth/BluetoothDevice;B)Z
-Landroid/bluetooth/IBluetoothHidHost;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHidHost;->setProtocolMode(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothHidHost;->setReport(Landroid/bluetooth/BluetoothDevice;BLjava/lang/String;)Z
-Landroid/bluetooth/IBluetoothHidHost;->virtualUnplug(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->bindBluetoothProfileService(ILandroid/bluetooth/IBluetoothProfileServiceConnection;)Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->disable(Ljava/lang/String;Z)Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->enable(Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->enableNoAutoConnect(Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->getAddress()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->getBluetoothGatt()Landroid/bluetooth/IBluetoothGatt;
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->getName()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->getState()I
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->isBleAppPresent()Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->isBleScanAlwaysAvailable()Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->isEnabled()Z
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->registerAdapter(Landroid/bluetooth/IBluetoothManagerCallback;)Landroid/bluetooth/IBluetooth;
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->registerStateChangeCallback(Landroid/bluetooth/IBluetoothStateChangeCallback;)V
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->unbindBluetoothProfileService(ILandroid/bluetooth/IBluetoothProfileServiceConnection;)V
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->unregisterAdapter(Landroid/bluetooth/IBluetoothManagerCallback;)V
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->unregisterStateChangeCallback(Landroid/bluetooth/IBluetoothStateChangeCallback;)V
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;->updateBleAppCount(Landroid/os/IBinder;ZLjava/lang/String;)I
-Landroid/bluetooth/IBluetoothManager$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothManager$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_bindBluetoothProfileService:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_disable:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_enableNoAutoConnect:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_getAddress:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_getBluetoothGatt:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_getName:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_getState:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_isBleAppPresent:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_isBleScanAlwaysAvailable:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_isEnabled:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_registerAdapter:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_registerStateChangeCallback:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_unbindBluetoothProfileService:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_unregisterAdapter:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_unregisterStateChangeCallback:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_updateBleAppCount:I
-Landroid/bluetooth/IBluetoothManager;->bindBluetoothProfileService(ILandroid/bluetooth/IBluetoothProfileServiceConnection;)Z
-Landroid/bluetooth/IBluetoothManager;->disable(Ljava/lang/String;Z)Z
-Landroid/bluetooth/IBluetoothManager;->enable(Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothManager;->enableNoAutoConnect(Ljava/lang/String;)Z
-Landroid/bluetooth/IBluetoothManager;->getAddress()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManager;->getName()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManager;->getState()I
-Landroid/bluetooth/IBluetoothManager;->isBleAppPresent()Z
-Landroid/bluetooth/IBluetoothManager;->isBleScanAlwaysAvailable()Z
-Landroid/bluetooth/IBluetoothManager;->isEnabled()Z
-Landroid/bluetooth/IBluetoothManager;->registerAdapter(Landroid/bluetooth/IBluetoothManagerCallback;)Landroid/bluetooth/IBluetooth;
-Landroid/bluetooth/IBluetoothManager;->unbindBluetoothProfileService(ILandroid/bluetooth/IBluetoothProfileServiceConnection;)V
-Landroid/bluetooth/IBluetoothManager;->unregisterAdapter(Landroid/bluetooth/IBluetoothManagerCallback;)V
-Landroid/bluetooth/IBluetoothManager;->updateBleAppCount(Landroid/os/IBinder;ZLjava/lang/String;)I
-Landroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;->onBluetoothServiceDown()V
-Landroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;->onBluetoothServiceUp(Landroid/bluetooth/IBluetooth;)V
-Landroid/bluetooth/IBluetoothManagerCallback$Stub$Proxy;->onBrEdrDown()V
-Landroid/bluetooth/IBluetoothManagerCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothManagerCallback;
-Landroid/bluetooth/IBluetoothManagerCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothManagerCallback$Stub;->TRANSACTION_onBluetoothServiceDown:I
-Landroid/bluetooth/IBluetoothManagerCallback$Stub;->TRANSACTION_onBluetoothServiceUp:I
-Landroid/bluetooth/IBluetoothManagerCallback$Stub;->TRANSACTION_onBrEdrDown:I
-Landroid/bluetooth/IBluetoothManagerCallback;->onBluetoothServiceDown()V
-Landroid/bluetooth/IBluetoothManagerCallback;->onBluetoothServiceUp(Landroid/bluetooth/IBluetooth;)V
-Landroid/bluetooth/IBluetoothManagerCallback;->onBrEdrDown()V
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->getClient()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->getState()I
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothMap$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothMap$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothMap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothMap;
-Landroid/bluetooth/IBluetoothMap$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_getClient:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_getState:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_isConnected:I
-Landroid/bluetooth/IBluetoothMap$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothMap;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMap;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMap;->getClient()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothMap;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothMap;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMap;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothMap;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMap;->getState()I
-Landroid/bluetooth/IBluetoothMap;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMap;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->getUnreadMessages(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->sendMessage(Landroid/bluetooth/BluetoothDevice;[Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)Z
-Landroid/bluetooth/IBluetoothMapClient$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothMapClient$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothMapClient$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothMapClient;
-Landroid/bluetooth/IBluetoothMapClient$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_getUnreadMessages:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_isConnected:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_sendMessage:I
-Landroid/bluetooth/IBluetoothMapClient$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothMapClient;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothMapClient;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMapClient;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothMapClient;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothMapClient;->getUnreadMessages(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothMapClient;->sendMessage(Landroid/bluetooth/BluetoothDevice;[Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)Z
-Landroid/bluetooth/IBluetoothMapClient;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->isTetheringOn()Z
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothPan$Stub$Proxy;->setBluetoothTethering(Z)V
-Landroid/bluetooth/IBluetoothPan$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothPan$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPan;
-Landroid/bluetooth/IBluetoothPan$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothPan$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothPan$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothPan$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothPan$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothPan$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothPan$Stub;->TRANSACTION_isTetheringOn:I
-Landroid/bluetooth/IBluetoothPan$Stub;->TRANSACTION_setBluetoothTethering:I
-Landroid/bluetooth/IBluetoothPan;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPan;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPan;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothPan;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPan;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothPan;->isTetheringOn()Z
-Landroid/bluetooth/IBluetoothPan;->setBluetoothTethering(Z)V
-Landroid/bluetooth/IBluetoothPbap$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothPbap$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothPbap$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbap$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPbap$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbap$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothPbap$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothPbap$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothPbap$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothPbap$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothPbap$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothPbap$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothPbap$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothPbap;->disconnect(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothPbap;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbap;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPbap;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothPbapClient$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothPbapClient$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPbapClient;
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothPbapClient$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothPbapClient;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPbapClient;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothPbapClient;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbapClient;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPbapClient;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothPbapClient;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothPbapClient;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub$Proxy;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub$Proxy;->onServiceDisconnected(Landroid/content/ComponentName;)V
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothProfileServiceConnection;
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub;->TRANSACTION_onServiceConnected:I
-Landroid/bluetooth/IBluetoothProfileServiceConnection$Stub;->TRANSACTION_onServiceDisconnected:I
-Landroid/bluetooth/IBluetoothProfileServiceConnection;->onServiceConnected(Landroid/content/ComponentName;Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothProfileServiceConnection;->onServiceDisconnected(Landroid/content/ComponentName;)V
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->getClient()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->getState()I
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothSap$Stub$Proxy;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothSap$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothSap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothSap;
-Landroid/bluetooth/IBluetoothSap$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_connect:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_disconnect:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_getClient:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_getConnectedDevices:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_getConnectionState:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_getDevicesMatchingConnectionStates:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_getPriority:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_getState:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_isConnected:I
-Landroid/bluetooth/IBluetoothSap$Stub;->TRANSACTION_setPriority:I
-Landroid/bluetooth/IBluetoothSap;->connect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothSap;->disconnect(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothSap;->getClient()Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/IBluetoothSap;->getConnectedDevices()Ljava/util/List;
-Landroid/bluetooth/IBluetoothSap;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothSap;->getDevicesMatchingConnectionStates([I)Ljava/util/List;
-Landroid/bluetooth/IBluetoothSap;->getPriority(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetoothSap;->getState()I
-Landroid/bluetooth/IBluetoothSap;->isConnected(Landroid/bluetooth/BluetoothDevice;)Z
-Landroid/bluetooth/IBluetoothSap;->setPriority(Landroid/bluetooth/BluetoothDevice;I)Z
-Landroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;->connectSocket(Landroid/bluetooth/BluetoothDevice;ILandroid/os/ParcelUuid;II)Landroid/os/ParcelFileDescriptor;
-Landroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;->createSocketChannel(ILjava/lang/String;Landroid/os/ParcelUuid;II)Landroid/os/ParcelFileDescriptor;
-Landroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothSocketManager$Stub$Proxy;->requestMaximumTxDataLength(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothSocketManager$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothSocketManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothSocketManager;
-Landroid/bluetooth/IBluetoothSocketManager$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothSocketManager$Stub;->TRANSACTION_connectSocket:I
-Landroid/bluetooth/IBluetoothSocketManager$Stub;->TRANSACTION_createSocketChannel:I
-Landroid/bluetooth/IBluetoothSocketManager$Stub;->TRANSACTION_requestMaximumTxDataLength:I
-Landroid/bluetooth/IBluetoothSocketManager;->connectSocket(Landroid/bluetooth/BluetoothDevice;ILandroid/os/ParcelUuid;II)Landroid/os/ParcelFileDescriptor;
-Landroid/bluetooth/IBluetoothSocketManager;->createSocketChannel(ILjava/lang/String;Landroid/os/ParcelUuid;II)Landroid/os/ParcelFileDescriptor;
-Landroid/bluetooth/IBluetoothSocketManager;->requestMaximumTxDataLength(Landroid/bluetooth/BluetoothDevice;)V
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub$Proxy;->onBluetoothStateChange(Z)V
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothStateChangeCallback;
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;->TRANSACTION_onBluetoothStateChange:I
-Landroid/bluetooth/IBluetoothStateChangeCallback;->onBluetoothStateChange(Z)V
-Landroid/bluetooth/le/AdvertiseCallback;->ADVERTISE_SUCCESS:I
-Landroid/bluetooth/le/AdvertiseData$Builder;->mIncludeDeviceName:Z
-Landroid/bluetooth/le/AdvertiseData$Builder;->mIncludeTxPowerLevel:Z
-Landroid/bluetooth/le/AdvertiseData$Builder;->mManufacturerSpecificData:Landroid/util/SparseArray;
-Landroid/bluetooth/le/AdvertiseData$Builder;->mServiceData:Ljava/util/Map;
-Landroid/bluetooth/le/AdvertiseData$Builder;->mServiceUuids:Ljava/util/List;
-Landroid/bluetooth/le/AdvertiseData;-><init>(Ljava/util/List;Landroid/util/SparseArray;Ljava/util/Map;ZZ)V
-Landroid/bluetooth/le/AdvertiseData;->mIncludeDeviceName:Z
-Landroid/bluetooth/le/AdvertiseData;->mIncludeTxPowerLevel:Z
-Landroid/bluetooth/le/AdvertiseData;->mManufacturerSpecificData:Landroid/util/SparseArray;
-Landroid/bluetooth/le/AdvertiseData;->mServiceData:Ljava/util/Map;
-Landroid/bluetooth/le/AdvertiseData;->mServiceUuids:Ljava/util/List;
-Landroid/bluetooth/le/AdvertiseSettings$Builder;->mConnectable:Z
-Landroid/bluetooth/le/AdvertiseSettings$Builder;->mMode:I
-Landroid/bluetooth/le/AdvertiseSettings$Builder;->mTimeoutMillis:I
-Landroid/bluetooth/le/AdvertiseSettings$Builder;->mTxPowerLevel:I
-Landroid/bluetooth/le/AdvertiseSettings;-><init>(IIZI)V
-Landroid/bluetooth/le/AdvertiseSettings;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/AdvertiseSettings;->LIMITED_ADVERTISING_MAX_MILLIS:I
-Landroid/bluetooth/le/AdvertiseSettings;->mAdvertiseConnectable:Z
-Landroid/bluetooth/le/AdvertiseSettings;->mAdvertiseMode:I
-Landroid/bluetooth/le/AdvertiseSettings;->mAdvertiseTimeoutMillis:I
-Landroid/bluetooth/le/AdvertiseSettings;->mAdvertiseTxPowerLevel:I
-Landroid/bluetooth/le/AdvertisingSet;-><init>(ILandroid/bluetooth/IBluetoothManager;)V
-Landroid/bluetooth/le/AdvertisingSet;->getAdvertiserId()I
-Landroid/bluetooth/le/AdvertisingSet;->getOwnAddress()V
-Landroid/bluetooth/le/AdvertisingSet;->mAdvertiserId:I
-Landroid/bluetooth/le/AdvertisingSet;->mGatt:Landroid/bluetooth/IBluetoothGatt;
-Landroid/bluetooth/le/AdvertisingSet;->setAdvertiserId(I)V
-Landroid/bluetooth/le/AdvertisingSet;->TAG:Ljava/lang/String;
-Landroid/bluetooth/le/AdvertisingSetCallback;->onOwnAddressRead(Landroid/bluetooth/le/AdvertisingSet;ILjava/lang/String;)V
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mConnectable:Z
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mIncludeTxPower:Z
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mInterval:I
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mIsAnonymous:Z
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mIsLegacy:Z
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mPrimaryPhy:I
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mScannable:Z
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mSecondaryPhy:I
-Landroid/bluetooth/le/AdvertisingSetParameters$Builder;->mTxPowerLevel:I
-Landroid/bluetooth/le/AdvertisingSetParameters;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/AdvertisingSetParameters;-><init>(ZZZZZIIII)V
-Landroid/bluetooth/le/AdvertisingSetParameters;->LIMITED_ADVERTISING_MAX_MILLIS:I
-Landroid/bluetooth/le/AdvertisingSetParameters;->mConnectable:Z
-Landroid/bluetooth/le/AdvertisingSetParameters;->mIncludeTxPower:Z
-Landroid/bluetooth/le/AdvertisingSetParameters;->mInterval:I
-Landroid/bluetooth/le/AdvertisingSetParameters;->mIsAnonymous:Z
-Landroid/bluetooth/le/AdvertisingSetParameters;->mIsLegacy:Z
-Landroid/bluetooth/le/AdvertisingSetParameters;->mPrimaryPhy:I
-Landroid/bluetooth/le/AdvertisingSetParameters;->mScannable:Z
-Landroid/bluetooth/le/AdvertisingSetParameters;->mSecondaryPhy:I
-Landroid/bluetooth/le/AdvertisingSetParameters;->mTxPowerLevel:I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;-><init>(Landroid/bluetooth/IBluetoothManager;)V
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->byteLength([B)I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->cleanup()V
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->FLAGS_FIELD_BYTES:I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->mAdvertisingSets:Ljava/util/Map;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->MANUFACTURER_SPECIFIC_DATA_LENGTH:I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->MAX_ADVERTISING_DATA_BYTES:I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->MAX_LEGACY_ADVERTISING_DATA_BYTES:I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->mBluetoothAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->mBluetoothManager:Landroid/bluetooth/IBluetoothManager;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->mCallbackWrappers:Ljava/util/Map;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->mHandler:Landroid/os/Handler;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->mLegacyAdvertisers:Ljava/util/Map;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->OVERHEAD_BYTES_PER_FIELD:I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->postStartFailure(Landroid/bluetooth/le/AdvertiseCallback;I)V
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->postStartSetFailure(Landroid/os/Handler;Landroid/bluetooth/le/AdvertisingSetCallback;I)V
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->postStartSuccess(Landroid/bluetooth/le/AdvertiseCallback;Landroid/bluetooth/le/AdvertiseSettings;)V
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->TAG:Ljava/lang/String;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->totalBytes(Landroid/bluetooth/le/AdvertiseData;Z)I
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->wrap(Landroid/bluetooth/le/AdvertisingSetCallback;Landroid/os/Handler;)Landroid/bluetooth/le/IAdvertisingSetCallback;
-Landroid/bluetooth/le/BluetoothLeAdvertiser;->wrapOldCallback(Landroid/bluetooth/le/AdvertiseCallback;Landroid/bluetooth/le/AdvertiseSettings;)Landroid/bluetooth/le/AdvertisingSetCallback;
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->flushPendingBatchResults()V
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->mBluetoothGatt:Landroid/bluetooth/IBluetoothGatt;
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->mFilters:Ljava/util/List;
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->mResultStorages:Ljava/util/List;
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->mScanCallback:Landroid/bluetooth/le/ScanCallback;
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->mScannerId:I
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->mSettings:Landroid/bluetooth/le/ScanSettings;
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->mWorkSource:Landroid/os/WorkSource;
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->onBatchScanResults(Ljava/util/List;)V
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->onFoundOrLost(ZLandroid/bluetooth/le/ScanResult;)V
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->onScanManagerErrorCallback(I)V
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->onScannerRegistered(II)V
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->onScanResult(Landroid/bluetooth/le/ScanResult;)V
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->REGISTRATION_CALLBACK_TIMEOUT_MILLIS:I
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->startRegistration()V
-Landroid/bluetooth/le/BluetoothLeScanner$BleScanCallbackWrapper;->stopLeScan()V
-Landroid/bluetooth/le/BluetoothLeScanner;-><init>(Landroid/bluetooth/IBluetoothManager;)V
-Landroid/bluetooth/le/BluetoothLeScanner;->cleanup()V
-Landroid/bluetooth/le/BluetoothLeScanner;->DBG:Z
-Landroid/bluetooth/le/BluetoothLeScanner;->isHardwareResourcesAvailableForScan(Landroid/bluetooth/le/ScanSettings;)Z
-Landroid/bluetooth/le/BluetoothLeScanner;->isSettingsAndFilterComboAllowed(Landroid/bluetooth/le/ScanSettings;Ljava/util/List;)Z
-Landroid/bluetooth/le/BluetoothLeScanner;->isSettingsConfigAllowedForScan(Landroid/bluetooth/le/ScanSettings;)Z
-Landroid/bluetooth/le/BluetoothLeScanner;->mBluetoothAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/le/BluetoothLeScanner;->mBluetoothManager:Landroid/bluetooth/IBluetoothManager;
-Landroid/bluetooth/le/BluetoothLeScanner;->mHandler:Landroid/os/Handler;
-Landroid/bluetooth/le/BluetoothLeScanner;->mLeScanClients:Ljava/util/Map;
-Landroid/bluetooth/le/BluetoothLeScanner;->postCallbackError(Landroid/bluetooth/le/ScanCallback;I)V
-Landroid/bluetooth/le/BluetoothLeScanner;->postCallbackErrorOrReturn(Landroid/bluetooth/le/ScanCallback;I)I
-Landroid/bluetooth/le/BluetoothLeScanner;->startScan(Ljava/util/List;Landroid/bluetooth/le/ScanSettings;Landroid/os/WorkSource;Landroid/bluetooth/le/ScanCallback;Landroid/app/PendingIntent;Ljava/util/List;)I
-Landroid/bluetooth/le/BluetoothLeScanner;->TAG:Ljava/lang/String;
-Landroid/bluetooth/le/BluetoothLeScanner;->VDBG:Z
-Landroid/bluetooth/le/BluetoothLeUtils;-><init>()V
-Landroid/bluetooth/le/BluetoothLeUtils;->checkAdapterStateOn(Landroid/bluetooth/BluetoothAdapter;)V
-Landroid/bluetooth/le/BluetoothLeUtils;->equals(Landroid/util/SparseArray;Landroid/util/SparseArray;)Z
-Landroid/bluetooth/le/BluetoothLeUtils;->equals(Ljava/util/Map;Ljava/util/Map;)Z
-Landroid/bluetooth/le/BluetoothLeUtils;->toString(Landroid/util/SparseArray;)Ljava/lang/String;
-Landroid/bluetooth/le/BluetoothLeUtils;->toString(Ljava/util/Map;)Ljava/lang/String;
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onAdvertisingDataSet(II)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onAdvertisingEnabled(IZI)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onAdvertisingParametersUpdated(III)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onAdvertisingSetStarted(III)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onAdvertisingSetStopped(I)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onOwnAddressRead(IILjava/lang/String;)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onPeriodicAdvertisingDataSet(II)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onPeriodicAdvertisingEnabled(IZI)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onPeriodicAdvertisingParametersUpdated(II)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub$Proxy;->onScanResponseDataSet(II)V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;-><init>()V
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/le/IAdvertisingSetCallback;
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onAdvertisingDataSet:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onAdvertisingEnabled:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onAdvertisingParametersUpdated:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onAdvertisingSetStarted:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onAdvertisingSetStopped:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onOwnAddressRead:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onPeriodicAdvertisingDataSet:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onPeriodicAdvertisingEnabled:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onPeriodicAdvertisingParametersUpdated:I
-Landroid/bluetooth/le/IAdvertisingSetCallback$Stub;->TRANSACTION_onScanResponseDataSet:I
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onAdvertisingDataSet(II)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onAdvertisingEnabled(IZI)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onAdvertisingParametersUpdated(III)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onAdvertisingSetStarted(III)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onAdvertisingSetStopped(I)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onOwnAddressRead(IILjava/lang/String;)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onPeriodicAdvertisingDataSet(II)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onPeriodicAdvertisingEnabled(IZI)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onPeriodicAdvertisingParametersUpdated(II)V
-Landroid/bluetooth/le/IAdvertisingSetCallback;->onScanResponseDataSet(II)V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub$Proxy;->onPeriodicAdvertisingReport(Landroid/bluetooth/le/PeriodicAdvertisingReport;)V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub$Proxy;->onSyncEstablished(ILandroid/bluetooth/BluetoothDevice;IIII)V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub$Proxy;->onSyncLost(I)V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub;-><init>()V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/le/IPeriodicAdvertisingCallback;
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub;->TRANSACTION_onPeriodicAdvertisingReport:I
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub;->TRANSACTION_onSyncEstablished:I
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback$Stub;->TRANSACTION_onSyncLost:I
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback;->onPeriodicAdvertisingReport(Landroid/bluetooth/le/PeriodicAdvertisingReport;)V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback;->onSyncEstablished(ILandroid/bluetooth/BluetoothDevice;IIII)V
-Landroid/bluetooth/le/IPeriodicAdvertisingCallback;->onSyncLost(I)V
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;->onBatchScanResults(Ljava/util/List;)V
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;->onFoundOrLost(ZLandroid/bluetooth/le/ScanResult;)V
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;->onScanManagerErrorCallback(I)V
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;->onScannerRegistered(II)V
-Landroid/bluetooth/le/IScannerCallback$Stub$Proxy;->onScanResult(Landroid/bluetooth/le/ScanResult;)V
-Landroid/bluetooth/le/IScannerCallback$Stub;-><init>()V
-Landroid/bluetooth/le/IScannerCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/le/IScannerCallback;
-Landroid/bluetooth/le/IScannerCallback$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/bluetooth/le/IScannerCallback$Stub;->TRANSACTION_onBatchScanResults:I
-Landroid/bluetooth/le/IScannerCallback$Stub;->TRANSACTION_onFoundOrLost:I
-Landroid/bluetooth/le/IScannerCallback$Stub;->TRANSACTION_onScanManagerErrorCallback:I
-Landroid/bluetooth/le/IScannerCallback$Stub;->TRANSACTION_onScannerRegistered:I
-Landroid/bluetooth/le/IScannerCallback$Stub;->TRANSACTION_onScanResult:I
-Landroid/bluetooth/le/IScannerCallback;->onBatchScanResults(Ljava/util/List;)V
-Landroid/bluetooth/le/IScannerCallback;->onFoundOrLost(ZLandroid/bluetooth/le/ScanResult;)V
-Landroid/bluetooth/le/IScannerCallback;->onScanManagerErrorCallback(I)V
-Landroid/bluetooth/le/IScannerCallback;->onScannerRegistered(II)V
-Landroid/bluetooth/le/IScannerCallback;->onScanResult(Landroid/bluetooth/le/ScanResult;)V
-Landroid/bluetooth/le/PeriodicAdvertisingCallback;-><init>()V
-Landroid/bluetooth/le/PeriodicAdvertisingCallback;->onPeriodicAdvertisingReport(Landroid/bluetooth/le/PeriodicAdvertisingReport;)V
-Landroid/bluetooth/le/PeriodicAdvertisingCallback;->onSyncEstablished(ILandroid/bluetooth/BluetoothDevice;IIII)V
-Landroid/bluetooth/le/PeriodicAdvertisingCallback;->onSyncLost(I)V
-Landroid/bluetooth/le/PeriodicAdvertisingCallback;->SYNC_NO_RESOURCES:I
-Landroid/bluetooth/le/PeriodicAdvertisingCallback;->SYNC_NO_RESPONSE:I
-Landroid/bluetooth/le/PeriodicAdvertisingCallback;->SYNC_SUCCESS:I
-Landroid/bluetooth/le/PeriodicAdvertisingManager;-><init>(Landroid/bluetooth/IBluetoothManager;)V
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->mBluetoothAdapter:Landroid/bluetooth/BluetoothAdapter;
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->mBluetoothManager:Landroid/bluetooth/IBluetoothManager;
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->mCallbackWrappers:Ljava/util/Map;
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->registerSync(Landroid/bluetooth/le/ScanResult;IILandroid/bluetooth/le/PeriodicAdvertisingCallback;)V
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->registerSync(Landroid/bluetooth/le/ScanResult;IILandroid/bluetooth/le/PeriodicAdvertisingCallback;Landroid/os/Handler;)V
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->SKIP_MAX:I
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->SKIP_MIN:I
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->SYNC_STARTING:I
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->TAG:Ljava/lang/String;
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->TIMEOUT_MAX:I
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->TIMEOUT_MIN:I
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->unregisterSync(Landroid/bluetooth/le/PeriodicAdvertisingCallback;)V
-Landroid/bluetooth/le/PeriodicAdvertisingManager;->wrap(Landroid/bluetooth/le/PeriodicAdvertisingCallback;Landroid/os/Handler;)Landroid/bluetooth/le/IPeriodicAdvertisingCallback;
-Landroid/bluetooth/le/PeriodicAdvertisingParameters$Builder;->mIncludeTxPower:Z
-Landroid/bluetooth/le/PeriodicAdvertisingParameters$Builder;->mInterval:I
-Landroid/bluetooth/le/PeriodicAdvertisingParameters;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/PeriodicAdvertisingParameters;-><init>(ZI)V
-Landroid/bluetooth/le/PeriodicAdvertisingParameters;->INTERVAL_MAX:I
-Landroid/bluetooth/le/PeriodicAdvertisingParameters;->INTERVAL_MIN:I
-Landroid/bluetooth/le/PeriodicAdvertisingParameters;->mIncludeTxPower:Z
-Landroid/bluetooth/le/PeriodicAdvertisingParameters;->mInterval:I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;-><init>(IIIILandroid/bluetooth/le/ScanRecord;)V
-Landroid/bluetooth/le/PeriodicAdvertisingReport;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->DATA_COMPLETE:I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->DATA_INCOMPLETE_TRUNCATED:I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->getData()Landroid/bluetooth/le/ScanRecord;
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->getDataStatus()I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->getRssi()I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->getSyncHandle()I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->getTimestampNanos()J
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->getTxPower()I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->mData:Landroid/bluetooth/le/ScanRecord;
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->mDataStatus:I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->mRssi:I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->mSyncHandle:I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->mTimestampNanos:J
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->mTxPower:I
-Landroid/bluetooth/le/PeriodicAdvertisingReport;->readFromParcel(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/ResultStorageDescriptor;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/ResultStorageDescriptor;->mLength:I
-Landroid/bluetooth/le/ResultStorageDescriptor;->mOffset:I
-Landroid/bluetooth/le/ResultStorageDescriptor;->mType:I
-Landroid/bluetooth/le/ResultStorageDescriptor;->ReadFromParcel(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/ScanCallback;->NO_ERROR:I
-Landroid/bluetooth/le/ScanCallback;->SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES:I
-Landroid/bluetooth/le/ScanCallback;->SCAN_FAILED_SCANNING_TOO_FREQUENTLY:I
-Landroid/bluetooth/le/ScanFilter$Builder;->mDeviceAddress:Ljava/lang/String;
-Landroid/bluetooth/le/ScanFilter$Builder;->mDeviceName:Ljava/lang/String;
-Landroid/bluetooth/le/ScanFilter$Builder;->mManufacturerData:[B
-Landroid/bluetooth/le/ScanFilter$Builder;->mManufacturerDataMask:[B
-Landroid/bluetooth/le/ScanFilter$Builder;->mManufacturerId:I
-Landroid/bluetooth/le/ScanFilter$Builder;->mServiceData:[B
-Landroid/bluetooth/le/ScanFilter$Builder;->mServiceDataMask:[B
-Landroid/bluetooth/le/ScanFilter$Builder;->mServiceDataUuid:Landroid/os/ParcelUuid;
-Landroid/bluetooth/le/ScanFilter$Builder;->mServiceUuid:Landroid/os/ParcelUuid;
-Landroid/bluetooth/le/ScanFilter$Builder;->mUuidMask:Landroid/os/ParcelUuid;
-Landroid/bluetooth/le/ScanFilter;-><init>(Ljava/lang/String;Ljava/lang/String;Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;[B[BI[B[B)V
-Landroid/bluetooth/le/ScanFilter;->EMPTY:Landroid/bluetooth/le/ScanFilter;
-Landroid/bluetooth/le/ScanFilter;->isAllFieldsEmpty()Z
-Landroid/bluetooth/le/ScanFilter;->matchesPartialData([B[B[B)Z
-Landroid/bluetooth/le/ScanFilter;->matchesServiceUuid(Ljava/util/UUID;Ljava/util/UUID;Ljava/util/UUID;)Z
-Landroid/bluetooth/le/ScanFilter;->matchesServiceUuids(Landroid/os/ParcelUuid;Landroid/os/ParcelUuid;Ljava/util/List;)Z
-Landroid/bluetooth/le/ScanFilter;->mDeviceAddress:Ljava/lang/String;
-Landroid/bluetooth/le/ScanFilter;->mDeviceName:Ljava/lang/String;
-Landroid/bluetooth/le/ScanFilter;->mManufacturerData:[B
-Landroid/bluetooth/le/ScanFilter;->mManufacturerDataMask:[B
-Landroid/bluetooth/le/ScanFilter;->mManufacturerId:I
-Landroid/bluetooth/le/ScanFilter;->mServiceData:[B
-Landroid/bluetooth/le/ScanFilter;->mServiceDataMask:[B
-Landroid/bluetooth/le/ScanFilter;->mServiceDataUuid:Landroid/os/ParcelUuid;
-Landroid/bluetooth/le/ScanFilter;->mServiceUuid:Landroid/os/ParcelUuid;
-Landroid/bluetooth/le/ScanFilter;->mServiceUuidMask:Landroid/os/ParcelUuid;
-Landroid/bluetooth/le/ScanRecord;-><init>(Ljava/util/List;Landroid/util/SparseArray;Ljava/util/Map;IILjava/lang/String;[B)V
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_FLAGS:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_LOCAL_NAME_COMPLETE:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_LOCAL_NAME_SHORT:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_DATA_128_BIT:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_DATA_16_BIT:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_DATA_32_BIT:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:I
-Landroid/bluetooth/le/ScanRecord;->DATA_TYPE_TX_POWER_LEVEL:I
-Landroid/bluetooth/le/ScanRecord;->extractBytes([BII)[B
-Landroid/bluetooth/le/ScanRecord;->mAdvertiseFlags:I
-Landroid/bluetooth/le/ScanRecord;->mBytes:[B
-Landroid/bluetooth/le/ScanRecord;->mDeviceName:Ljava/lang/String;
-Landroid/bluetooth/le/ScanRecord;->mManufacturerSpecificData:Landroid/util/SparseArray;
-Landroid/bluetooth/le/ScanRecord;->mServiceData:Ljava/util/Map;
-Landroid/bluetooth/le/ScanRecord;->mServiceUuids:Ljava/util/List;
-Landroid/bluetooth/le/ScanRecord;->mTxPowerLevel:I
-Landroid/bluetooth/le/ScanRecord;->parseServiceUuid([BIIILjava/util/List;)I
-Landroid/bluetooth/le/ScanRecord;->TAG:Ljava/lang/String;
-Landroid/bluetooth/le/ScanResult;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/ScanResult;->ET_CONNECTABLE_MASK:I
-Landroid/bluetooth/le/ScanResult;->ET_LEGACY_MASK:I
-Landroid/bluetooth/le/ScanResult;->mAdvertisingSid:I
-Landroid/bluetooth/le/ScanResult;->mDevice:Landroid/bluetooth/BluetoothDevice;
-Landroid/bluetooth/le/ScanResult;->mEventType:I
-Landroid/bluetooth/le/ScanResult;->mPeriodicAdvertisingInterval:I
-Landroid/bluetooth/le/ScanResult;->mPrimaryPhy:I
-Landroid/bluetooth/le/ScanResult;->mRssi:I
-Landroid/bluetooth/le/ScanResult;->mScanRecord:Landroid/bluetooth/le/ScanRecord;
-Landroid/bluetooth/le/ScanResult;->mSecondaryPhy:I
-Landroid/bluetooth/le/ScanResult;->mTimestampNanos:J
-Landroid/bluetooth/le/ScanResult;->mTxPower:I
-Landroid/bluetooth/le/ScanResult;->readFromParcel(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/ScanSettings$Builder;->isValidCallbackType(I)Z
-Landroid/bluetooth/le/ScanSettings$Builder;->mCallbackType:I
-Landroid/bluetooth/le/ScanSettings$Builder;->mLegacy:Z
-Landroid/bluetooth/le/ScanSettings$Builder;->mMatchMode:I
-Landroid/bluetooth/le/ScanSettings$Builder;->mNumOfMatchesPerFilter:I
-Landroid/bluetooth/le/ScanSettings$Builder;->mPhy:I
-Landroid/bluetooth/le/ScanSettings$Builder;->mReportDelayMillis:J
-Landroid/bluetooth/le/ScanSettings$Builder;->mScanMode:I
-Landroid/bluetooth/le/ScanSettings$Builder;->mScanResultType:I
-Landroid/bluetooth/le/ScanSettings;-><init>(IIIJIIZI)V
-Landroid/bluetooth/le/ScanSettings;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/le/ScanSettings;->getMatchMode()I
-Landroid/bluetooth/le/ScanSettings;->getNumOfMatches()I
-Landroid/bluetooth/le/ScanSettings;->mCallbackType:I
-Landroid/bluetooth/le/ScanSettings;->mLegacy:Z
-Landroid/bluetooth/le/ScanSettings;->mMatchMode:I
-Landroid/bluetooth/le/ScanSettings;->mNumOfMatchesPerFilter:I
-Landroid/bluetooth/le/ScanSettings;->mPhy:I
-Landroid/bluetooth/le/ScanSettings;->mReportDelayMillis:J
-Landroid/bluetooth/le/ScanSettings;->mScanMode:I
-Landroid/bluetooth/le/ScanSettings;->mScanResultType:I
-Landroid/bluetooth/le/TruncatedFilter;->mFilter:Landroid/bluetooth/le/ScanFilter;
-Landroid/bluetooth/le/TruncatedFilter;->mStorageDescriptors:Ljava/util/List;
-Landroid/bluetooth/OobData;-><init>()V
-Landroid/bluetooth/OobData;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/OobData;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/OobData;->getLeBluetoothDeviceAddress()[B
-Landroid/bluetooth/OobData;->getLeSecureConnectionsConfirmation()[B
-Landroid/bluetooth/OobData;->getLeSecureConnectionsRandom()[B
-Landroid/bluetooth/OobData;->getSecurityManagerTk()[B
-Landroid/bluetooth/OobData;->mLeBluetoothDeviceAddress:[B
-Landroid/bluetooth/OobData;->mLeSecureConnectionsConfirmation:[B
-Landroid/bluetooth/OobData;->mLeSecureConnectionsRandom:[B
-Landroid/bluetooth/OobData;->mSecurityManagerTk:[B
-Landroid/bluetooth/OobData;->setLeBluetoothDeviceAddress([B)V
-Landroid/bluetooth/OobData;->setLeSecureConnectionsConfirmation([B)V
-Landroid/bluetooth/OobData;->setLeSecureConnectionsRandom([B)V
-Landroid/bluetooth/OobData;->setSecurityManagerTk([B)V
-Landroid/bluetooth/SdpMasRecord$MessageType;-><init>()V
-Landroid/bluetooth/SdpMasRecord$MessageType;->EMAIL:I
-Landroid/bluetooth/SdpMasRecord$MessageType;->MMS:I
-Landroid/bluetooth/SdpMasRecord$MessageType;->SMS_CDMA:I
-Landroid/bluetooth/SdpMasRecord$MessageType;->SMS_GSM:I
-Landroid/bluetooth/SdpMasRecord;-><init>(IIIIIILjava/lang/String;)V
-Landroid/bluetooth/SdpMasRecord;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/SdpMasRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/SdpMasRecord;->getL2capPsm()I
-Landroid/bluetooth/SdpMasRecord;->getMasInstanceId()I
-Landroid/bluetooth/SdpMasRecord;->getProfileVersion()I
-Landroid/bluetooth/SdpMasRecord;->getRfcommCannelNumber()I
-Landroid/bluetooth/SdpMasRecord;->getServiceName()Ljava/lang/String;
-Landroid/bluetooth/SdpMasRecord;->getSupportedFeatures()I
-Landroid/bluetooth/SdpMasRecord;->getSupportedMessageTypes()I
-Landroid/bluetooth/SdpMasRecord;->mL2capPsm:I
-Landroid/bluetooth/SdpMasRecord;->mMasInstanceId:I
-Landroid/bluetooth/SdpMasRecord;->mProfileVersion:I
-Landroid/bluetooth/SdpMasRecord;->mRfcommChannelNumber:I
-Landroid/bluetooth/SdpMasRecord;->mServiceName:Ljava/lang/String;
-Landroid/bluetooth/SdpMasRecord;->msgSupported(I)Z
-Landroid/bluetooth/SdpMasRecord;->mSupportedFeatures:I
-Landroid/bluetooth/SdpMasRecord;->mSupportedMessageTypes:I
-Landroid/bluetooth/SdpMnsRecord;-><init>(IIIILjava/lang/String;)V
-Landroid/bluetooth/SdpMnsRecord;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/SdpMnsRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/SdpMnsRecord;->getL2capPsm()I
-Landroid/bluetooth/SdpMnsRecord;->getProfileVersion()I
-Landroid/bluetooth/SdpMnsRecord;->getRfcommChannelNumber()I
-Landroid/bluetooth/SdpMnsRecord;->getServiceName()Ljava/lang/String;
-Landroid/bluetooth/SdpMnsRecord;->getSupportedFeatures()I
-Landroid/bluetooth/SdpMnsRecord;->mL2capPsm:I
-Landroid/bluetooth/SdpMnsRecord;->mProfileVersion:I
-Landroid/bluetooth/SdpMnsRecord;->mRfcommChannelNumber:I
-Landroid/bluetooth/SdpMnsRecord;->mServiceName:Ljava/lang/String;
-Landroid/bluetooth/SdpMnsRecord;->mSupportedFeatures:I
-Landroid/bluetooth/SdpOppOpsRecord;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/SdpOppOpsRecord;-><init>(Ljava/lang/String;III[B)V
-Landroid/bluetooth/SdpOppOpsRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/SdpOppOpsRecord;->getFormatsList()[B
-Landroid/bluetooth/SdpOppOpsRecord;->getL2capPsm()I
-Landroid/bluetooth/SdpOppOpsRecord;->getProfileVersion()I
-Landroid/bluetooth/SdpOppOpsRecord;->getRfcommChannel()I
-Landroid/bluetooth/SdpOppOpsRecord;->getServiceName()Ljava/lang/String;
-Landroid/bluetooth/SdpOppOpsRecord;->mFormatsList:[B
-Landroid/bluetooth/SdpOppOpsRecord;->mL2capPsm:I
-Landroid/bluetooth/SdpOppOpsRecord;->mProfileVersion:I
-Landroid/bluetooth/SdpOppOpsRecord;->mRfcommChannel:I
-Landroid/bluetooth/SdpOppOpsRecord;->mServiceName:Ljava/lang/String;
-Landroid/bluetooth/SdpPseRecord;-><init>(IIIIILjava/lang/String;)V
-Landroid/bluetooth/SdpPseRecord;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/SdpPseRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/SdpPseRecord;->getL2capPsm()I
-Landroid/bluetooth/SdpPseRecord;->getProfileVersion()I
-Landroid/bluetooth/SdpPseRecord;->getRfcommChannelNumber()I
-Landroid/bluetooth/SdpPseRecord;->getServiceName()Ljava/lang/String;
-Landroid/bluetooth/SdpPseRecord;->getSupportedFeatures()I
-Landroid/bluetooth/SdpPseRecord;->getSupportedRepositories()I
-Landroid/bluetooth/SdpPseRecord;->mL2capPsm:I
-Landroid/bluetooth/SdpPseRecord;->mProfileVersion:I
-Landroid/bluetooth/SdpPseRecord;->mRfcommChannelNumber:I
-Landroid/bluetooth/SdpPseRecord;->mServiceName:Ljava/lang/String;
-Landroid/bluetooth/SdpPseRecord;->mSupportedFeatures:I
-Landroid/bluetooth/SdpPseRecord;->mSupportedRepositories:I
-Landroid/bluetooth/SdpRecord;-><init>(I[B)V
-Landroid/bluetooth/SdpRecord;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/SdpRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/SdpRecord;->getRawData()[B
-Landroid/bluetooth/SdpRecord;->getRawSize()I
-Landroid/bluetooth/SdpRecord;->mRawData:[B
-Landroid/bluetooth/SdpRecord;->mRawSize:I
-Landroid/bluetooth/SdpSapsRecord;-><init>(IILjava/lang/String;)V
-Landroid/bluetooth/SdpSapsRecord;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/SdpSapsRecord;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/SdpSapsRecord;->getProfileVersion()I
-Landroid/bluetooth/SdpSapsRecord;->getRfcommCannelNumber()I
-Landroid/bluetooth/SdpSapsRecord;->getServiceName()Ljava/lang/String;
-Landroid/bluetooth/SdpSapsRecord;->mProfileVersion:I
-Landroid/bluetooth/SdpSapsRecord;->mRfcommChannelNumber:I
-Landroid/bluetooth/SdpSapsRecord;->mServiceName:Ljava/lang/String;
-Landroid/bluetooth/UidTraffic;-><init>(I)V
-Landroid/bluetooth/UidTraffic;-><init>(IJJ)V
-Landroid/bluetooth/UidTraffic;-><init>(Landroid/os/Parcel;)V
-Landroid/bluetooth/UidTraffic;->addRxBytes(J)V
-Landroid/bluetooth/UidTraffic;->addTxBytes(J)V
-Landroid/bluetooth/UidTraffic;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/bluetooth/UidTraffic;->getRxBytes()J
-Landroid/bluetooth/UidTraffic;->getTxBytes()J
-Landroid/bluetooth/UidTraffic;->getUid()I
-Landroid/bluetooth/UidTraffic;->mAppUid:I
-Landroid/bluetooth/UidTraffic;->mRxBytes:J
-Landroid/bluetooth/UidTraffic;->mTxBytes:J
-Landroid/bluetooth/UidTraffic;->setRxBytes(J)V
-Landroid/bluetooth/UidTraffic;->setTxBytes(J)V
 Landroid/companion/AssociationRequest$Builder;->mDeviceFilters:Ljava/util/ArrayList;
 Landroid/companion/AssociationRequest$Builder;->mSingleDevice:Z
 Landroid/companion/AssociationRequest;-><init>(Landroid/os/Parcel;)V
diff --git a/boot/hiddenapi/hiddenapi-max-target-p.txt b/boot/hiddenapi/hiddenapi-max-target-p.txt
index 351e71d..4a66a7c 100644
--- a/boot/hiddenapi/hiddenapi-max-target-p.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-p.txt
@@ -1,8 +1,6 @@
 Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher;
 Landroid/app/ISearchManager$Stub;-><init>()V
 Landroid/app/IUiModeManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IUiModeManager;
-Landroid/bluetooth/IBluetooth$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothA2dp$Stub;-><init>()V
 Landroid/content/IIntentReceiver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentReceiver;
 Landroid/content/IIntentSender$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IIntentSender;
 Landroid/os/storage/IObbActionListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IObbActionListener;
diff --git a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt
index 20d7cc0..dbc3b51 100644
--- a/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-r-loprio.txt
@@ -3,9 +3,6 @@
 Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
 Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
 Landroid/app/INotificationManager$Stub;->TRANSACTION_enqueueNotificationWithTag:I
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
-Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_enable:I
-Landroid/bluetooth/IBluetoothManager$Stub;->TRANSACTION_enable:I
 Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
 Landroid/content/om/IOverlayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/om/IOverlayManager;
 Landroid/content/pm/IPackageManager$Stub;->TRANSACTION_getApplicationInfo:I
diff --git a/boot/hiddenapi/hiddenapi-unsupported.txt b/boot/hiddenapi/hiddenapi-unsupported.txt
index 033afb6..f619913 100644
--- a/boot/hiddenapi/hiddenapi-unsupported.txt
+++ b/boot/hiddenapi/hiddenapi-unsupported.txt
@@ -62,19 +62,6 @@
 Landroid/app/job/IJobService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/job/IJobService;
 Landroid/app/trust/ITrustManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/app/usage/IUsageStatsManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/usage/IUsageStatsManager;
-Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAddress()Ljava/lang/String;
-Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth;
-Landroid/bluetooth/IBluetoothA2dp$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dp;
-Landroid/bluetooth/IBluetoothCallback$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothGattCallback$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothGattCallback$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothGattCallback;
-Landroid/bluetooth/IBluetoothHeadset$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothHeadset;
-Landroid/bluetooth/IBluetoothHidDeviceCallback$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/bluetooth/IBluetoothManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothManager;
-Landroid/bluetooth/IBluetoothManagerCallback$Stub;-><init>()V
-Landroid/bluetooth/IBluetoothPbap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPbap;
-Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;-><init>()V
 Landroid/content/IClipboard$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
 Landroid/content/IContentService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 1f4a64f..f9317eb 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -764,6 +764,7 @@
     // We have no bootanimation file, so we use the stock android logo
     // animation.
     if (mZipFileName.isEmpty()) {
+        ALOGD("No animation file");
         result = android();
     } else {
         result = movie();
@@ -1476,6 +1477,10 @@
                     part.backgroundColor[2],
                     1.0f);
 
+            ALOGD("Playing files = %s/%s, Requested repeat = %d, playUntilComplete = %s",
+                    animation.fileName.string(), part.path.string(), part.count,
+                    part.playUntilComplete ? "true" : "false");
+
             // For the last animation, if we have progress indicator from
             // the system, display it.
             int currentProgress = android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);
@@ -1609,6 +1614,9 @@
         }
     }
 
+    ALOGD("%sAnimationShownTiming End time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
+            elapsedRealtime());
+
     return true;
 }
 
@@ -1684,6 +1692,8 @@
         return nullptr;
     }
 
+    ALOGD("%s is loaded successfully", fn.string());
+
     Animation *animation =  new Animation;
     animation->fileName = fn;
     animation->zip = zip;
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 9c6402a..738b9cf 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -37,7 +37,6 @@
 #include "idmap2/Idmap.h"
 #include "idmap2/LogInfo.h"
 
-using android::Res_value;
 using ::testing::NotNull;
 
 using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 5a1d808..32b3d13 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -29,8 +29,6 @@
 #include "idmap2/LogInfo.h"
 #include "idmap2/ResourceMapping.h"
 
-using android::Res_value;
-
 using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
 
 namespace android::idmap2 {
diff --git a/cmds/incidentd/src/incidentd_util.cpp b/cmds/incidentd/src/incidentd_util.cpp
index 150ab99..ec0b79b 100644
--- a/cmds/incidentd/src/incidentd_util.cpp
+++ b/cmds/incidentd/src/incidentd_util.cpp
@@ -184,11 +184,26 @@
     sigemptyset(&child_mask);
     sigaddset(&child_mask, SIGCHLD);
 
+    // block SIGCHLD before we check if a process has exited
     if (sigprocmask(SIG_BLOCK, &child_mask, &old_mask) == -1) {
-        ALOGW("sigprocmask failed: %s", strerror(errno));
+        ALOGW("*** sigprocmask failed: %s\n", strerror(errno));
         return false;
     }
 
+    // if the child has exited already, handle and reset signals before leaving
+    pid_t child_pid = waitpid(pid, status, WNOHANG);
+    if (child_pid != pid) {
+        if (child_pid > 0) {
+            ALOGW("*** Waiting for pid %d, got pid %d instead\n", pid, child_pid);
+            sigprocmask(SIG_SETMASK, &old_mask, nullptr);
+            return false;
+        }
+    } else {
+        sigprocmask(SIG_SETMASK, &old_mask, nullptr);
+        return true;
+    }
+
+    // wait for a SIGCHLD
     timespec ts;
     ts.tv_sec = timeout_ms / 1000;
     ts.tv_nsec = (timeout_ms % 1000) * 1000000;
@@ -197,7 +212,7 @@
 
     // Set the signals back the way they were.
     if (sigprocmask(SIG_SETMASK, &old_mask, nullptr) == -1) {
-        ALOGW("sigprocmask failed: %s", strerror(errno));
+        ALOGW("*** sigprocmask failed: %s\n", strerror(errno));
         if (ret == 0) {
             return false;
         }
@@ -207,21 +222,21 @@
         if (errno == EAGAIN) {
             errno = ETIMEDOUT;
         } else {
-            ALOGW("sigtimedwait failed: %s", strerror(errno));
+            ALOGW("*** sigtimedwait failed: %s\n", strerror(errno));
         }
         return false;
     }
 
-    pid_t child_pid = waitpid(pid, status, WNOHANG);
-    if (child_pid == pid) {
-        return true;
+    child_pid = waitpid(pid, status, WNOHANG);
+    if (child_pid != pid) {
+        if (child_pid != -1) {
+            ALOGW("*** Waiting for pid %d, got pid %d instead\n", pid, child_pid);
+        } else {
+            ALOGW("*** waitpid failed: %s\n", strerror(errno));
+        }
+        return false;
     }
-    if (child_pid == -1) {
-        ALOGW("waitpid failed: %s", strerror(errno));
-    } else {
-        ALOGW("Waiting for pid %d, got pid %d instead", pid, child_pid);
-    }
-    return false;
+    return true;
 }
 
 status_t kill_child(pid_t pid) {
diff --git a/cmds/svc/src/com/android/commands/svc/BluetoothCommand.java b/cmds/svc/src/com/android/commands/svc/BluetoothCommand.java
deleted file mode 100644
index b572ce2..0000000
--- a/cmds/svc/src/com/android/commands/svc/BluetoothCommand.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.commands.svc;
-
-import android.bluetooth.BluetoothAdapter;
-import android.os.RemoteException;
-
-public class BluetoothCommand extends Svc.Command {
-
-    public BluetoothCommand() {
-        super("bluetooth");
-    }
-
-    @Override
-    public String shortHelp() {
-        return "Control Bluetooth service";
-    }
-
-    @Override
-    public String longHelp() {
-        return shortHelp() + "\n"
-                + "\n"
-                + "usage: svc bluetooth [enable|disable]\n"
-                + "         Turn Bluetooth on or off.\n\n";
-    }
-
-    @Override
-    public void run(String[] args) {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-
-        if (adapter == null) {
-            System.err.println("Got a null BluetoothAdapter, is the system running?");
-            return;
-        }
-
-        if (args.length == 2 && "enable".equals(args[1])) {
-            adapter.enable();
-        } else if (args.length == 2 && "disable".equals(args[1])) {
-            adapter.disable();
-        } else {
-            System.err.println(longHelp());
-        }
-    }
-}
diff --git a/cmds/svc/src/com/android/commands/svc/Svc.java b/cmds/svc/src/com/android/commands/svc/Svc.java
index 2ed2678..bbad984 100644
--- a/cmds/svc/src/com/android/commands/svc/Svc.java
+++ b/cmds/svc/src/com/android/commands/svc/Svc.java
@@ -96,7 +96,7 @@
             // `svc wifi` has been migrated to WifiShellCommand
             new UsbCommand(),
             new NfcCommand(),
-            new BluetoothCommand(),
+            // `svc bluetooth` has been migrated to BluetoothShellCommand
             new SystemServerCommand(),
     };
 }
diff --git a/cmds/svc/svc b/cmds/svc/svc
index 95265e8..a2c9de3 100755
--- a/cmds/svc/svc
+++ b/cmds/svc/svc
@@ -33,6 +33,25 @@
     exit 1
 fi
 
+# `svc bluetooth` has been migrated to BluetoothShellCommand,
+# simply perform translation to `cmd bluetooth set-bluetooth-enabled` here.
+if [ "x$1" == "xbluetooth" ]; then
+    # `cmd wifi` by convention uses enabled/disabled
+    # instead of enable/disable
+    if [ "x$2" == "xenable" ]; then
+        exec cmd bluetooth_manager enable
+    elif [ "x$2" == "xdisable" ]; then
+        exec cmd bluetooth_manager disable
+    else
+        echo "Control the Bluetooth manager"
+        echo ""
+        echo "usage: svc bluetooth [enable|disable]"
+        echo "         Turn Bluetooth on or off."
+        echo ""
+    fi
+    exit 1
+fi
+
 export CLASSPATH=/system/framework/svc.jar
 exec app_process /system/bin com.android.commands.svc.Svc "$@"
 
diff --git a/core/api/current.txt b/core/api/current.txt
index 3a6fc59..ec87591 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";
@@ -189,6 +191,7 @@
     field public static final String START_VIEW_APP_FEATURES = "android.permission.START_VIEW_APP_FEATURES";
     field public static final String START_VIEW_PERMISSION_USAGE = "android.permission.START_VIEW_PERMISSION_USAGE";
     field public static final String STATUS_BAR = "android.permission.STATUS_BAR";
+    field public static final String SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE = "android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE";
     field public static final String SYSTEM_ALERT_WINDOW = "android.permission.SYSTEM_ALERT_WINDOW";
     field public static final String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
     field public static final String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
@@ -978,8 +981,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
@@ -2093,12 +2096,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
@@ -3247,7 +3246,7 @@
     method public int getNonInteractiveUiTimeoutMillis();
     method public android.content.pm.ResolveInfo getResolveInfo();
     method public String getSettingsActivityName();
-    method @Nullable public String getTileServiceClassName();
+    method @Nullable public String getTileServiceName();
     method public boolean isAccessibilityTool();
     method public String loadDescription(android.content.pm.PackageManager);
     method @Nullable public CharSequence loadIntro(@NonNull android.content.pm.PackageManager);
@@ -4072,7 +4071,7 @@
     method @Deprecated public void onTabUnselected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
   }
 
-  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
     ctor public Activity();
     method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void closeContextMenu();
@@ -4115,7 +4114,7 @@
     method public int getMaxNumPictureInPictureActions();
     method public final android.media.session.MediaController getMediaController();
     method @NonNull public android.view.MenuInflater getMenuInflater();
-    method @NonNull public android.view.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
+    method @NonNull public android.window.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
     method public final android.app.Activity getParent();
     method @Nullable public android.content.Intent getParentActivityIntent();
     method public android.content.SharedPreferences getPreferences(int);
@@ -5001,7 +5000,7 @@
     method public void onDateSet(android.widget.DatePicker, int, int, int);
   }
 
-  public class Dialog implements android.content.DialogInterface android.view.KeyEvent.Callback android.view.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+  public class Dialog implements android.content.DialogInterface android.view.KeyEvent.Callback android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
     ctor public Dialog(@NonNull @UiContext android.content.Context);
     ctor public Dialog(@NonNull @UiContext android.content.Context, @StyleRes int);
     ctor protected Dialog(@NonNull @UiContext android.content.Context, boolean, @Nullable android.content.DialogInterface.OnCancelListener);
@@ -5021,7 +5020,7 @@
     method @NonNull @UiContext public final android.content.Context getContext();
     method @Nullable public android.view.View getCurrentFocus();
     method @NonNull public android.view.LayoutInflater getLayoutInflater();
-    method @NonNull public android.view.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
+    method @NonNull public android.window.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
     method @Nullable public final android.app.Activity getOwnerActivity();
     method @Nullable public final android.view.SearchEvent getSearchEvent();
     method public final int getVolumeControlStream();
@@ -5559,11 +5558,11 @@
 
   public final class GameState implements android.os.Parcelable {
     ctor public GameState(boolean, int);
-    ctor public GameState(boolean, int, @Nullable String, @NonNull android.os.Bundle);
+    ctor public GameState(boolean, int, int, int);
     method public int describeContents();
-    method @Nullable public String getDescription();
-    method @NonNull public android.os.Bundle getMetadata();
+    method public int getLabel();
     method public int getMode();
+    method public int getQuality();
     method public boolean isLoading();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.GameState> CREATOR;
@@ -5677,6 +5676,7 @@
   }
 
   public class KeyguardManager {
+    method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void addKeyguardLockedStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.KeyguardManager.KeyguardLockedStateListener);
     method @Deprecated public android.content.Intent createConfirmDeviceCredentialIntent(CharSequence, CharSequence);
     method @Deprecated @RequiresPermission(android.Manifest.permission.DISABLE_KEYGUARD) public void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult);
     method @Deprecated public boolean inKeyguardRestrictedInputMode();
@@ -5685,6 +5685,7 @@
     method public boolean isKeyguardLocked();
     method public boolean isKeyguardSecure();
     method @Deprecated public android.app.KeyguardManager.KeyguardLock newKeyguardLock(String);
+    method @RequiresPermission(android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE) public void removeKeyguardLockedStateListener(@NonNull android.app.KeyguardManager.KeyguardLockedStateListener);
     method public void requestDismissKeyguard(@NonNull android.app.Activity, @Nullable android.app.KeyguardManager.KeyguardDismissCallback);
   }
 
@@ -5700,6 +5701,10 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.DISABLE_KEYGUARD) public void reenableKeyguard();
   }
 
+  @java.lang.FunctionalInterface public static interface KeyguardManager.KeyguardLockedStateListener {
+    method public void onKeyguardLockedStateChanged(boolean);
+  }
+
   @Deprecated public static interface KeyguardManager.OnKeyguardExitResult {
     method @Deprecated public void onKeyguardExitResult(boolean);
   }
@@ -7381,14 +7386,14 @@
     method public int getCurrentFailedPasswordAttempts();
     method @Nullable public java.util.List<java.lang.String> getDelegatePackages(@NonNull android.content.ComponentName, @NonNull String);
     method @NonNull public java.util.List<java.lang.String> getDelegatedScopes(@Nullable android.content.ComponentName, @NonNull String);
-    method @Nullable public String getDeviceManagerRoleHolderPackageName();
     method public CharSequence getDeviceOwnerLockScreenInfo();
-    method @Nullable public android.graphics.drawable.Drawable getDrawable(@NonNull String, @NonNull String, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
-    method @Nullable public android.graphics.drawable.Drawable getDrawable(@NonNull String, @NonNull String, @NonNull String, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
+    method @Nullable public String getDevicePolicyManagementRoleHolderPackage();
+    method @Nullable public android.graphics.drawable.Drawable getDrawable(@NonNull String, @NonNull String, @NonNull java.util.function.Supplier<android.graphics.drawable.Drawable>);
+    method @Nullable public android.graphics.drawable.Drawable getDrawable(@NonNull String, @NonNull String, @NonNull String, @NonNull java.util.function.Supplier<android.graphics.drawable.Drawable>);
     method @Nullable public android.graphics.drawable.Icon getDrawableAsIcon(@NonNull String, @NonNull String, @NonNull String, @Nullable android.graphics.drawable.Icon);
     method @Nullable public android.graphics.drawable.Icon getDrawableAsIcon(@NonNull String, @NonNull String, @Nullable android.graphics.drawable.Icon);
-    method @Nullable public android.graphics.drawable.Drawable getDrawableForDensity(@NonNull String, @NonNull String, int, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
-    method @Nullable public android.graphics.drawable.Drawable getDrawableForDensity(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.concurrent.Callable<android.graphics.drawable.Drawable>);
+    method @Nullable public android.graphics.drawable.Drawable getDrawableForDensity(@NonNull String, @NonNull String, int, @NonNull java.util.function.Supplier<android.graphics.drawable.Drawable>);
+    method @Nullable public android.graphics.drawable.Drawable getDrawableForDensity(@NonNull String, @NonNull String, @NonNull String, int, @NonNull java.util.function.Supplier<android.graphics.drawable.Drawable>);
     method public CharSequence getEndUserSessionMessage(@NonNull android.content.ComponentName);
     method @NonNull public String getEnrollmentSpecificId();
     method @Nullable public android.app.admin.FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(@Nullable android.content.ComponentName);
@@ -7432,7 +7437,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);
@@ -7577,7 +7582,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);
@@ -7697,9 +7702,10 @@
     field public static final String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
     field public static final String EXTRA_PROVISIONING_WIFI_SSID = "android.app.extra.PROVISIONING_WIFI_SSID";
     field public static final String EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE = "android.app.extra.PROVISIONING_WIFI_USER_CERTIFICATE";
-    field public static final String EXTRA_RESOURCE_ID = "android.app.extra.RESOURCE_ID";
-    field public static final String EXTRA_RESOURCE_TYPE_DRAWABLE = "android.app.extra.RESOURCE_TYPE_DRAWABLE";
-    field public static final String EXTRA_RESOURCE_TYPE_STRING = "android.app.extra.RESOURCE_TYPE_STRING";
+    field public static final String EXTRA_RESOURCE_IDS = "android.app.extra.RESOURCE_IDS";
+    field public static final String EXTRA_RESOURCE_TYPE = "android.app.extra.RESOURCE_TYPE";
+    field public static final int EXTRA_RESOURCE_TYPE_DRAWABLE = 1; // 0x1
+    field public static final int EXTRA_RESOURCE_TYPE_STRING = 2; // 0x2
     field public static final String EXTRA_RESULT_LAUNCH_INTENT = "android.app.extra.RESULT_LAUNCH_INTENT";
     field public static final int FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY = 1; // 0x1
     field public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 2; // 0x2
@@ -10321,7 +10327,6 @@
     field public static final String ACTION_VIEW_LOCUS = "android.intent.action.VIEW_LOCUS";
     field @RequiresPermission(android.Manifest.permission.START_VIEW_PERMISSION_USAGE) public static final String ACTION_VIEW_PERMISSION_USAGE = "android.intent.action.VIEW_PERMISSION_USAGE";
     field @RequiresPermission(android.Manifest.permission.START_VIEW_PERMISSION_USAGE) public static final String ACTION_VIEW_PERMISSION_USAGE_FOR_PERIOD = "android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD";
-    field @RequiresPermission("android.permission.MANAGE_SENSOR_PRIVACY") public static final String ACTION_VIEW_SAFETY_HUB = "android.intent.action.VIEW_SAFETY_HUB";
     field public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
     field @Deprecated public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
     field public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
@@ -17391,7 +17396,7 @@
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_MAX_NUM_OUTPUT_RAW;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_PARTIAL_RESULT_COUNT;
     field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Byte> REQUEST_PIPELINE_MAX_DEPTH;
-    field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE;
+    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;
@@ -18111,22 +18116,23 @@
   }
 
   public final class DynamicRangeProfiles {
-    ctor public DynamicRangeProfiles(@NonNull int[]);
-    method @NonNull public java.util.Set<java.lang.Integer> getProfileCaptureRequestConstraints(int);
-    method @NonNull public java.util.Set<java.lang.Integer> getSupportedProfiles();
-    field public static final int DOLBY_VISION_10B_HDR_OEM = 64; // 0x40
-    field public static final int DOLBY_VISION_10B_HDR_OEM_PO = 128; // 0x80
-    field public static final int DOLBY_VISION_10B_HDR_REF = 16; // 0x10
-    field public static final int DOLBY_VISION_10B_HDR_REF_PO = 32; // 0x20
-    field public static final int DOLBY_VISION_8B_HDR_OEM = 1024; // 0x400
-    field public static final int DOLBY_VISION_8B_HDR_OEM_PO = 2048; // 0x800
-    field public static final int DOLBY_VISION_8B_HDR_REF = 256; // 0x100
-    field public static final int DOLBY_VISION_8B_HDR_REF_PO = 512; // 0x200
-    field public static final int HDR10 = 4; // 0x4
-    field public static final int HDR10_PLUS = 8; // 0x8
-    field public static final int HLG10 = 2; // 0x2
-    field public static final int PUBLIC_MAX = 4096; // 0x1000
-    field public static final int STANDARD = 1; // 0x1
+    ctor public DynamicRangeProfiles(@NonNull long[]);
+    method @NonNull public java.util.Set<java.lang.Long> getProfileCaptureRequestConstraints(long);
+    method @NonNull public java.util.Set<java.lang.Long> getSupportedProfiles();
+    method public boolean isExtraLatencyPresent(long);
+    field public static final long DOLBY_VISION_10B_HDR_OEM = 64L; // 0x40L
+    field public static final long DOLBY_VISION_10B_HDR_OEM_PO = 128L; // 0x80L
+    field public static final long DOLBY_VISION_10B_HDR_REF = 16L; // 0x10L
+    field public static final long DOLBY_VISION_10B_HDR_REF_PO = 32L; // 0x20L
+    field public static final long DOLBY_VISION_8B_HDR_OEM = 1024L; // 0x400L
+    field public static final long DOLBY_VISION_8B_HDR_OEM_PO = 2048L; // 0x800L
+    field public static final long DOLBY_VISION_8B_HDR_REF = 256L; // 0x100L
+    field public static final long DOLBY_VISION_8B_HDR_REF_PO = 512L; // 0x200L
+    field public static final long HDR10 = 4L; // 0x4L
+    field public static final long HDR10_PLUS = 8L; // 0x8L
+    field public static final long HLG10 = 2L; // 0x2L
+    field public static final long PUBLIC_MAX = 4096L; // 0x1000L
+    field public static final long STANDARD = 1L; // 0x1L
   }
 
   public final class ExtensionSessionConfiguration {
@@ -18233,7 +18239,7 @@
     method @NonNull public static java.util.Collection<android.hardware.camera2.params.OutputConfiguration> createInstancesForMultiResolutionOutput(@NonNull android.hardware.camera2.MultiResolutionImageReader);
     method public int describeContents();
     method public void enableSurfaceSharing();
-    method public int getDynamicRangeProfile();
+    method public long getDynamicRangeProfile();
     method public int getMaxSharedSurfaceCount();
     method public int getMirrorMode();
     method public int getStreamUseCase();
@@ -18243,7 +18249,7 @@
     method public int getTimestampBase();
     method public void removeSensorPixelModeUsed(int);
     method public void removeSurface(@NonNull android.view.Surface);
-    method public void setDynamicRangeProfile(int);
+    method public void setDynamicRangeProfile(long);
     method public void setMirrorMode(int);
     method public void setPhysicalCameraId(@Nullable String);
     method public void setStreamUseCase(int);
@@ -26613,9 +26619,9 @@
 
   public abstract class PlatformVpnProfile {
     method public final boolean areLocalRoutesExcluded();
-    method public final boolean getRequiresInternetValidation();
     method public final int getType();
     method @NonNull public final String getTypeString();
+    method public final boolean isInternetValidationRequired();
     field public static final int TYPE_IKEV2_IPSEC_PSK = 7; // 0x7
     field public static final int TYPE_IKEV2_IPSEC_RSA = 8; // 0x8
     field public static final int TYPE_IKEV2_IPSEC_USER_PASS = 6; // 0x6
@@ -26822,7 +26828,7 @@
     field public static final String EXTRA_ERROR_CLASS = "android.net.extra.ERROR_CLASS";
     field public static final String EXTRA_ERROR_CODE = "android.net.extra.ERROR_CODE";
     field public static final String EXTRA_SESSION_KEY = "android.net.extra.SESSION_KEY";
-    field public static final String EXTRA_TIMESTAMP = "android.net.extra.TIMESTAMP";
+    field public static final String EXTRA_TIMESTAMP_MILLIS = "android.net.extra.TIMESTAMP_MILLIS";
     field public static final String EXTRA_UNDERLYING_LINK_PROPERTIES = "android.net.extra.UNDERLYING_LINK_PROPERTIES";
     field public static final String EXTRA_UNDERLYING_NETWORK = "android.net.extra.UNDERLYING_NETWORK";
     field public static final String EXTRA_UNDERLYING_NETWORK_CAPABILITIES = "android.net.extra.UNDERLYING_NETWORK_CAPABILITIES";
@@ -30859,6 +30865,7 @@
     field public static final int PREVIEW_SDK_INT;
     field public static final String RELEASE;
     field @NonNull public static final String RELEASE_OR_CODENAME;
+    field @NonNull public static final String RELEASE_OR_PREVIEW_DISPLAY;
     field @Deprecated public static final String SDK;
     field public static final int SDK_INT;
     field public static final String SECURITY_PATCH;
@@ -30933,7 +30940,7 @@
     method @Deprecated @Nullable public android.os.Parcelable[] getParcelableArray(@Nullable String);
     method @Nullable public <T> T[] getParcelableArray(@Nullable String, @NonNull Class<T>);
     method @Deprecated @Nullable public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayList(@Nullable String);
-    method @Nullable public <T> java.util.ArrayList<T> getParcelableArrayList(@Nullable String, @NonNull Class<T>);
+    method @Nullable public <T> java.util.ArrayList<T> getParcelableArrayList(@Nullable String, @NonNull Class<? extends T>);
     method @Deprecated @Nullable public java.io.Serializable getSerializable(@Nullable String);
     method @Nullable public <T extends java.io.Serializable> T getSerializable(@Nullable String, @NonNull Class<T>);
     method public short getShort(String);
@@ -30942,7 +30949,7 @@
     method @Nullable public android.util.Size getSize(@Nullable String);
     method @Nullable public android.util.SizeF getSizeF(@Nullable String);
     method @Deprecated @Nullable public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String);
-    method @Nullable public <T> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String, @NonNull Class<T>);
+    method @Nullable public <T> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String, @NonNull Class<? extends T>);
     method @Nullable public java.util.ArrayList<java.lang.String> getStringArrayList(@Nullable String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
@@ -31567,7 +31574,7 @@
     method @Deprecated @Nullable public android.os.Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader);
     method @Nullable public <T> android.os.Parcelable.Creator<T> readParcelableCreator(@Nullable ClassLoader, @NonNull Class<T>);
     method @Deprecated @NonNull public <T extends android.os.Parcelable> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader);
-    method @NonNull public <T> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader, @NonNull Class<T>);
+    method @NonNull public <T> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader, @NonNull Class<? extends T>);
     method @Nullable public android.os.PersistableBundle readPersistableBundle();
     method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
     method @Deprecated @Nullable public java.io.Serializable readSerializable();
@@ -31791,7 +31798,7 @@
     method public android.os.PowerManager.WakeLock newWakeLock(int, String);
     method @RequiresPermission(android.Manifest.permission.REBOOT) public void reboot(@Nullable String);
     method public void removeThermalStatusListener(@NonNull android.os.PowerManager.OnThermalStatusChangedListener);
-    field public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
+    field @Deprecated public static final int ACQUIRE_CAUSES_WAKEUP = 268435456; // 0x10000000
     field public static final String ACTION_DEVICE_IDLE_MODE_CHANGED = "android.os.action.DEVICE_IDLE_MODE_CHANGED";
     field public static final String ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED = "android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED";
     field public static final String ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED = "android.os.action.LOW_POWER_STANDBY_ENABLED_CHANGED";
@@ -31850,7 +31857,7 @@
     method public static final boolean is64Bit();
     method public static boolean isApplicationUid(int);
     method public static final boolean isIsolated();
-    method public static final boolean isSupplemental();
+    method public static final boolean isSdkSandbox();
     method public static final void killProcess(int);
     method public static final int myPid();
     method @NonNull public static String myProcessName();
@@ -35442,8 +35449,8 @@
     field public static final String EXTRA_WIFI_NETWORK_RESULT_LIST = "android.provider.extra.WIFI_NETWORK_RESULT_LIST";
     field public static final String INTENT_CATEGORY_USAGE_ACCESS_CONFIG = "android.intent.category.USAGE_ACCESS_CONFIG";
     field public static final String METADATA_USAGE_ACCESS_REASON = "android.settings.metadata.USAGE_ACCESS_REASON";
-    field public static final String SUPERVISOR_VERIFICATION_SETTING_BIOMETRICS = "supervisor_restricted_biometrics_controller";
-    field public static final String SUPERVISOR_VERIFICATION_SETTING_UNKNOWN = "";
+    field public static final int SUPERVISOR_VERIFICATION_SETTING_BIOMETRICS = 1; // 0x1
+    field public static final int SUPERVISOR_VERIFICATION_SETTING_UNKNOWN = 0; // 0x0
   }
 
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
@@ -38072,6 +38079,7 @@
   }
 
   public final class Field {
+    method @Nullable public java.util.regex.Pattern getFilter();
     method @Nullable public android.service.autofill.Presentations getPresentations();
     method @Nullable public android.view.autofill.AutofillValue getValue();
   }
@@ -40012,7 +40020,6 @@
     field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 2048; // 0x800
     field public static final int PROPERTY_RTT = 1024; // 0x400
     field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100
-    field public static final int PROPERTY_TETHERED_CALL = 32768; // 0x8000
     field public static final int PROPERTY_VOIP_AUDIO_MODE = 4096; // 0x1000
     field public static final int PROPERTY_WIFI = 8; // 0x8
   }
@@ -40041,7 +40048,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telecom.CallAudioState> CREATOR;
     field public static final int ROUTE_BLUETOOTH = 2; // 0x2
     field public static final int ROUTE_EARPIECE = 1; // 0x1
-    field public static final int ROUTE_EXTERNAL = 16; // 0x10
     field public static final int ROUTE_SPEAKER = 8; // 0x8
     field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4
     field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
@@ -40316,7 +40322,6 @@
     field public static final int PROPERTY_IS_RTT = 256; // 0x100
     field public static final int PROPERTY_NETWORK_IDENTIFIED_EMERGENCY_CALL = 1024; // 0x400
     field public static final int PROPERTY_SELF_MANAGED = 128; // 0x80
-    field public static final int PROPERTY_TETHERED_CALL = 16384; // 0x4000
     field public static final int PROPERTY_WIFI = 8; // 0x8
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_DIALING = 3; // 0x3
@@ -40745,8 +40750,9 @@
     method public String getDefaultDialerPackage();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telecom.PhoneAccountHandle getDefaultOutgoingPhoneAccount(String);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.READ_SMS, android.Manifest.permission.READ_PHONE_NUMBERS}, conditional=true) public String getLine1Number(android.telecom.PhoneAccountHandle);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_OWN_CALLS) public java.util.List<android.telecom.PhoneAccountHandle> getOwnSelfManagedPhoneAccounts();
     method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle);
-    method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.MANAGE_OWN_CALLS}) public java.util.List<android.telecom.PhoneAccountHandle> getSelfManagedPhoneAccounts();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telecom.PhoneAccountHandle> getSelfManagedPhoneAccounts();
     method public android.telecom.PhoneAccountHandle getSimCallManager();
     method @Nullable public android.telecom.PhoneAccountHandle getSimCallManagerForSubscription(int);
     method @Nullable public String getSystemDialerPackage();
@@ -49021,21 +49027,6 @@
     field public int toolType;
   }
 
-  public interface OnBackInvokedCallback {
-    method public default void onBackInvoked();
-  }
-
-  public interface OnBackInvokedDispatcher {
-    method public void registerOnBackInvokedCallback(@NonNull android.view.OnBackInvokedCallback, @IntRange(from=0) int);
-    method public void unregisterOnBackInvokedCallback(@NonNull android.view.OnBackInvokedCallback);
-    field public static final int PRIORITY_DEFAULT = 0; // 0x0
-    field public static final int PRIORITY_OVERLAY = 1000000; // 0xf4240
-  }
-
-  public interface OnBackInvokedDispatcherOwner {
-    method @NonNull public android.view.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
-  }
-
   public interface OnReceiveContentListener {
     method @Nullable public android.view.ContentInfo onReceiveContent(@NonNull android.view.View, @NonNull android.view.ContentInfo);
   }
@@ -51938,12 +51929,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;
   }
 
@@ -52955,6 +52942,7 @@
     method public default boolean performSpellCheck();
     method public boolean reportFullscreenMode(boolean);
     method public boolean requestCursorUpdates(int);
+    method public default boolean requestCursorUpdates(int, int);
     method public boolean sendKeyEvent(android.view.KeyEvent);
     method public boolean setComposingRegion(int, int);
     method public default boolean setComposingRegion(int, int, @Nullable android.view.inputmethod.TextAttribute);
@@ -53112,7 +53100,7 @@
     field public static final int RESULT_SHOWN = 2; // 0x2
     field public static final int RESULT_UNCHANGED_HIDDEN = 1; // 0x1
     field public static final int RESULT_UNCHANGED_SHOWN = 0; // 0x0
-    field public static final int SHOW_FORCED = 2; // 0x2
+    field @Deprecated public static final int SHOW_FORCED = 2; // 0x2
     field public static final int SHOW_IMPLICIT = 1; // 0x1
   }
 
@@ -57897,12 +57885,27 @@
 
 package android.window {
 
+  public interface OnBackInvokedCallback {
+    method public default void onBackInvoked();
+  }
+
+  public interface OnBackInvokedDispatcher {
+    method public void registerOnBackInvokedCallback(@NonNull android.window.OnBackInvokedCallback, @IntRange(from=0) int);
+    method public void unregisterOnBackInvokedCallback(@NonNull android.window.OnBackInvokedCallback);
+    field public static final int PRIORITY_DEFAULT = 0; // 0x0
+    field public static final int PRIORITY_OVERLAY = 1000000; // 0xf4240
+  }
+
+  public interface OnBackInvokedDispatcherOwner {
+    method @NonNull public android.window.OnBackInvokedDispatcher getOnBackInvokedDispatcher();
+  }
+
   public interface SplashScreen {
     method public void clearOnExitAnimationListener();
     method public void setOnExitAnimationListener(@NonNull android.window.SplashScreen.OnExitAnimationListener);
     method public void setSplashScreenTheme(@StyleRes int);
-    field public static final int SPLASH_SCREEN_STYLE_EMPTY = 0; // 0x0
     field public static final int SPLASH_SCREEN_STYLE_ICON = 1; // 0x1
+    field public static final int SPLASH_SCREEN_STYLE_SOLID_COLOR = 0; // 0x0
   }
 
   public static interface SplashScreen.OnExitAnimationListener {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 594f46b..241e5c8 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -10,7 +10,7 @@
 
 package android.app {
 
-  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
     method public final boolean addDumpable(@NonNull android.util.Dumpable);
   }
 
@@ -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,21 +50,6 @@
     method public void onCanceled(@NonNull android.app.PendingIntent);
   }
 
-  public class PropertyInvalidatedCache<Query, Result> {
-    ctor public PropertyInvalidatedCache(int, int, @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(int, @NonNull String);
-    method @Nullable public final Result query(@NonNull Query);
-    field public static final int MODULE_BLUETOOTH = 2; // 0x2
-  }
-
-  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);
   }
@@ -120,7 +101,7 @@
 
   public abstract class PackageManager {
     method @NonNull public String getPermissionControllerPackageName();
-    method @NonNull public String getSupplementalProcessPackageName();
+    method @NonNull public String getSdkSandboxPackageName();
     field public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 67108864; // 0x4000000
   }
 
@@ -357,14 +338,30 @@
     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 boolean isSupplemental(int);
-    method public static final int toAppUid(int);
-    method public static final int toSupplementalUid(int);
+    method public static final int getAppUidForSdkSandboxUid(int);
+    method public static final boolean isSdkSandboxUid(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
   }
@@ -413,6 +410,7 @@
 
   public class StorageManager {
     method public long computeStorageCacheBytes(@NonNull java.io.File);
+    method @Nullable public String getCloudMediaProvider();
     method public void notifyAppIoBlocked(@NonNull java.util.UUID, int, int, int);
     method public void notifyAppIoResumed(@NonNull java.util.UUID, int, int, int);
     method public void setCloudMediaProvider(@Nullable String);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 2c0e641..06f1ac1 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -234,6 +234,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";
@@ -416,7 +417,7 @@
     field public static final int config_defaultCallScreening = 17039398; // 0x1040026
     field public static final int config_defaultDialer = 17039395; // 0x1040023
     field public static final int config_defaultSms = 17039396; // 0x1040024
-    field public static final int config_deviceManager;
+    field public static final int config_devicePolicyManagement;
     field public static final int config_feedbackIntentExtraKey = 17039391; // 0x104001f
     field public static final int config_feedbackIntentNameKey = 17039392; // 0x1040020
     field public static final int config_helpIntentExtraKey = 17039389; // 0x104001d
@@ -463,7 +464,7 @@
 
 package android.app {
 
-  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
     method public void convertFromTranslucent();
     method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
     method @Deprecated public boolean isBackgroundVisibleBehind();
@@ -915,10 +916,10 @@
 
   public class StatusBarManager {
     method @NonNull @RequiresPermission(android.Manifest.permission.STATUS_BAR) public android.app.StatusBarManager.DisableInfo getDisableInfo();
-    method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public int getNavBarModeOverride();
+    method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public int getNavBarMode();
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void registerNearbyMediaDevicesProvider(@NonNull android.media.NearbyMediaDevicesProvider);
     method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setDisabledForSetup(boolean);
-    method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setNavBarModeOverride(int);
+    method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setNavBarMode(int);
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void unregisterNearbyMediaDevicesProvider(@NonNull android.media.NearbyMediaDevicesProvider);
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void updateMediaTapToTransferReceiverDisplay(int, @NonNull android.media.MediaRoute2Info, @Nullable android.graphics.drawable.Icon, @Nullable CharSequence);
     method @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public void updateMediaTapToTransferSenderDisplay(int, @NonNull android.media.MediaRoute2Info, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
@@ -933,8 +934,8 @@
     field public static final int MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED = 7; // 0x7
     field public static final int MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED = 5; // 0x5
     field public static final int MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED = 3; // 0x3
-    field public static final int NAV_BAR_MODE_OVERRIDE_KIDS = 1; // 0x1
-    field public static final int NAV_BAR_MODE_OVERRIDE_NONE = 0; // 0x0
+    field public static final int NAV_BAR_MODE_DEFAULT = 0; // 0x0
+    field public static final int NAV_BAR_MODE_KIDS = 1; // 0x1
   }
 
   public static final class StatusBarManager.DisableInfo {
@@ -1059,10 +1060,10 @@
     ctor public DevicePolicyDrawableResource(@NonNull android.content.Context, @NonNull String, @NonNull String, @NonNull String, @DrawableRes int);
     ctor public DevicePolicyDrawableResource(@NonNull android.content.Context, @NonNull String, @NonNull String, @DrawableRes int);
     method public int describeContents();
-    method @DrawableRes public int getCallingPackageResourceId();
     method @NonNull public String getDrawableId();
     method @NonNull public String getDrawableSource();
     method @NonNull public String getDrawableStyle();
+    method @DrawableRes public int getResourceIdInCallingPackage();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DevicePolicyDrawableResource> CREATOR;
   }
@@ -1088,8 +1089,8 @@
     method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_ADMIN_POLICY}) public java.util.List<java.lang.String> getPermittedInputMethodsForCurrentUser();
     method @Nullable public android.content.ComponentName getProfileOwner() throws java.lang.IllegalArgumentException;
     method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}) public String getProfileOwnerNameAsUser(int) throws java.lang.IllegalArgumentException;
-    method @Nullable public String getString(@NonNull String, @NonNull java.util.concurrent.Callable<java.lang.String>);
-    method @Nullable public String getString(@NonNull String, @NonNull java.util.concurrent.Callable<java.lang.String>, @NonNull java.lang.Object...);
+    method @Nullable public String getString(@NonNull String, @NonNull java.util.function.Supplier<java.lang.String>);
+    method @Nullable public String getString(@NonNull String, @NonNull java.util.function.Supplier<java.lang.String>, @NonNull java.lang.Object...);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}) public int getUserProvisioningState();
     method public boolean isDeviceManaged();
     method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isDeviceProvisioned();
@@ -1101,7 +1102,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>);
@@ -1239,7 +1240,7 @@
   public final class DevicePolicyStringResource implements android.os.Parcelable {
     ctor public DevicePolicyStringResource(@NonNull android.content.Context, @NonNull String, @StringRes int);
     method public int describeContents();
-    method public int getCallingPackageResourceId();
+    method public int getResourceIdInCallingPackage();
     method @NonNull public String getStringId();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.DevicePolicyStringResource> CREATOR;
@@ -1254,6 +1255,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 +1266,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);
@@ -2172,23 +2175,41 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.SmartspaceTarget> CREATOR;
     field public static final int FEATURE_ALARM = 7; // 0x7
     field public static final int FEATURE_BEDTIME_ROUTINE = 16; // 0x10
+    field public static final int FEATURE_BLAZE_BUILD_PROGRESS = 40; // 0x28
     field public static final int FEATURE_CALENDAR = 2; // 0x2
     field public static final int FEATURE_COMMUTE_TIME = 3; // 0x3
     field public static final int FEATURE_CONSENT = 11; // 0xb
+    field public static final int FEATURE_CROSS_DEVICE_TIMER = 32; // 0x20
+    field public static final int FEATURE_DOORBELL = 30; // 0x1e
+    field public static final int FEATURE_DRIVING_MODE = 26; // 0x1a
+    field public static final int FEATURE_EARTHQUAKE_ALERT = 38; // 0x26
+    field public static final int FEATURE_EARTHQUAKE_OCCURRED = 41; // 0x29
     field public static final int FEATURE_ETA_MONITORING = 18; // 0x12
     field public static final int FEATURE_FITNESS_TRACKING = 17; // 0x11
+    field public static final int FEATURE_FLASHLIGHT = 28; // 0x1c
     field public static final int FEATURE_FLIGHT = 4; // 0x4
+    field public static final int FEATURE_GAS_STATION_PAYMENT = 24; // 0x18
+    field public static final int FEATURE_HOLIDAY_ALARM = 34; // 0x22
     field public static final int FEATURE_LOYALTY_CARD = 14; // 0xe
     field public static final int FEATURE_MEDIA = 15; // 0xf
+    field public static final int FEATURE_MEDIA_HEADS_UP = 36; // 0x24
+    field public static final int FEATURE_MEDIA_RESUME = 31; // 0x1f
     field public static final int FEATURE_MISSED_CALL = 19; // 0x13
     field public static final int FEATURE_ONBOARDING = 8; // 0x8
     field public static final int FEATURE_PACKAGE_TRACKING = 20; // 0x14
+    field public static final int FEATURE_PAIRED_DEVICE_STATE = 25; // 0x19
     field public static final int FEATURE_REMINDER = 6; // 0x6
+    field public static final int FEATURE_SAFETY_CHECK = 35; // 0x23
+    field public static final int FEATURE_SEVERE_WEATHER_ALERT = 33; // 0x21
     field public static final int FEATURE_SHOPPING_LIST = 13; // 0xd
+    field public static final int FEATURE_SLEEP_SUMMARY = 27; // 0x1b
     field public static final int FEATURE_SPORTS = 9; // 0x9
+    field public static final int FEATURE_STEP_COUNTING = 37; // 0x25
+    field public static final int FEATURE_STEP_DATE = 39; // 0x27
     field public static final int FEATURE_STOCK_PRICE_CHANGE = 12; // 0xc
     field public static final int FEATURE_STOPWATCH = 22; // 0x16
     field public static final int FEATURE_TIMER = 21; // 0x15
+    field public static final int FEATURE_TIME_TO_LEAVE = 29; // 0x1d
     field public static final int FEATURE_TIPS = 5; // 0x5
     field public static final int FEATURE_UNDEFINED = 0; // 0x0
     field public static final int FEATURE_UPCOMING_ALARM = 23; // 0x17
@@ -2254,22 +2275,12 @@
   public class BaseTemplateData implements android.os.Parcelable {
     method public int describeContents();
     method public int getLayoutWeight();
-    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo getPrimaryLoggingInfo();
-    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getPrimaryTapAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.Icon getSubtitleIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.Text getSubtitleText();
-    method @Nullable public android.app.smartspace.uitemplatedata.Text getSupplementalAlarmText();
-    method @Nullable public android.app.smartspace.uitemplatedata.Icon getSupplementalIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo getSupplementalLoggingInfo();
-    method @Nullable public android.app.smartspace.uitemplatedata.Icon getSupplementalSubtitleIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo getSupplementalSubtitleLoggingInfo();
-    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getSupplementalSubtitleTapAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.Text getSupplementalSubtitleText();
-    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getSupplementalTapAction();
-    method @Nullable public android.app.smartspace.uitemplatedata.Text getSupplementalText();
+    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo getPrimaryItem();
+    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo getSubtitleItem();
+    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo getSubtitleSupplementalItem();
+    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo getSupplementalAlarmItem();
+    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo getSupplementalLineItem();
     method public int getTemplateType();
-    method @Nullable public android.app.smartspace.uitemplatedata.Icon getTitleIcon();
-    method @Nullable public android.app.smartspace.uitemplatedata.Text getTitleText();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.BaseTemplateData> CREATOR;
   }
@@ -2278,27 +2289,37 @@
     ctor public BaseTemplateData.Builder(int);
     method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData build();
     method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setLayoutWeight(int);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setPrimaryLoggingInfo(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setPrimaryTapAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSubtitleIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSubtitleText(@NonNull android.app.smartspace.uitemplatedata.Text);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalAlarmText(@NonNull android.app.smartspace.uitemplatedata.Text);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalLoggingInfo(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalSubtitleIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalSubtitleLoggingInfo(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalSubtitleTapAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalSubtitleText(@NonNull android.app.smartspace.uitemplatedata.Text);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalTapAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalText(@NonNull android.app.smartspace.uitemplatedata.Text);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setTitleIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
-    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setTitleText(@NonNull android.app.smartspace.uitemplatedata.Text);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setPrimaryItem(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSubtitleItem(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSubtitleSupplementalItem(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalAlarmItem(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.Builder setSupplementalLineItem(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo);
+  }
+
+  public static final class BaseTemplateData.SubItemInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @Nullable public android.app.smartspace.uitemplatedata.Icon getIcon();
+    method @Nullable public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo getLoggingInfo();
+    method @Nullable public android.app.smartspace.uitemplatedata.TapAction getTapAction();
+    method @Nullable public android.app.smartspace.uitemplatedata.Text getText();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo> CREATOR;
+  }
+
+  public static final class BaseTemplateData.SubItemInfo.Builder {
+    ctor public BaseTemplateData.SubItemInfo.Builder();
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo build();
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo.Builder setIcon(@NonNull android.app.smartspace.uitemplatedata.Icon);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo.Builder setLoggingInfo(@NonNull android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo.Builder setTapAction(@NonNull android.app.smartspace.uitemplatedata.TapAction);
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemInfo.Builder setText(@NonNull android.app.smartspace.uitemplatedata.Text);
   }
 
   public static final class BaseTemplateData.SubItemLoggingInfo implements android.os.Parcelable {
     method public int describeContents();
     method public int getFeatureType();
     method public int getInstanceId();
+    method @Nullable public CharSequence getPackageName();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo> CREATOR;
   }
@@ -2306,6 +2327,7 @@
   public static final class BaseTemplateData.SubItemLoggingInfo.Builder {
     ctor public BaseTemplateData.SubItemLoggingInfo.Builder(int, int);
     method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo build();
+    method @NonNull public android.app.smartspace.uitemplatedata.BaseTemplateData.SubItemLoggingInfo.Builder setPackageName(@NonNull CharSequence);
   }
 
   public final class CarouselTemplateData extends android.app.smartspace.uitemplatedata.BaseTemplateData {
@@ -2789,11 +2811,10 @@
   }
 
   public static class VirtualDeviceManager.VirtualDevice implements java.lang.AutoCloseable {
-    method public void addActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
-    method public void addActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener, @NonNull java.util.concurrent.Executor);
+    method public void addActivityListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
     method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.audio.VirtualAudioDevice createVirtualAudioDevice(@NonNull android.hardware.display.VirtualDisplay, @Nullable java.util.concurrent.Executor, @Nullable android.companion.virtual.audio.VirtualAudioDevice.AudioConfigurationChangeCallback);
-    method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @Nullable android.view.Surface, int, @NonNull java.util.concurrent.Executor, @Nullable android.hardware.display.VirtualDisplay.Callback);
+    method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(@IntRange(from=1) int, @IntRange(from=1) int, @IntRange(from=1) int, @Nullable android.view.Surface, int, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.display.VirtualDisplay.Callback);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
     method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
@@ -2804,11 +2825,14 @@
 
   public final class VirtualDeviceParams implements android.os.Parcelable {
     method public int describeContents();
-    method @Nullable public java.util.Set<android.content.ComponentName> getAllowedActivities();
-    method @Nullable public java.util.Set<android.content.ComponentName> getBlockedActivities();
+    method @NonNull public java.util.Set<android.content.ComponentName> getAllowedActivities();
+    method @NonNull public java.util.Set<android.content.ComponentName> getBlockedActivities();
+    method public int getDefaultActivityPolicy();
     method public int getLockState();
     method @NonNull public java.util.Set<android.os.UserHandle> getUsersWithMatchingAccounts();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int ACTIVITY_POLICY_DEFAULT_ALLOWED = 0; // 0x0
+    field public static final int ACTIVITY_POLICY_DEFAULT_BLOCKED = 1; // 0x1
     field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.VirtualDeviceParams> CREATOR;
     field public static final int LOCK_STATE_ALWAYS_UNLOCKED = 1; // 0x1
     field public static final int LOCK_STATE_DEFAULT = 0; // 0x0
@@ -2817,8 +2841,8 @@
   public static final class VirtualDeviceParams.Builder {
     ctor public VirtualDeviceParams.Builder();
     method @NonNull public android.companion.virtual.VirtualDeviceParams build();
-    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAllowedActivities(@Nullable java.util.Set<android.content.ComponentName>);
-    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@Nullable java.util.Set<android.content.ComponentName>);
+    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setAllowedActivities(@NonNull java.util.Set<android.content.ComponentName>);
+    method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setBlockedActivities(@NonNull java.util.Set<android.content.ComponentName>);
     method @NonNull @RequiresPermission(value=android.Manifest.permission.ADD_ALWAYS_UNLOCKED_DISPLAY, conditional=true) public android.companion.virtual.VirtualDeviceParams.Builder setLockState(int);
     method @NonNull public android.companion.virtual.VirtualDeviceParams.Builder setUsersWithMatchingAccounts(@NonNull java.util.Set<android.os.UserHandle>);
   }
@@ -2828,19 +2852,31 @@
 package android.companion.virtual.audio {
 
   public final class AudioCapture {
-    ctor public AudioCapture();
+    method @NonNull public android.media.AudioFormat getFormat();
     method public int getRecordingState();
+    method public int read(@NonNull byte[], int, int);
+    method public int read(@NonNull byte[], int, int, int);
     method public int read(@NonNull java.nio.ByteBuffer, int);
+    method public int read(@NonNull java.nio.ByteBuffer, int, int);
+    method public int read(@NonNull float[], int, int, int);
+    method public int read(@NonNull short[], int, int);
+    method public int read(@NonNull short[], int, int, int);
     method public void startRecording();
     method public void stop();
   }
 
   public final class AudioInjection {
-    ctor public AudioInjection();
+    method @NonNull public android.media.AudioFormat getFormat();
     method public int getPlayState();
     method public void play();
     method public void stop();
+    method public int write(@NonNull byte[], int, int);
+    method public int write(@NonNull byte[], int, int, int);
     method public int write(@NonNull java.nio.ByteBuffer, int, int);
+    method public int write(@NonNull java.nio.ByteBuffer, int, int, long);
+    method public int write(@NonNull float[], int, int, int);
+    method public int write(@NonNull short[], int, int);
+    method public int write(@NonNull short[], int, int, int);
   }
 
   public final class VirtualAudioDevice implements java.io.Closeable {
@@ -3016,6 +3052,7 @@
     field public static final String ACTION_USER_REMOVED = "android.intent.action.USER_REMOVED";
     field public static final String ACTION_USER_SWITCHED = "android.intent.action.USER_SWITCHED";
     field @RequiresPermission(android.Manifest.permission.START_VIEW_APP_FEATURES) public static final String ACTION_VIEW_APP_FEATURES = "android.intent.action.VIEW_APP_FEATURES";
+    field @RequiresPermission(android.Manifest.permission.MANAGE_SENSOR_PRIVACY) public static final String ACTION_VIEW_SAFETY_CENTER_QS = "android.intent.action.VIEW_SAFETY_CENTER_QS";
     field public static final String ACTION_VOICE_ASSIST = "android.intent.action.VOICE_ASSIST";
     field public static final String CATEGORY_LEANBACK_SETTINGS = "android.intent.category.LEANBACK_SETTINGS";
     field public static final String EXTRA_CALLING_PACKAGE = "android.intent.extra.CALLING_PACKAGE";
@@ -5889,16 +5926,16 @@
     method @IntRange(from=0, to=1023) public int getIssueOfDataClock();
     method @IntRange(from=0, to=255) public int getIssueOfDataEphemeris();
     method @Nullable public android.location.SatellitePvt.PositionEcef getPositionEcef();
-    method @IntRange(from=0) public long getTimeOfClock();
-    method @IntRange(from=0) public long getTimeOfEphemeris();
+    method @IntRange(from=0) public long getTimeOfClockSeconds();
+    method @IntRange(from=0) public long getTimeOfEphemerisSeconds();
     method @FloatRange public double getTropoDelayMeters();
     method @Nullable public android.location.SatellitePvt.VelocityEcef getVelocityEcef();
     method public boolean hasIono();
     method public boolean hasIssueOfDataClock();
     method public boolean hasIssueOfDataEphemeris();
     method public boolean hasPositionVelocityClockInfo();
-    method public boolean hasTimeOfClock();
-    method public boolean hasTimeOfEphemeris();
+    method public boolean hasTimeOfClockSeconds();
+    method public boolean hasTimeOfEphemerisSeconds();
     method public boolean hasTropo();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.location.SatellitePvt> CREATOR;
@@ -5917,8 +5954,8 @@
     method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataClock(@IntRange(from=0, to=1023) int);
     method @NonNull public android.location.SatellitePvt.Builder setIssueOfDataEphemeris(@IntRange(from=0, to=255) int);
     method @NonNull public android.location.SatellitePvt.Builder setPositionEcef(@NonNull android.location.SatellitePvt.PositionEcef);
-    method @NonNull public android.location.SatellitePvt.Builder setTimeOfClock(@IntRange(from=0) long);
-    method @NonNull public android.location.SatellitePvt.Builder setTimeOfEphemeris(@IntRange(from=0) int);
+    method @NonNull public android.location.SatellitePvt.Builder setTimeOfClockSeconds(@IntRange(from=0) long);
+    method @NonNull public android.location.SatellitePvt.Builder setTimeOfEphemerisSeconds(@IntRange(from=0) long);
     method @NonNull public android.location.SatellitePvt.Builder setTropoDelayMeters(@FloatRange(from=0.0f, to=100.0f) double);
     method @NonNull public android.location.SatellitePvt.Builder setVelocityEcef(@NonNull android.location.SatellitePvt.VelocityEcef);
   }
@@ -6085,7 +6122,7 @@
 
   public class AudioManager {
     method @Deprecated public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addAssistantServicesUids(@NonNull java.util.List<java.lang.Integer>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addAssistantServicesUids(@NonNull int[]);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDeviceForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener) throws java.lang.SecurityException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForCapturePresetChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener) throws java.lang.SecurityException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void addOnPreferredDevicesForStrategyChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener) throws java.lang.SecurityException;
@@ -6093,9 +6130,9 @@
     method public void clearAudioServerStateCallback();
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean clearPreferredDevicesForCapturePreset(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int dispatchAudioFocusChange(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
-    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<java.lang.Integer> getActiveAssistantServicesUids();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getActiveAssistantServicesUids();
     method @IntRange(from=0) public long getAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo);
-    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public java.util.List<java.lang.Integer> getAssistantServicesUids();
+    method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int[] getAssistantServicesUids();
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioProductStrategy> getAudioProductStrategies();
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
     method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioRecord getCallDownlinkExtractionAudioRecord(@NonNull android.media.AudioFormat);
@@ -6120,7 +6157,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int registerAudioPolicy(@NonNull android.media.audiopolicy.AudioPolicy);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void registerMuteAwaitConnectionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.MuteAwaitConnectionCallback);
     method public void registerVolumeGroupCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.VolumeGroupCallback);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeAssistantServicesUids(@NonNull java.util.List<java.lang.Integer>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeAssistantServicesUids(@NonNull int[]);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDeviceForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDeviceForStrategyChangedListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForCapturePresetChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForCapturePresetChangedListener);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void removeOnPreferredDevicesForStrategyChangedListener(@NonNull android.media.AudioManager.OnPreferredDevicesForStrategyChangedListener);
@@ -6128,7 +6165,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.MODIFY_AUDIO_ROUTING}) public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, @NonNull android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public int requestAudioFocus(@NonNull android.media.AudioFocusRequest, @Nullable android.media.audiopolicy.AudioPolicy);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setActiveAssistantServiceUids(@NonNull java.util.List<java.lang.Integer>);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setActiveAssistantServiceUids(@NonNull int[]);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setAdditionalOutputDeviceDelay(@NonNull android.media.AudioDeviceInfo, @IntRange(from=0) long);
     method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
@@ -6306,7 +6343,6 @@
     method public int describeContents();
     method @NonNull public String getMediaRoute2Id();
     method public int getRangeZone();
-    method @NonNull public static String rangeZoneToString(int);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.media.NearbyDevice> CREATOR;
     field public static final int RANGE_CLOSE = 3; // 0x3
@@ -8509,14 +8545,21 @@
   }
 
   public final class EthernetNetworkUpdateRequest implements android.os.Parcelable {
-    ctor public EthernetNetworkUpdateRequest(@NonNull android.net.StaticIpConfiguration, @NonNull android.net.NetworkCapabilities);
     method public int describeContents();
-    method @NonNull public android.net.StaticIpConfiguration getIpConfig();
+    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();
@@ -8987,6 +9030,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 getMaxNumScanSsids(@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);
@@ -10262,6 +10306,7 @@
     method @RequiresPermission(android.Manifest.permission.WRITE_DEVICE_CONFIG) public static boolean setProperty(@NonNull String, @NonNull String, @Nullable String, boolean);
     field public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";
     field public static final String NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT = "activity_manager_native_boot";
+    field public static final String NAMESPACE_ADSERVICES = "adservices";
     field public static final String NAMESPACE_AMBIENT_CONTEXT_MANAGER_SERVICE = "ambient_context_manager_service";
     field public static final String NAMESPACE_APPSEARCH = "appsearch";
     field public static final String NAMESPACE_APP_COMPAT = "app_compat";
@@ -10299,13 +10344,13 @@
     field public static final String NAMESPACE_RUNTIME_NATIVE = "runtime_native";
     field public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot";
     field public static final String NAMESPACE_SCHEDULER = "scheduler";
+    field public static final String NAMESPACE_SDK_SANDBOX = "sdk_sandbox";
     field public static final String NAMESPACE_STATSD_JAVA = "statsd_java";
     field public static final String NAMESPACE_STATSD_JAVA_BOOT = "statsd_java_boot";
     field public static final String NAMESPACE_STATSD_NATIVE = "statsd_native";
     field public static final String NAMESPACE_STATSD_NATIVE_BOOT = "statsd_native_boot";
     field @Deprecated public static final String NAMESPACE_STORAGE = "storage";
     field public static final String NAMESPACE_STORAGE_NATIVE_BOOT = "storage_native_boot";
-    field public static final String NAMESPACE_SUPPLEMENTAL_API = "supplemental_api";
     field public static final String NAMESPACE_SURFACE_FLINGER_NATIVE_BOOT = "surface_flinger_native_boot";
     field public static final String NAMESPACE_SWCODEC_NATIVE = "swcodec_native";
     field public static final String NAMESPACE_SYSTEMUI = "systemui";
@@ -10493,6 +10538,7 @@
     field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS";
     field public static final String ACTION_TETHER_PROVISIONING_UI = "android.settings.TETHER_PROVISIONING_UI";
     field public static final String ACTION_TETHER_SETTINGS = "android.settings.TETHER_SETTINGS";
+    field public static final String ACTION_TETHER_UNSUPPORTED_CARRIER_UI = "android.settings.TETHER_UNSUPPORTED_CARRIER_UI";
   }
 
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
@@ -11360,7 +11406,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
   }
 
@@ -15670,6 +15716,11 @@
 
 package android.view {
 
+  @UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+    method @NonNull public final java.util.List<android.graphics.Rect> getUnrestrictedPreferKeepClearRects();
+    method @RequiresPermission(android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS) public final void setUnrestrictedPreferKeepClearRects(@NonNull java.util.List<android.graphics.Rect>);
+  }
+
   public abstract class Window {
     method public void addSystemFlags(@android.view.WindowManager.LayoutParams.SystemFlags int);
   }
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 9757b2f..a22c4bc 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -103,7 +103,7 @@
 
 package android.app {
 
-  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+  @UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.window.OnBackInvokedDispatcherOwner android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
     method public final boolean addDumpable(@NonNull android.util.Dumpable);
     method public void dumpInternal(@NonNull String, @Nullable java.io.FileDescriptor, @NonNull java.io.PrintWriter, @Nullable String[]);
     method public void onMovedToDisplay(int, android.content.res.Configuration);
@@ -154,9 +154,10 @@
   }
 
   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);
+    method public void setEligibleForLegacyPermissionPrompt(boolean);
     method public static void setExitTransitionTimeout(long);
     method public void setLaunchActivityType(int);
     method public void setLaunchWindowingMode(int);
@@ -370,23 +371,25 @@
   }
 
   public class PropertyInvalidatedCache<Query, Result> {
-    ctor public PropertyInvalidatedCache(int, int, @NonNull String, @NonNull String, @NonNull android.app.PropertyInvalidatedCache.QueryHandler<Query,Result>);
-    method @NonNull public static String createPropertyName(int, @NonNull String);
-    method public final void disableForCurrentProcess();
+    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 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 static void invalidateCache(int, @NonNull String);
+    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 int MODULE_BLUETOOTH = 2; // 0x2
-    field public static final int MODULE_SYSTEM = 1; // 0x1
-    field public static final int MODULE_TEST = 0; // 0x0
+    field public static final String MODULE_BLUETOOTH = "bluetooth";
+    field public static final String MODULE_SYSTEM = "system_server";
+    field public static final String MODULE_TELEPHONY = "telephony";
+    field public static final String MODULE_TEST = "test";
   }
 
   public abstract static class PropertyInvalidatedCache.QueryHandler<Q, R> {
@@ -514,6 +517,7 @@
     method public boolean isCurrentInputMethodSetByOwner();
     method public boolean isFactoryResetProtectionPolicySupported();
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public boolean isNewUserDisclaimerAcknowledged();
+    method public boolean isRemovingAdmin(@NonNull android.content.ComponentName, int);
     method @RequiresPermission(anyOf={android.Manifest.permission.MARK_DEVICE_ORGANIZATION_OWNED, android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS}, conditional=true) public void markProfileOwnerOnOrganizationOwnedDevice(@NonNull android.content.ComponentName);
     method @NonNull public static String operationSafetyReasonToString(int);
     method @NonNull public static String operationToString(int);
@@ -826,9 +830,9 @@
     method @NonNull public java.util.List<android.content.pm.ApplicationInfo> getInstalledApplicationsAsUser(@NonNull android.content.pm.PackageManager.ApplicationInfoFlags, int);
     method @Nullable public abstract String[] getNamesForUids(int[]);
     method @NonNull public String getPermissionControllerPackageName();
+    method @NonNull public String getSdkSandboxPackageName();
     method @NonNull public abstract String getServicesSystemSharedLibraryPackageName();
     method @NonNull public abstract String getSharedSystemSharedLibraryPackageName();
-    method @NonNull public String getSupplementalProcessPackageName();
     method @Nullable public String getSystemTextClassifierPackageName();
     method @Nullable public String getWellbeingPackageName();
     method public void holdLock(android.os.IBinder, int);
@@ -1073,7 +1077,7 @@
     field public static final int DIALOG = 3; // 0x3
     field public static final int OTHER = 5; // 0x5
     field public static final int QS_TILE = 1; // 0x1
-    field public static final int SAFETY_HUB = 6; // 0x6
+    field public static final int SAFETY_CENTER = 6; // 0x6
     field public static final int SETTINGS = 2; // 0x2
     field public static final int SHELL = 4; // 0x4
   }
@@ -1462,6 +1466,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);
@@ -1722,6 +1727,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);
@@ -1773,14 +1791,17 @@
   }
 
   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 int toSupplementalUid(int);
+    method public static final boolean isSdkSandboxUid(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
     field public static final int LAST_APP_ZYGOTE_ISOLATED_UID = 98999; // 0x182b7
     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 {
@@ -2157,6 +2178,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";
@@ -2347,6 +2369,8 @@
 
   public abstract class DreamOverlayService extends android.app.Service {
     ctor public DreamOverlayService();
+    method @Nullable public final CharSequence getDreamLabel();
+    method public final boolean isPreviewMode();
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method public abstract void onStartDream(@NonNull android.view.WindowManager.LayoutParams);
     method public final void requestExit();
@@ -2827,10 +2851,6 @@
     field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
   }
 
-  public interface OnBackInvokedDispatcher {
-    field public static final long DISPATCH_BACK_INVOCATION_AHEAD_OF_TIME = 195946584L; // 0xbade858L
-  }
-
   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface RemotableViewMethod {
     method public abstract String asyncImpl() default "";
   }
@@ -2872,6 +2892,7 @@
     method public static int getHoverTooltipHideTimeout();
     method public static int getHoverTooltipShowTimeout();
     method public static int getLongPressTooltipHideTimeout();
+    method public int getPreferKeepClearForFocusDelay();
   }
 
   public class ViewDebug {
@@ -2960,6 +2981,7 @@
 
   public final class AutofillManager {
     field public static final String DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "compat_mode_allowed_packages";
+    field public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED = "autofill_dialog_enabled";
     field public static final String DEVICE_CONFIG_AUTOFILL_SMART_SUGGESTION_SUPPORTED_MODES = "smart_suggestion_supported_modes";
     field public static final int FLAG_SMART_SUGGESTION_OFF = 0; // 0x0
     field public static final int FLAG_SMART_SUGGESTION_SYSTEM = 1; // 0x1
@@ -3082,6 +3104,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public java.util.List<android.view.inputmethod.InputMethodInfo> getInputMethodListAsUser(int);
     method public boolean hasActiveInputConnection(@Nullable android.view.View);
     method public boolean isInputMethodPickerShown();
+    field public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // 0xcc1a029L
   }
 
 }
@@ -3242,6 +3265,10 @@
     field public static final int FEATURE_WINDOW_TOKENS = 2; // 0x2
   }
 
+  public interface OnBackInvokedDispatcher {
+    field public static final long DISPATCH_BACK_INVOCATION_AHEAD_OF_TIME = 195946584L; // 0xbade858L
+  }
+
   public final class SplashScreenView extends android.widget.FrameLayout {
     method @Nullable public android.view.View getBrandingView();
   }
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 8af68d7..530de0f 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -83,11 +83,13 @@
  * @attr ref android.R.styleable#AccessibilityService_canRequestFilterKeyEvents
  * @attr ref android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
  * @attr ref android.R.styleable#AccessibilityService_canRetrieveWindowContent
+ * @attr ref android.R.styleable#AccessibilityService_intro
  * @attr ref android.R.styleable#AccessibilityService_description
  * @attr ref android.R.styleable#AccessibilityService_summary
  * @attr ref android.R.styleable#AccessibilityService_notificationTimeout
  * @attr ref android.R.styleable#AccessibilityService_packageNames
  * @attr ref android.R.styleable#AccessibilityService_settingsActivity
+ * @attr ref android.R.styleable#AccessibilityService_tileService
  * @attr ref android.R.styleable#AccessibilityService_nonInteractiveUiTimeout
  * @attr ref android.R.styleable#AccessibilityService_interactiveUiTimeout
  * @attr ref android.R.styleable#AccessibilityService_canTakeScreenshot
@@ -547,11 +549,11 @@
     private String mSettingsActivityName;
 
     /**
-     * The class name of {@link android.service.quicksettings.TileService} is associated with this
+     * The name of {@link android.service.quicksettings.TileService} is associated with this
      * accessibility service for one to one mapping. It is used by system settings to remind users
      * this accessibility service has a {@link android.service.quicksettings.TileService}.
      */
-    private String mTileServiceClassName;
+    private String mTileServiceName;
 
     /**
      * Bit mask with capabilities of this service.
@@ -740,7 +742,7 @@
             }
             mIsAccessibilityTool = asAttributes.getBoolean(
                     R.styleable.AccessibilityService_isAccessibilityTool, false);
-            mTileServiceClassName = asAttributes.getString(
+            mTileServiceName = asAttributes.getString(
                     com.android.internal.R.styleable.AccessibilityService_tileService);
             peekedValue = asAttributes.peekValue(
                     com.android.internal.R.styleable.AccessibilityService_intro);
@@ -850,14 +852,14 @@
     }
 
     /**
-     * Gets the class name of {@link android.service.quicksettings.TileService} is associated with
+     * Gets the name of {@link android.service.quicksettings.TileService} is associated with
      * this accessibility service.
      *
-     * @return The class names of {@link android.service.quicksettings.TileService}.
+     * @return The name of {@link android.service.quicksettings.TileService}.
      */
     @Nullable
-    public String getTileServiceClassName() {
-        return mTileServiceClassName;
+    public String getTileServiceName() {
+        return mTileServiceName;
     }
 
     /**
@@ -1146,7 +1148,7 @@
         parcel.writeInt(mHtmlDescriptionRes);
         parcel.writeString(mNonLocalizedDescription);
         parcel.writeBoolean(mIsAccessibilityTool);
-        parcel.writeString(mTileServiceClassName);
+        parcel.writeString(mTileServiceName);
         parcel.writeInt(mIntroResId);
     }
 
@@ -1170,7 +1172,7 @@
         mHtmlDescriptionRes = parcel.readInt();
         mNonLocalizedDescription = parcel.readString();
         mIsAccessibilityTool = parcel.readBoolean();
-        mTileServiceClassName = parcel.readString();
+        mTileServiceName = parcel.readString();
         mIntroResId = parcel.readInt();
     }
 
@@ -1224,7 +1226,7 @@
         stringBuilder.append(", ");
         stringBuilder.append("settingsActivityName: ").append(mSettingsActivityName);
         stringBuilder.append(", ");
-        stringBuilder.append("tileServiceClassName: ").append(mTileServiceClassName);
+        stringBuilder.append("tileServiceName: ").append(mTileServiceName);
         stringBuilder.append(", ");
         stringBuilder.append("summary: ").append(mNonLocalizedSummary);
         stringBuilder.append(", ");
diff --git a/core/java/android/accessibilityservice/AccessibilityShortcutInfo.java b/core/java/android/accessibilityservice/AccessibilityShortcutInfo.java
index 9a73219..4e6cfb35 100644
--- a/core/java/android/accessibilityservice/AccessibilityShortcutInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityShortcutInfo.java
@@ -101,11 +101,11 @@
     private String mSettingsActivityName;
 
     /**
-     * The class name of {@link android.service.quicksettings.TileService} is associated with this
+     * The name of {@link android.service.quicksettings.TileService} is associated with this
      * accessibility shortcut target for one to one mapping. It is used by system settings to remind
      * users this accessibility service has a {@link android.service.quicksettings.TileService}.
      */
-    private String mTileServiceClassName;
+    private String mTileServiceName;
 
     /**
      * Creates a new instance.
@@ -163,7 +163,7 @@
             mSettingsActivityName = asAttributes.getString(
                     com.android.internal.R.styleable.AccessibilityShortcutTarget_settingsActivity);
             // Get tile service class name
-            mTileServiceClassName = asAttributes.getString(
+            mTileServiceName = asAttributes.getString(
                     com.android.internal.R.styleable.AccessibilityShortcutTarget_tileService);
             // Gets intro
             mIntroResId = asAttributes.getResourceId(
@@ -287,14 +287,14 @@
     }
 
     /**
-     * Gets the class name of {@link android.service.quicksettings.TileService} is associated with
+     * Gets the name of {@link android.service.quicksettings.TileService} is associated with
      * this accessibility shortcut target.
      *
-     * @return The class names of {@link android.service.quicksettings.TileService}.
+     * @return The class name of {@link android.service.quicksettings.TileService}.
      */
     @Nullable
-    public String getTileServiceClassName() {
-        return mTileServiceClassName;
+    public String getTileServiceName() {
+        return mTileServiceName;
     }
 
     /**
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 11663a5..8f348a4 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -120,9 +120,6 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
-import android.view.OnBackInvokedCallback;
-import android.view.OnBackInvokedDispatcher;
-import android.view.OnBackInvokedDispatcherOwner;
 import android.view.RemoteAnimationDefinition;
 import android.view.SearchEvent;
 import android.view.View;
@@ -149,6 +146,9 @@
 import android.widget.AdapterView;
 import android.widget.Toast;
 import android.widget.Toolbar;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
+import android.window.OnBackInvokedDispatcherOwner;
 import android.window.SplashScreen;
 import android.window.WindowOnBackInvokedDispatcher;
 
@@ -7416,7 +7416,6 @@
                     } else {
                         mDumpableContainer.listDumpables(prefix, writer);
                     }
-                    mDumpableContainer.listDumpables(prefix, writer);
                     return;
                 case DUMP_ARG_DUMP_DUMPABLE:
                     if (args.length == 1) {
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 5ddaa80..0178fa1 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -174,6 +174,13 @@
     public static final String KEY_SPLASH_SCREEN_THEME = "android.activity.splashScreenTheme";
 
     /**
+     * Indicates that this activity launch is eligible to show a legacy permission prompt
+     * @hide
+     */
+    public static final String KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE =
+            "android:activity.legacyPermissionPromptEligible";
+
+    /**
      * Callback for when the last frame of the animation is played.
      * @hide
      */
@@ -445,6 +452,7 @@
     private String mSplashScreenThemeResName;
     @SplashScreen.SplashScreenStyle
     private int mSplashScreenStyle = SplashScreen.SPLASH_SCREEN_STYLE_UNDEFINED;
+    private boolean mIsEligibleForLegacyPermissionPrompt;
     private boolean mRemoveWithTaskOrganizer;
     private boolean mLaunchedFromBubble;
     private boolean mTransientLaunch;
@@ -1243,6 +1251,8 @@
         mTransientLaunch = opts.getBoolean(KEY_TRANSIENT_LAUNCH);
         mSplashScreenStyle = opts.getInt(KEY_SPLASH_SCREEN_STYLE);
         mLaunchIntoPipParams = opts.getParcelable(KEY_LAUNCH_INTO_PIP_PARAMS);
+        mIsEligibleForLegacyPermissionPrompt =
+                opts.getBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE);
     }
 
     /**
@@ -1411,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 */
@@ -1462,18 +1464,36 @@
      * Sets the preferred splash screen style of the opening activities. This only applies if the
      * Activity or Process is not yet created.
      * @param style Can be either {@link SplashScreen#SPLASH_SCREEN_STYLE_ICON} or
-     *              {@link SplashScreen#SPLASH_SCREEN_STYLE_EMPTY}
+     *              {@link SplashScreen#SPLASH_SCREEN_STYLE_SOLID_COLOR}
      */
     @NonNull
     public ActivityOptions setSplashScreenStyle(@SplashScreen.SplashScreenStyle int style) {
         if (style == SplashScreen.SPLASH_SCREEN_STYLE_ICON
-                || style == SplashScreen.SPLASH_SCREEN_STYLE_EMPTY) {
+                || style == SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR) {
             mSplashScreenStyle = style;
         }
         return this;
     }
 
     /**
+     * Whether the activity is eligible to show a legacy permission prompt
+     * @hide
+     */
+    @TestApi
+    public boolean isEligibleForLegacyPermissionPrompt() {
+        return mIsEligibleForLegacyPermissionPrompt;
+    }
+
+    /**
+     * Sets whether the activity is eligible to show a legacy permission prompt
+     * @hide
+     */
+    @TestApi
+    public void setEligibleForLegacyPermissionPrompt(boolean eligible) {
+        mIsEligibleForLegacyPermissionPrompt = eligible;
+    }
+
+    /**
      * Sets whether the activity is to be launched into LockTask mode.
      *
      * Use this option to start an activity in LockTask mode. Note that only apps permitted by
@@ -1909,6 +1929,7 @@
         mSpecsFuture = otherOptions.mSpecsFuture;
         mRemoteAnimationAdapter = otherOptions.mRemoteAnimationAdapter;
         mLaunchIntoPipParams = otherOptions.mLaunchIntoPipParams;
+        mIsEligibleForLegacyPermissionPrompt = otherOptions.mIsEligibleForLegacyPermissionPrompt;
     }
 
     /**
@@ -2084,6 +2105,10 @@
         if (mLaunchIntoPipParams != null) {
             b.putParcelable(KEY_LAUNCH_INTO_PIP_PARAMS, mLaunchIntoPipParams);
         }
+        if (mIsEligibleForLegacyPermissionPrompt) {
+            b.putBoolean(KEY_LEGACY_PERMISSION_PROMPT_ELIGIBLE,
+                    mIsEligibleForLegacyPermissionPrompt);
+        }
         return b;
     }
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 61d1865..64f0301 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4469,12 +4469,6 @@
         // we are back active so skip it.
         unscheduleGcIdler();
 
-        // To investigate "duplciate Application objects" bug (b/185177290)
-        if (UserHandle.myUserId() != UserHandle.getUserId(data.info.applicationInfo.uid)) {
-            Slog.wtf(TAG, "handleCreateService called with wrong appinfo UID: myUserId="
-                    + UserHandle.myUserId() + " appinfo.uid=" + data.info.applicationInfo.uid);
-        }
-
         LoadedApk packageInfo = getPackageInfoNoCheck(
                 data.info.applicationInfo, data.compatInfo);
         Service service = null;
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 9eb3e8f..7c337a4 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -29,14 +29,12 @@
 import android.content.res.Configuration;
 import android.os.Build;
 import android.os.Bundle;
-import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
 import android.view.autofill.AutofillManager;
 
-import com.android.internal.annotations.GuardedBy;
-
 import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Base class for maintaining global application state. You can provide your own
@@ -74,12 +72,8 @@
     @UnsupportedAppUsage
     public LoadedApk mLoadedApk;
 
-    @GuardedBy("sInstances")
-    private static final ArrayMap<Class<?>, Application> sInstances =
-            DEBUG_DUP_APP_INSTANCES ? new ArrayMap<>(1) : null;
-
-    // Only set when DEBUG_DUP_APP_INSTANCES is true.
-    private StackTrace mConstructorStackTrace;
+    private static final AtomicReference<StackTrace> sConstructorStackTrace =
+            new AtomicReference<>();
 
     public interface ActivityLifecycleCallbacks {
 
@@ -252,28 +246,20 @@
     }
 
     private void checkDuplicateInstances() {
-        final Class<?> myClass = this.getClass();
-
-        // We only activate this check for custom application classes.
-        // Otherwise, it'd misfire if multiple apps share the same process, if all of them use
-        // the same Application class (on the same classloader).
-        if (myClass == Application.class) {
+        // STOPSHIP: Delete this check b/221248960
+        // Only run this check for gms-core.
+        if (!"com.google.android.gms".equals(ActivityThread.currentOpPackageName())) {
             return;
         }
-        synchronized (sInstances) {
-            final Application firstInstance = sInstances.get(myClass);
-            if (firstInstance == null) {
-                this.mConstructorStackTrace = new StackTrace("First ctor was called here");
-                sInstances.put(myClass, this);
-                return;
-            }
-            final StackTrace currentStackTrace = new StackTrace("Current ctor was called here",
-                    firstInstance.mConstructorStackTrace);
-            this.mConstructorStackTrace = currentStackTrace;
-            Slog.wtf(TAG, "Application ctor called twice for " + myClass
-                    + " first LoadedApk=" + firstInstance.getLoadedApkInfo(),
-                    currentStackTrace);
+
+        final StackTrace previousStackTrace = sConstructorStackTrace.getAndSet(
+                new StackTrace("Previous stack trace"));
+        if (previousStackTrace == null) {
+            // This is the first call.
+            return;
         }
+        Slog.wtf(TAG, "Application ctor called twice for " + this.getClass(),
+                new StackTrace("Current stack trace", previousStackTrace));
     }
 
     private String getLoadedApkInfo() {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 20ffa25..dca5c54 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -165,50 +165,35 @@
     public static final String PERMISSION_CONTROLLER_RESOURCE_PACKAGE =
             "com.android.permissioncontroller";
 
-    private final Object mLock = new Object();
-
-    @GuardedBy("mLock")
-    private UserManager mUserManager;
-    @GuardedBy("mLock")
-    private PermissionManager mPermissionManager;
-    @GuardedBy("mLock")
-    private PackageInstaller mInstaller;
-    @GuardedBy("mLock")
-    private ArtManager mArtManager;
-    @GuardedBy("mLock")
-    private DevicePolicyManager mDevicePolicyManager;
+    private volatile UserManager mUserManager;
+    private volatile PermissionManager mPermissionManager;
+    private volatile PackageInstaller mInstaller;
+    private volatile ArtManager mArtManager;
+    private volatile DevicePolicyManager mDevicePolicyManager;
+    private volatile String mPermissionsControllerPackageName;
 
     @GuardedBy("mDelegates")
     private final ArrayList<MoveCallbackDelegate> mDelegates = new ArrayList<>();
 
-    @GuardedBy("mLock")
-    private String mPermissionsControllerPackageName;
-
     UserManager getUserManager() {
-        synchronized (mLock) {
-            if (mUserManager == null) {
-                mUserManager = UserManager.get(mContext);
-            }
-            return mUserManager;
+        if (mUserManager == null) {
+            mUserManager = UserManager.get(mContext);
         }
+        return mUserManager;
     }
 
     DevicePolicyManager getDevicePolicyManager() {
-        synchronized (mLock) {
-            if (mDevicePolicyManager == null) {
-                mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
-            }
-            return mDevicePolicyManager;
+        if (mDevicePolicyManager == null) {
+            mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
         }
+        return mDevicePolicyManager;
     }
 
     private PermissionManager getPermissionManager() {
-        synchronized (mLock) {
-            if (mPermissionManager == null) {
-                mPermissionManager = mContext.getSystemService(PermissionManager.class);
-            }
-            return mPermissionManager;
+        if (mPermissionManager == null) {
+            mPermissionManager = mContext.getSystemService(PermissionManager.class);
         }
+        return mPermissionManager;
     }
 
     @Override
@@ -851,25 +836,23 @@
      */
     @Override
     public String getPermissionControllerPackageName() {
-        synchronized (mLock) {
-            if (mPermissionsControllerPackageName == null) {
-                try {
-                    mPermissionsControllerPackageName = mPM.getPermissionControllerPackageName();
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
+        if (mPermissionsControllerPackageName == null) {
+            try {
+                mPermissionsControllerPackageName = mPM.getPermissionControllerPackageName();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
-            return mPermissionsControllerPackageName;
         }
+        return mPermissionsControllerPackageName;
     }
 
     /**
      * @hide
      */
     @Override
-    public String getSupplementalProcessPackageName() {
+    public String getSdkSandboxPackageName() {
         try {
-            return mPM.getSupplementalProcessPackageName();
+            return mPM.getSdkSandboxPackageName();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3235,17 +3218,15 @@
 
     @Override
     public PackageInstaller getPackageInstaller() {
-        synchronized (mLock) {
-            if (mInstaller == null) {
-                try {
-                    mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
-                            mContext.getPackageName(), mContext.getAttributionTag(), getUserId());
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
+        if (mInstaller == null) {
+            try {
+                mInstaller = new PackageInstaller(mPM.getPackageInstaller(),
+                        mContext.getPackageName(), mContext.getAttributionTag(), getUserId());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
-            return mInstaller;
         }
+        return mInstaller;
     }
 
     @Override
@@ -3583,16 +3564,14 @@
 
     @Override
     public ArtManager getArtManager() {
-        synchronized (mLock) {
-            if (mArtManager == null) {
-                try {
-                    mArtManager = new ArtManager(mContext, mPM.getArtManager());
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
+        if (mArtManager == null) {
+            try {
+                mArtManager = new ArtManager(mContext, mPM.getArtManager());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
-            return mArtManager;
         }
+        return mArtManager;
     }
 
     @Override
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index e31a566..8b3c9fa 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -523,6 +523,8 @@
      * Sets whether events (such as posting a notification) originating from an app after it
      * receives the broadcast while in background should be recorded as responses to the broadcast.
      *
+     * <p> Note that this will only be considered when sending explicit broadcast intents.
+     *
      * @param id ID to be used for the response events corresponding to this broadcast. If the
      *           value is {@code 0} (default), then response events will not be recorded. Otherwise,
      *           they will be recorded with the ID provided.
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 569fda9..82ff42b 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -52,9 +52,6 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
-import android.view.OnBackInvokedCallback;
-import android.view.OnBackInvokedDispatcher;
-import android.view.OnBackInvokedDispatcherOwner;
 import android.view.SearchEvent;
 import android.view.View;
 import android.view.View.OnCreateContextMenuListener;
@@ -63,6 +60,9 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
+import android.window.OnBackInvokedDispatcherOwner;
 import android.window.WindowOnBackInvokedDispatcher;
 
 import com.android.internal.R;
diff --git a/core/java/android/app/GameState.java b/core/java/android/app/GameState.java
index 979dd34..fe6e554 100644
--- a/core/java/android/app/GameState.java
+++ b/core/java/android/app/GameState.java
@@ -18,8 +18,6 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -88,12 +86,11 @@
     // One of the states listed above.
     private final @GameStateMode int mMode;
 
-    // This is a game specific description. For example can be level or scene name.
-    private final @Nullable String mDescription;
+    // A developer-supplied enum, e.g. to indicate level or scene.
+    private final int mLabel;
 
-    // This contains any other game specific parameters not covered by the fields above. It can be
-    // quality parameter data, settings, or game modes.
-    private final @NonNull Bundle mMetaData;
+    // The developer-supplied enum, e.g. to indicate the current quality level.
+    private final int mQuality;
 
     /**
      * Create a GameState with the specified loading status.
@@ -101,29 +98,28 @@
      * @param mode The game state mode of type @GameStateMode.
      */
     public GameState(boolean isLoading, @GameStateMode int mode) {
-        this(isLoading, mode, null, new Bundle());
+        this(isLoading, mode, -1, -1);
     }
 
     /**
      * Create a GameState with the given state variables.
      * @param isLoading Whether the game is in the loading state.
-     * @param mode The game state mode of type @GameStateMode.
-     * @param description An optional description of the state.
-     * @param metaData Optional metadata.
+     * @param mode The game state mode.
+     * @param label An optional developer-supplied enum e.g. for the current level.
+     * @param quality An optional developer-supplied enum, e.g. for the current quality level.
      */
-    public GameState(boolean isLoading, @GameStateMode int mode, @Nullable String description,
-            @NonNull Bundle metaData) {
+    public GameState(boolean isLoading, @GameStateMode int mode, int label, int quality) {
         mIsLoading = isLoading;
         mMode = mode;
-        mDescription = description;
-        mMetaData = metaData;
+        mLabel = label;
+        mQuality = quality;
     }
 
     private GameState(Parcel in) {
         mIsLoading = in.readBoolean();
         mMode = in.readInt();
-        mDescription = in.readString();
-        mMetaData = in.readBundle();
+        mLabel = in.readInt();
+        mQuality = in.readInt();
     }
 
     /**
@@ -141,17 +137,19 @@
     }
 
     /**
-     * @return The state description, or null if one is not set.
+     * @return The developer-supplied enum, e.g. to indicate level or scene. The default value (if
+     * not supplied) is -1.
      */
-    public @Nullable String getDescription() {
-        return mDescription;
+    public int getLabel() {
+        return mLabel;
     }
 
     /**
-     * @return metadata associated with the state.
+     * @return The developer-supplied enum, e.g. to indicate the current quality level. The default
+     * value (if not suplied) is -1.
      */
-    public @NonNull Bundle getMetadata() {
-        return mMetaData;
+    public int getQuality() {
+        return mQuality;
     }
 
     @Override
@@ -163,8 +161,8 @@
     public void writeToParcel(@NonNull Parcel parcel, int flags) {
         parcel.writeBoolean(mIsLoading);
         parcel.writeInt(mMode);
-        parcel.writeString(mDescription);
-        parcel.writeBundle(mMetaData);
+        parcel.writeInt(mLabel);
+        parcel.writeInt(mQuality);
     }
 
     /**
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 7c48a57..fe0edfe 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -510,7 +510,6 @@
     void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
     @UnsupportedAppUsage
     int getPackageProcessState(in String packageName, in String callingPackage);
-    void updateDeviceOwner(in String packageName);
 
     // Start of N transactions
     // Start Binder transaction tracking for all applications.
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 490afc1..ef9a2f2 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -299,7 +299,7 @@
      * a short predefined amount of time.
      */
     void registerRemoteAnimationForNextActivityStart(in String packageName,
-           in RemoteAnimationAdapter adapter);
+            in RemoteAnimationAdapter adapter, in IBinder launchCookie);
 
     /**
      * Registers remote animations for a display.
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/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 9910000..cedf483e 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -52,6 +52,7 @@
 import android.view.WindowManagerGlobal;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.policy.IKeyguardLockedStateListener;
 import com.android.internal.util.Preconditions;
 import com.android.internal.widget.IWeakEscrowTokenActivatedListener;
 import com.android.internal.widget.IWeakEscrowTokenRemovedListener;
@@ -183,6 +184,19 @@
     })
     @interface LockTypes {}
 
+    private final IKeyguardLockedStateListener mIKeyguardLockedStateListener =
+            new IKeyguardLockedStateListener.Stub() {
+                @Override
+                public void onKeyguardLockedStateChanged(boolean isKeyguardLocked) {
+                    mKeyguardLockedStateListeners.forEach((listener, executor) -> {
+                        executor.execute(
+                                () -> listener.onKeyguardLockedStateChanged(isKeyguardLocked));
+                    });
+                }
+            };
+    private final ArrayMap<KeyguardLockedStateListener, Executor>
+            mKeyguardLockedStateListeners = new ArrayMap<>();
+
     /**
      * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics
      * if enrolled) for the current user of the device. The caller is expected to launch this
@@ -534,7 +548,7 @@
     /**
      * Return whether the keyguard is currently locked.
      *
-     * @return true if keyguard is locked.
+     * @return {@code true} if the keyguard is locked.
      */
     public boolean isKeyguardLocked() {
         try {
@@ -550,7 +564,7 @@
      *
      * <p>See also {@link #isDeviceSecure()} which ignores SIM locked states.
      *
-     * @return true if a PIN, pattern or password is set or a SIM card is locked.
+     * @return {@code true} if a PIN, pattern or password is set or a SIM card is locked.
      */
     public boolean isKeyguardSecure() {
         try {
@@ -565,7 +579,7 @@
      * keyguard password emergency screen). When in such mode, certain keys,
      * such as the Home key and the right soft keys, don't work.
      *
-     * @return true if in keyguard restricted input mode.
+     * @return {@code true} if in keyguard restricted input mode.
      * @deprecated Use {@link #isKeyguardLocked()} instead.
      */
     public boolean inKeyguardRestrictedInputMode() {
@@ -576,7 +590,7 @@
      * Returns whether the device is currently locked and requires a PIN, pattern or
      * password to unlock.
      *
-     * @return true if unlocking the device currently requires a PIN, pattern or
+     * @return {@code true} if unlocking the device currently requires a PIN, pattern or
      * password.
      */
     public boolean isDeviceLocked() {
@@ -603,7 +617,7 @@
      *
      * <p>See also {@link #isKeyguardSecure} which treats SIM locked states as secure.
      *
-     * @return true if a PIN, pattern or password was set.
+     * @return {@code true} if a PIN, pattern or password was set.
      */
     public boolean isDeviceSecure() {
         return isDeviceSecure(mContext.getUserId());
@@ -762,7 +776,7 @@
     *        as the output of String#getBytes
     * @param complexity - complexity level imposed by the requester
     *        as defined in {@code DevicePolicyManager.PasswordComplexity}
-    * @return true if the password is valid, false otherwise
+    * @return {@code true} if the password is valid, false otherwise
     * @hide
     */
     @RequiresPermission(Manifest.permission.SET_INITIAL_LOCK)
@@ -821,7 +835,7 @@
     *        as the output of String#getBytes
     * @param complexity - complexity level imposed by the requester
     *        as defined in {@code DevicePolicyManager.PasswordComplexity}
-    * @return true if the lock is successfully set, false otherwise
+    * @return {@code true} if the lock is successfully set, false otherwise
     * @hide
     */
     @RequiresPermission(Manifest.permission.SET_INITIAL_LOCK)
@@ -903,8 +917,8 @@
     /**
      * Remove a weak escrow token.
      *
-     * @return true if the given handle refers to a valid weak token previously returned from
-     * {@link #addWeakEscrowToken}, whether it's active or not. return false otherwise.
+     * @return {@code true} if the given handle refers to a valid weak token previously returned
+     * from {@link #addWeakEscrowToken}, whether it's active or not. return false otherwise.
      * @hide
      */
     @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
@@ -944,7 +958,7 @@
     /**
      * Register the given WeakEscrowTokenRemovedListener.
      *
-     * @return true if the listener is registered successfully, return false otherwise.
+     * @return {@code true} if the listener is registered successfully, return false otherwise.
      * @hide
      */
     @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
@@ -982,7 +996,7 @@
     /**
      * Unregister the given WeakEscrowTokenRemovedListener.
      *
-     * @return true if the listener is unregistered successfully, return false otherwise.
+     * @return {@code true} if the listener is unregistered successfully, return false otherwise.
      * @hide
      */
     @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE)
@@ -1076,4 +1090,54 @@
                 throw new IllegalArgumentException("Unknown lock type " + lockType);
         }
     }
+
+    /**
+     * Listener for keyguard locked state changes.
+     */
+    @FunctionalInterface
+    public interface KeyguardLockedStateListener {
+        /**
+         * Callback function that executes when the keyguard locked state changes.
+         */
+        void onKeyguardLockedStateChanged(boolean isKeyguardLocked);
+    }
+
+    /**
+     * Registers a listener to execute when the keyguard visibility changes.
+     *
+     * @param listener The listener to add to receive keyguard visibility changes.
+     */
+    @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+    public void addKeyguardLockedStateListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull KeyguardLockedStateListener listener) {
+        synchronized (mKeyguardLockedStateListeners) {
+            mKeyguardLockedStateListeners.put(listener, executor);
+            if (mKeyguardLockedStateListeners.size() > 1) {
+                return;
+            }
+            try {
+                mWM.addKeyguardLockedStateListener(mIKeyguardLockedStateListener);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Unregisters a listener that executes when the keyguard visibility changes.
+     */
+    @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+    public void removeKeyguardLockedStateListener(@NonNull KeyguardLockedStateListener listener) {
+        synchronized (mKeyguardLockedStateListeners) {
+            mKeyguardLockedStateListeners.remove(listener);
+            if (!mKeyguardLockedStateListeners.isEmpty()) {
+                return;
+            }
+            try {
+                mWM.removeKeyguardLockedStateListener(mIKeyguardLockedStateListener);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 77c7c6f..cf259e57 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -160,6 +160,13 @@
     private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
         = new ArrayMap<>();
     private AppComponentFactory mAppComponentFactory;
+
+    /**
+     * We cache the instantiated application object for each package on this process here.
+     */
+    @GuardedBy("sApplications")
+    private static final ArrayMap<String, Application> sApplications = new ArrayMap<>(4);
+
     private final Object mLock = new Object();
 
     Application getApplication() {
@@ -1345,14 +1352,6 @@
         return mResources;
     }
 
-    /**
-     * Used to investigate "duplicate app objects" bug (b/185177290).
-     * makeApplication() should only be called on the main thread, so no synchronization should
-     * be needed, but syncing anyway just in case.
-     */
-    @GuardedBy("sApplicationCache")
-    private static final ArrayMap<String, Application> sApplicationCache = new ArrayMap<>(4);
-
     @UnsupportedAppUsage
     public Application makeApplication(boolean forceDefaultAppClass,
             Instrumentation instrumentation) {
@@ -1361,15 +1360,8 @@
         }
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
 
-        // For b/185177290.
-        final boolean wrongUser =
-                UserHandle.myUserId() != UserHandle.getUserId(mApplicationInfo.uid);
-        if (wrongUser) {
-            Slog.wtf(TAG, "makeApplication called with wrong appinfo UID: myUserId="
-                    + UserHandle.myUserId() + " appinfo.uid=" + mApplicationInfo.uid);
-        }
-        synchronized (sApplicationCache) {
-            final Application cached = sApplicationCache.get(mPackageName);
+        synchronized (sApplications) {
+            final Application cached = sApplications.get(mPackageName);
             if (cached != null) {
                 // Looks like this is always happening for the system server, because
                 // the LoadedApk created in systemMain() -> attach() isn't cached properly?
@@ -1377,18 +1369,16 @@
                     Slog.wtf(TAG, "App instance already created for package=" + mPackageName
                             + " instance=" + cached);
                 }
-                // TODO Return the cached one, unless it's for the wrong user?
-                // For now, we just add WTF checks.
+                mApplication = cached;
+                return cached;
             }
         }
 
         Application app = null;
 
-        // Temporarily disable per-process app class to investigate b/185177290
-//        final String myProcessName = Process.myProcessName();
-//        String appClass = mApplicationInfo.getCustomApplicationClassNameForProcess(
-//                myProcessName);
-        String appClass = mApplicationInfo.className;
+        final String myProcessName = Process.myProcessName();
+        String appClass = mApplicationInfo.getCustomApplicationClassNameForProcess(
+                myProcessName);
         if (forceDefaultAppClass || (appClass == null)) {
             appClass = "android.app.Application";
         }
@@ -1431,8 +1421,8 @@
         }
         mActivityThread.mAllApplications.add(app);
         mApplication = app;
-        synchronized (sApplicationCache) {
-            sApplicationCache.put(mPackageName, app);
+        synchronized (sApplications) {
+            sApplications.put(mPackageName, app);
         }
 
         if (instrumentation != null) {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 9dd206e..7e0cea89 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -9009,6 +9009,10 @@
          * information that will replace the default values for the output switcher chip on the
          * media control, as well as an intent to use when the output switcher chip is tapped,
          * on devices where this is supported.
+         * <p>
+         * This method is intended for system applications to provide information and/or
+         * functionality that would otherwise be unavailable to the default output switcher because
+         * the media originated on a remote device.
          *
          * @param deviceName The name of the remote device to display
          * @param iconResource Icon resource representing the device
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 715de14..df7bf7b 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -16,10 +16,8 @@
 
 package android.app;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.os.Handler;
 import android.os.Looper;
@@ -138,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:
  *
@@ -193,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.
@@ -232,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> {
         /**
@@ -265,13 +279,6 @@
      * the permissions granted to the processes that contain the corresponding caches.
      * @hide
      */
-    @IntDef(prefix = { "MODULE_" }, value = {
-                MODULE_TEST,
-                MODULE_SYSTEM,
-                MODULE_BLUETOOTH
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Module {}
 
     /**
      * The module used for unit tests and cts tests.  It is expected that no process in
@@ -279,7 +286,7 @@
      * @hide
      */
     @TestApi
-    public static final int MODULE_TEST = 0;
+    public static final String MODULE_TEST = "test";
 
     /**
      * The module used for system server/framework caches.  This is not visible outside
@@ -287,19 +294,19 @@
      * @hide
      */
     @TestApi
-    public static final int MODULE_SYSTEM = 1;
+    public static final String MODULE_SYSTEM = "system_server";
 
     /**
      * The module used for bluetooth caches.
      * @hide
      */
-    @SystemApi(client=SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
-    public static final int MODULE_BLUETOOTH = 2;
+    public static final String MODULE_BLUETOOTH = "bluetooth";
 
-    // A static array mapping module constants to strings.
-    private final static String[] sModuleNames =
-            { "test", "system_server", "bluetooth" };
+    /**
+     * The module used for telephony caches.
+     */
+    public static final String MODULE_TELEPHONY = "telephony";
 
     /**
      * Construct a system property that matches the rules described above.  The module is
@@ -315,7 +322,8 @@
      * @hide
      */
     @TestApi
-    public static @NonNull String createPropertyName(@Module int module, @NonNull String apiName) {
+    public static @NonNull String createPropertyName(@NonNull String module,
+            @NonNull String apiName) {
         char[] api = apiName.toCharArray();
         int upper = 0;
         for (int i = 0; i < api.length; i++) {
@@ -338,14 +346,7 @@
             }
         }
 
-        String moduleName = null;
-        try {
-            moduleName = sModuleNames[module];
-        } catch (ArrayIndexOutOfBoundsException e) {
-            throw new IllegalArgumentException("invalid module " + module);
-        }
-
-        return "cache_key." + moduleName + "." + new String(suffix);
+        return "cache_key." + module + "." + new String(suffix);
     }
 
     /**
@@ -546,9 +547,8 @@
      * @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, @Module int module, @NonNull String api,
+    public PropertyInvalidatedCache(int maxEntries, @NonNull String module, @NonNull String api,
             @NonNull String cacheName, @NonNull QueryHandler<Query, Result> computer) {
         mPropertyName = createPropertyName(module, api);
         mCacheName = cacheName;
@@ -805,7 +805,7 @@
      * TODO(216112648) Remove this in favor of disableForCurrentProcess().
      * @hide
      */
-    public final void disableLocal() {
+    public void disableLocal() {
         disableForCurrentProcess();
     }
 
@@ -815,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
@@ -834,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)) {
@@ -977,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);
     }
 
@@ -987,9 +990,8 @@
      * 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(@Module int module, @NonNull String api) {
+    public static void invalidateCache(@NonNull String module, @NonNull String api) {
         invalidateCache(createPropertyName(module, api));
     }
 
@@ -1211,8 +1213,10 @@
                     getHandlerLocked().sendEmptyMessageAtTime(0, mUncorkDeadlineMs);
                     PropertyInvalidatedCache.corkInvalidations(mPropertyName);
                 } else {
-                    final long count = sCorkedInvalidates.getOrDefault(mPropertyName, (long) 0);
-                    sCorkedInvalidates.put(mPropertyName, count + 1);
+                    synchronized (sCorkLock) {
+                        final long count = sCorkedInvalidates.getOrDefault(mPropertyName, (long) 0);
+                        sCorkedInvalidates.put(mPropertyName, count + 1);
+                    }
                 }
             }
         }
@@ -1341,7 +1345,7 @@
         }
     }
 
-    private void dumpContents(PrintWriter pw, String[] args) {
+    private void dumpContents(PrintWriter pw) {
         long invalidateCount;
         long corkedInvalidates;
         synchronized (sCorkLock) {
@@ -1418,7 +1422,7 @@
 
             for (int i = 0; i < activeCaches.size(); i++) {
                 PropertyInvalidatedCache currentCache = activeCaches.get(i);
-                currentCache.dumpContents(pw, args);
+                currentCache.dumpContents(pw);
                 pw.flush();
             }
         } catch (IOException e) {
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 0326e11..c6e36a3 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -324,31 +324,31 @@
     public @interface RequestResult {}
 
     /**
-     * Constant for {@link #setNavBarModeOverride(int)} indicating the default navbar mode.
+     * Constant for {@link #setNavBarMode(int)} indicating the default navbar mode.
      *
      * @hide
      */
     @SystemApi
-    public static final int NAV_BAR_MODE_OVERRIDE_NONE = 0;
+    public static final int NAV_BAR_MODE_DEFAULT = 0;
 
     /**
-     * Constant for {@link #setNavBarModeOverride(int)} indicating kids navbar mode.
+     * Constant for {@link #setNavBarMode(int)} indicating kids navbar mode.
      *
      * <p>When used, back and home icons will change drawables and layout, recents will be hidden,
-     * and the navbar will remain visible when apps are in immersive mode.
+     * and enables the setting to force navbar visible, even when apps are in immersive mode.
      *
      * @hide
      */
     @SystemApi
-    public static final int NAV_BAR_MODE_OVERRIDE_KIDS = 1;
+    public static final int NAV_BAR_MODE_KIDS = 1;
 
     /** @hide */
-    @IntDef(prefix = {"NAV_BAR_MODE_OVERRIDE_"}, value = {
-            NAV_BAR_MODE_OVERRIDE_NONE,
-            NAV_BAR_MODE_OVERRIDE_KIDS
+    @IntDef(prefix = {"NAV_BAR_MODE_"}, value = {
+            NAV_BAR_MODE_DEFAULT,
+            NAV_BAR_MODE_KIDS
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface NavBarModeOverride {}
+    public @interface NavBarMode {}
 
     /**
      * State indicating that this sender device is close to a receiver device, so the user can
@@ -926,25 +926,23 @@
     }
 
     /**
-     * Sets or removes the navigation bar mode override.
+     * Sets or removes the navigation bar mode.
      *
-     * @param navBarModeOverride the mode of the navigation bar override to be set.
+     * @param navBarMode the mode of the navigation bar to be set.
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.STATUS_BAR)
-    public void setNavBarModeOverride(@NavBarModeOverride int navBarModeOverride) {
-        if (navBarModeOverride != NAV_BAR_MODE_OVERRIDE_NONE
-                && navBarModeOverride != NAV_BAR_MODE_OVERRIDE_KIDS) {
-            throw new IllegalArgumentException(
-                    "Supplied navBarModeOverride not supported: " + navBarModeOverride);
+    public void setNavBarMode(@NavBarMode int navBarMode) {
+        if (navBarMode != NAV_BAR_MODE_DEFAULT && navBarMode != NAV_BAR_MODE_KIDS) {
+            throw new IllegalArgumentException("Supplied navBarMode not supported: " + navBarMode);
         }
 
         try {
             final IStatusBarService svc = getService();
             if (svc != null) {
-                svc.setNavBarModeOverride(navBarModeOverride);
+                svc.setNavBarMode(navBarMode);
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -952,23 +950,23 @@
     }
 
     /**
-     * Gets the navigation bar mode override. Returns default value if no override is set.
+     * Gets the navigation bar mode. Returns default value if no mode is set.
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.STATUS_BAR)
-    public @NavBarModeOverride int getNavBarModeOverride() {
-        int navBarModeOverride = NAV_BAR_MODE_OVERRIDE_NONE;
+    public @NavBarMode int getNavBarMode() {
+        int navBarMode = NAV_BAR_MODE_DEFAULT;
         try {
             final IStatusBarService svc = getService();
             if (svc != null) {
-                navBarModeOverride = svc.getNavBarModeOverride();
+                navBarMode = svc.getNavBarMode();
             }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
-        return navBarModeOverride;
+        return navBarMode;
     }
 
     /**
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index eeb4705..58db93c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -18,6 +18,7 @@
 
 import android.accounts.AccountManager;
 import android.accounts.IAccountManager;
+import android.adservices.AdServicesFrameworkInitializer;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -36,6 +37,7 @@
 import android.app.people.PeopleManager;
 import android.app.prediction.AppPredictionManager;
 import android.app.role.RoleFrameworkInitializer;
+import android.app.sdksandbox.SdkSandboxManagerFrameworkInitializer;
 import android.app.search.SearchUiManager;
 import android.app.slice.SliceManager;
 import android.app.smartspace.SmartspaceManager;
@@ -208,7 +210,6 @@
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.service.persistentdata.PersistentDataBlockManager;
 import android.service.vr.IVrManager;
-import android.supplementalprocess.SupplementalProcessFrameworkInitializer;
 import android.telecom.TelecomManager;
 import android.telephony.MmsManager;
 import android.telephony.TelephonyFrameworkInitializer;
@@ -1564,7 +1565,8 @@
             MediaFrameworkInitializer.registerServiceWrappers();
             RoleFrameworkInitializer.registerServiceWrappers();
             SchedulingFrameworkInitializer.registerServiceWrappers();
-            SupplementalProcessFrameworkInitializer.registerServiceWrappers();
+            SdkSandboxManagerFrameworkInitializer.registerServiceWrappers();
+            AdServicesFrameworkInitializer.registerServiceWrappers();
             UwbFrameworkInitializer.registerServiceWrappers();
             SafetyCenterFrameworkInitializer.registerServiceWrappers();
             ConnectivityFrameworkInitializerTiramisu.registerServiceWrappers();
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index b791f05..5c1ab38 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -841,15 +841,6 @@
     }
 
     /**
-     * Returns true if the windowingMode represents a split window.
-     * @hide
-     */
-    public static boolean isSplitScreenWindowingMode(int windowingMode) {
-        return windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-    }
-
-    /**
      * Returns true if the windows associated with this window configuration can receive input keys.
      * @hide
      */
diff --git a/core/java/android/app/admin/DevicePolicyDrawableResource.java b/core/java/android/app/admin/DevicePolicyDrawableResource.java
index 61ff11b..7fd8e89 100644
--- a/core/java/android/app/admin/DevicePolicyDrawableResource.java
+++ b/core/java/android/app/admin/DevicePolicyDrawableResource.java
@@ -38,7 +38,7 @@
     @NonNull private final @DevicePolicyResources.UpdatableDrawableId String mDrawableId;
     @NonNull private final @DevicePolicyResources.UpdatableDrawableStyle String mDrawableStyle;
     @NonNull private final @DevicePolicyResources.UpdatableDrawableSource String mDrawableSource;
-    private final @DrawableRes int mCallingPackageResourceId;
+    private final @DrawableRes int mResourceIdInCallingPackage;
     @NonNull private ParcelableResource mResource;
 
     /**
@@ -47,25 +47,25 @@
      *
      * <p>It will be used to update the drawable defined by {@code drawableId} with style
      * {@code drawableStyle} located in source {@code drawableSource} to the drawable with ID
-     * {@code callingPackageResourceId} in the calling package</p>
+     * {@code resourceIdInCallingPackage} in the calling package</p>
      *
      * @param drawableId The ID of the drawable to update.
      * @param drawableStyle The style of the drawable to update.
      * @param drawableSource The source of the drawable to update.
-     * @param callingPackageResourceId The ID of the drawable resource in the calling package to
+     * @param resourceIdInCallingPackage The ID of the drawable resource in the calling package to
      *        use as an updated resource.
      *
      * @throws IllegalStateException if the resource with ID
-     * {@code callingPackageResourceId} doesn't exist in the {@code context} package.
+     * {@code resourceIdInCallingPackage} doesn't exist in the {@code context} package.
      */
     public DevicePolicyDrawableResource(
             @NonNull Context context,
             @NonNull @DevicePolicyResources.UpdatableDrawableId String drawableId,
             @NonNull @DevicePolicyResources.UpdatableDrawableStyle String drawableStyle,
             @NonNull @DevicePolicyResources.UpdatableDrawableSource String drawableSource,
-            @DrawableRes int callingPackageResourceId) {
-        this(drawableId, drawableStyle, drawableSource, callingPackageResourceId,
-                new ParcelableResource(context, callingPackageResourceId,
+            @DrawableRes int resourceIdInCallingPackage) {
+        this(drawableId, drawableStyle, drawableSource, resourceIdInCallingPackage,
+                new ParcelableResource(context, resourceIdInCallingPackage,
                         ParcelableResource.RESOURCE_TYPE_DRAWABLE));
     }
 
@@ -73,7 +73,7 @@
             @NonNull @DevicePolicyResources.UpdatableDrawableId String drawableId,
             @NonNull @DevicePolicyResources.UpdatableDrawableStyle String drawableStyle,
             @NonNull @DevicePolicyResources.UpdatableDrawableSource String drawableSource,
-            @DrawableRes int callingPackageResourceId,
+            @DrawableRes int resourceIdInCallingPackage,
             @NonNull ParcelableResource resource) {
 
         Objects.requireNonNull(drawableId);
@@ -84,7 +84,7 @@
         this.mDrawableId = drawableId;
         this.mDrawableStyle = drawableStyle;
         this.mDrawableSource = drawableSource;
-        this.mCallingPackageResourceId = callingPackageResourceId;
+        this.mResourceIdInCallingPackage = resourceIdInCallingPackage;
         this.mResource = resource;
     }
 
@@ -92,24 +92,24 @@
      * Creates an object containing the required information for updating an enterprise drawable
      * resource using {@link DevicePolicyManager#setDrawables}.
      * <p>It will be used to update the drawable defined by {@code drawableId} with style
-     * {@code drawableStyle} to the drawable with ID {@code callingPackageResourceId} in the
+     * {@code drawableStyle} to the drawable with ID {@code resourceIdInCallingPackage} in the
      * calling package</p>
      *
      * @param drawableId The ID of the drawable to update.
      * @param drawableStyle The style of the drawable to update.
-     * @param callingPackageResourceId The ID of the drawable resource in the calling package to
+     * @param resourceIdInCallingPackage The ID of the drawable resource in the calling package to
      *        use as an updated resource.
      *
      * @throws IllegalStateException if the resource with ID
-     * {@code callingPackageResourceId} doesn't exist in the calling package.
+     * {@code resourceIdInCallingPackage} doesn't exist in the calling package.
      */
     public DevicePolicyDrawableResource(
             @NonNull Context context,
             @NonNull @DevicePolicyResources.UpdatableDrawableId String drawableId,
             @NonNull @DevicePolicyResources.UpdatableDrawableStyle String drawableStyle,
-            @DrawableRes int callingPackageResourceId) {
+            @DrawableRes int resourceIdInCallingPackage) {
        this(context, drawableId, drawableStyle, Drawables.Source.UNDEFINED,
-               callingPackageResourceId);
+               resourceIdInCallingPackage);
     }
 
     /**
@@ -144,8 +144,8 @@
      * resource.
      */
     @DrawableRes
-    public int getCallingPackageResourceId() {
-        return mCallingPackageResourceId;
+    public int getResourceIdInCallingPackage() {
+        return mResourceIdInCallingPackage;
     }
 
     /**
@@ -166,14 +166,14 @@
         return mDrawableId.equals(other.mDrawableId)
                 && mDrawableStyle.equals(other.mDrawableStyle)
                 && mDrawableSource.equals(other.mDrawableSource)
-                && mCallingPackageResourceId == other.mCallingPackageResourceId
+                && mResourceIdInCallingPackage == other.mResourceIdInCallingPackage
                 && mResource.equals(other.mResource);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(
-                mDrawableId, mDrawableStyle, mDrawableSource, mCallingPackageResourceId, mResource);
+        return Objects.hash(mDrawableId, mDrawableStyle, mDrawableSource,
+                mResourceIdInCallingPackage, mResource);
     }
 
     @Override
@@ -186,7 +186,7 @@
         dest.writeString(mDrawableId);
         dest.writeString(mDrawableStyle);
         dest.writeString(mDrawableSource);
-        dest.writeInt(mCallingPackageResourceId);
+        dest.writeInt(mResourceIdInCallingPackage);
         dest.writeTypedObject(mResource, flags);
     }
 
@@ -197,11 +197,11 @@
                     String drawableId = in.readString();
                     String drawableStyle = in.readString();
                     String drawableSource = in.readString();
-                    int callingPackageResourceId = in.readInt();
+                    int resourceIdInCallingPackage = in.readInt();
                     ParcelableResource resource = in.readTypedObject(ParcelableResource.CREATOR);
 
                     return new DevicePolicyDrawableResource(
-                            drawableId, drawableStyle, drawableSource, callingPackageResourceId,
+                            drawableId, drawableStyle, drawableSource, resourceIdInCallingPackage,
                             resource);
                 }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 753df3d..4c7b910 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;
@@ -132,11 +134,11 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.Callable;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 // TODO(b/172376923) - add CarDevicePolicyManager examples below (or remove reference to it).
 /**
@@ -242,6 +244,17 @@
      * the provisioning flow was successful, although this doesn't guarantee the full flow will
      * succeed. Conversely a result code of {@link android.app.Activity#RESULT_CANCELED} implies
      * that the user backed-out of provisioning, or some precondition for provisioning wasn't met.
+     *
+     * <p>If a device policy management role holder (DPMRH) updater is present on the device, an
+     * internet connection attempt must be made prior to launching this intent. If internet
+     * connection could not be established, provisioning will fail unless {@link
+     * #EXTRA_PROVISIONING_ALLOW_OFFLINE} is explicitly set to {@code true}, in which case
+     * provisioning will continue without using the DPMRH. If an internet connection has been
+     * established, the DPMRH updater will be launched, which will update the DPMRH if it's not
+     * present on the device, or if it's present and not valid.
+     *
+     * <p>If a DPMRH is present on the device and valid, the provisioning flow will be deferred to
+     * it.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_PROVISION_MANAGED_PROFILE
@@ -398,6 +411,23 @@
      * by a privileged app with the permission
      * {@link android.Manifest.permission#DISPATCH_PROVISIONING_MESSAGE}.
      *
+     * <p>If a device policy management role holder (DPMRH) updater is present on the device, an
+     * internet connection attempt must be made prior to launching this intent. If internet
+     * connection could not be established, provisioning will fail unless {@link
+     * #EXTRA_PROVISIONING_ALLOW_OFFLINE} is explicitly set to {@code true}, in which case
+     * provisioning will continue without using the DPMRH. If an internet connection has been
+     * established, the DPMRH updater will be launched via {@link
+     * #ACTION_UPDATE_DEVICE_MANAGEMENT_ROLE_HOLDER}, which will update the DPMRH if it's not
+     * present on the device, or if it's present and not valid.
+     *
+     * <p>A DPMRH is considered valid if it has intent filters for {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}, {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_PROFILE} and {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_FINALIZATION}.
+     *
+     * <p>If a DPMRH is present on the device and valid, the provisioning flow will be deferred to
+     * it via the {@link #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} intent.
+     *
      * <p>The provisioning intent contains the following properties:
      * <ul>
      * <li>{@link #EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME}</li>
@@ -537,6 +567,10 @@
      * <li>{@link #STATE_USER_PROFILE_COMPLETE}</li>
      * </ul>
      *
+     * <p>If a device policy management role holder (DPMRH) is present on the device and
+     * valid, the provisioning flow will be deferred to it via the {@link
+     * #ACTION_ROLE_HOLDER_PROVISION_FINALIZATION} intent.
+     *
      * @hide
      */
     @SystemApi
@@ -545,15 +579,16 @@
             = "android.app.action.PROVISION_FINALIZATION";
 
     /**
-     * Activity action: starts the managed profile provisioning flow inside the device management
-     * role holder.
+     * Activity action: starts the managed profile provisioning flow inside the device policy
+     * management role holder.
      *
      * <p>During the managed profile provisioning flow, the platform-provided provisioning handler
-     * will delegate provisioning to the device management role holder, by firing this intent.
-     * Third-party mobile device management applications attempting to fire this intent will
+     * will delegate provisioning to the device policy management role holder, by firing this
+     * intent. Third-party mobile device management applications attempting to fire this intent will
      * receive a {@link SecurityException}.
      *
-     * <p>Device management role holders are required to have a handler for this intent action.
+     * <p>Device policy management role holders are required to have a handler for this intent
+     * action.
      *
      * <p>If {@link #EXTRA_ROLE_HOLDER_STATE} is supplied to this intent, it is the responsibility
      * of the role holder to restore its state from this extra. This is the same {@link Bundle}
@@ -596,15 +631,16 @@
     public static final int RESULT_DEVICE_OWNER_SET = 123;
 
     /**
-     * Activity action: starts the trusted source provisioning flow inside the device management
-     * role holder.
+     * Activity action: starts the trusted source provisioning flow inside the device policy
+     * management role holder.
      *
      * <p>During the trusted source provisioning flow, the platform-provided provisioning handler
-     * will delegate provisioning to the device management role holder, by firing this intent.
-     * Third-party mobile device management applications attempting to fire this intent will
+     * will delegate provisioning to the device policy management role holder, by firing this
+     * intent. Third-party mobile device management applications attempting to fire this intent will
      * receive a {@link SecurityException}.
      *
-     * <p>Device management role holders are required to have a handler for this intent action.
+     * <p>Device policy management role holders are required to have a handler for this intent
+     * action.
      *
      * <p>If {@link #EXTRA_ROLE_HOLDER_STATE} is supplied to this intent, it is the responsibility
      * of the role holder to restore its state from this extra. This is the same {@link Bundle}
@@ -624,15 +660,16 @@
             "android.app.action.ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE";
 
     /**
-     * Activity action: starts the provisioning finalization flow inside the device management
-     * role holder.
+     * Activity action: starts the provisioning finalization flow inside the device policy
+     * management role holder.
      *
      * <p>During the provisioning finalization flow, the platform-provided provisioning handler
-     * will delegate provisioning to the device management role holder, by firing this intent.
-     * Third-party mobile device management applications attempting to fire this intent will
+     * will delegate provisioning to the device policy management role holder, by firing this
+     * intent. Third-party mobile device management applications attempting to fire this intent will
      * receive a {@link SecurityException}.
      *
-     * <p>Device management role holders are required to have a handler for this intent action.
+     * <p>Device policy management role holders are required to have a handler for this intent
+     * action.
      *
      * <p>This handler forwards the result from the admin app's {@link
      * #ACTION_ADMIN_POLICY_COMPLIANCE} handler. Result code {@link Activity#RESULT_CANCELED}
@@ -697,9 +734,9 @@
      * A boolean extra indicating whether offline provisioning is allowed.
      *
      * <p>For the online provisioning flow, there will be an attempt to download and install
-     * the latest version of the device management role holder. The platform will then delegate
-     * provisioning to the device management role holder via role holder-specific provisioning
-     * actions.
+     * the latest version of the device policy management role holder. The platform will then
+     * delegate provisioning to the device policy management role holder via role holder-specific
+     * provisioning actions.
      *
      * <p>For the offline provisioning flow, the provisioning flow will always be handled by
      * the platform.
@@ -720,8 +757,8 @@
             "android.app.extra.PROVISIONING_ALLOW_OFFLINE";
 
     /**
-     * A String extra holding a url that specifies the download location of the device manager
-     * role holder package.
+     * A String extra holding a url that specifies the download location of the device policy
+     * management role holder package.
      *
      * <p>This is only meant to be used in cases when a specific variant of the role holder package
      * is needed (such as a debug variant). If not provided, the default variant of the device
@@ -777,13 +814,13 @@
 
     /**
      * An extra of type {@link android.os.PersistableBundle} that allows the provisioning initiator
-     * to pass data to the device manager role holder.
+     * to pass data to the device policy management role holder.
      *
-     * <p>The device manager role holder will receive this extra via the {@link
+     * <p>The device policy management role holder will receive this extra via the {@link
      * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} intent.
      *
      * <p>The contents of this extra are up to the contract between the provisioning initiator
-     * and the device manager role holder.
+     * and the device policy management role holder.
      *
      * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}
      * or in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
@@ -814,18 +851,19 @@
      * <p>If {@link #EXTRA_PROVISIONING_SHOULD_LAUNCH_RESULT_INTENT} is set to {@code false},
      * this result will be supplied as part of the result {@link Intent} for provisioning actions
      * such as {@link #ACTION_PROVISION_MANAGED_PROFILE}. This result will also be supplied as
-     * part of the result {@link Intent} for the device manager role holder provisioning actions.
+     * part of the result {@link Intent} for the device policy management role holder provisioning
+     * actions.
      */
     public static final String EXTRA_RESULT_LAUNCH_INTENT =
             "android.app.extra.RESULT_LAUNCH_INTENT";
 
     /**
      * A boolean extra that determines whether the provisioning flow should launch the resulting
-     * launch intent, if one is supplied by the device manager role holder via {@link
+     * launch intent, if one is supplied by the device policy management role holder via {@link
      * #EXTRA_RESULT_LAUNCH_INTENT}. Default value is {@code false}.
      *
      * <p>If {@code true}, the resulting intent will be launched by the provisioning flow, if one
-     * is supplied by the device manager role holder.
+     * is supplied by the device policy management role holder.
      *
      * <p>If {@code false}, the resulting intent will be returned as {@link
      * #EXTRA_RESULT_LAUNCH_INTENT} to the provisioning initiator, if one is supplied by the device
@@ -1377,6 +1415,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 =
@@ -3026,6 +3067,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
@@ -3049,8 +3092,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 =
@@ -3220,10 +3277,10 @@
             "android.app.action.ADMIN_POLICY_COMPLIANCE";
 
     /**
-     * Activity action: Starts the device management role holder updater.
+     * Activity action: Starts the device policy management role holder updater.
      *
-     * <p>The activity must handle the device management role holder update and set the intent
-     * result to either {@link Activity#RESULT_OK} if the update was successful, {@link
+     * <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
@@ -3261,9 +3318,9 @@
     /**
      * An {@link Intent} extra which resolves to a custom user consent screen.
      *
-     * <p>If this extra is provided to the device management role holder via either {@link
+     * <p>If this extra is provided to the device policy management role holder via either {@link
      * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE} or {@link
-     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_PROFILE}, the device management role holder must
+     * #ACTION_ROLE_HOLDER_PROVISION_MANAGED_PROFILE}, the device policy management role holder must
      * launch this intent which shows the custom user consent screen, replacing its own standard
      * consent screen.
      *
@@ -3279,9 +3336,9 @@
      * </ul>
      *
      * <p>If the custom consent screens are granted by the user {@link Activity#RESULT_OK} is
-     * returned, otherwise {@link Activity#RESULT_CANCELED} is returned. The device management
-     * role holder should ensure that the provisioning flow terminates immediately if consent
-     * is not granted by the user.
+     * returned, otherwise {@link Activity#RESULT_CANCELED} is returned. The device policy
+     * management role holder should ensure that the provisioning flow terminates immediately if
+     * consent is not granted by the user.
      *
      * @hide
      */
@@ -3611,42 +3668,45 @@
 
     /**
      * Broadcast action: notify system apps (e.g. settings, SysUI, etc) that the device management
-     * resources with IDs {@link #EXTRA_RESOURCE_ID} has been updated, the updated resources can be
+     * resources with IDs {@link #EXTRA_RESOURCE_IDS} has been updated, the updated resources can be
      * retrieved using {@link #getDrawable} and {@code #getString}.
      *
      * <p>This broadcast is sent to registered receivers only.
      *
-     * <p> The following extras will be included to identify the type of resource being updated:
-     * <ul>
-     *     <li>{@link #EXTRA_RESOURCE_TYPE_DRAWABLE} for drawable resources</li>
-     *     <li>{@link #EXTRA_RESOURCE_TYPE_STRING} for string resources</li>
-     * </ul>
+     * <p> {@link #EXTRA_RESOURCE_TYPE} will be included to identify the type of resource being
+     * updated.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED =
             "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
 
     /**
-     * A boolean extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate that a
-     * resource of type {@link Drawable} is being updated.
+     * An {@code int} extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate the type
+     * of the resource being updated, the type can be {@link #EXTRA_RESOURCE_TYPE_DRAWABLE} or
+     * {@link #EXTRA_RESOURCE_TYPE_STRING}
      */
-    public static final String EXTRA_RESOURCE_TYPE_DRAWABLE =
-            "android.app.extra.RESOURCE_TYPE_DRAWABLE";
+    public static final String EXTRA_RESOURCE_TYPE =
+            "android.app.extra.RESOURCE_TYPE";
 
     /**
-     * A boolean extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate that a
-     * resource of type {@link String} is being updated.
+     * A {@code int} value for {@link #EXTRA_RESOURCE_TYPE} to indicate that a resource of type
+     * {@link Drawable} is being updated.
      */
-    public static final String EXTRA_RESOURCE_TYPE_STRING =
-            "android.app.extra.RESOURCE_TYPE_STRING";
+    public static final int EXTRA_RESOURCE_TYPE_DRAWABLE = 1;
+
+    /**
+     * A {@code int} value for {@link #EXTRA_RESOURCE_TYPE} to indicate that a resource of type
+     * {@link String} is being updated.
+     */
+    public static final int EXTRA_RESOURCE_TYPE_STRING = 2;
 
     /**
      * An integer array extra for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to indicate which
-     * resource IDs (see {@link DevicePolicyResources.UpdatableDrawableId} and
-     * {@link DevicePolicyResources.UpdatableStringId}) have been updated.
+     * resource IDs (see {@link DevicePolicyResources.Drawables} and
+     * {@link DevicePolicyResources.Strings}) have been updated.
      */
-    public static final String EXTRA_RESOURCE_ID =
-            "android.app.extra.RESOURCE_ID";
+    public static final String EXTRA_RESOURCE_IDS =
+            "android.app.extra.RESOURCE_IDS";
 
     /** @hide */
     @NonNull
@@ -3759,6 +3819,7 @@
      * for the user.
      * @hide
      */
+    @TestApi
     public boolean isRemovingAdmin(@NonNull ComponentName admin, int userId) {
         if (mService != null) {
             try {
@@ -7024,10 +7085,10 @@
      * management app can use {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device
      * information including manufacturer, model, brand, device and product in the attestation
      * record.
-     * Only device owner, profile owner on an organization-owned device and their delegated
-     * certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and
-     * {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial number,
-     * IMEI and MEID correspondingly), if supported by the device
+     * Only device owner, profile owner on an organization-owned device or affiliated user, and
+     * their delegated certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI}
+     * and {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial
+     * number, IMEI and MEID correspondingly), if supported by the device
      * (see {@link #isDeviceIdAttestationSupported()}).
      * Additionally, device owner, profile owner on an organization-owned device and their delegated
      * certificate installers can also request the attestation record to be signed using an
@@ -7913,6 +7974,10 @@
     /**
      * Returns the current runtime nearby notification streaming policy set by the device or profile
      * owner.
+     * <p>
+     * The caller must be the target user's device owner/profile owner or hold the
+     * {@link android.Manifest.permission#READ_NEARBY_STREAMING_POLICY READ_NEARBY_STREAMING_POLICY}
+     * permission.
      */
     @RequiresPermission(
             value = android.Manifest.permission.READ_NEARBY_STREAMING_POLICY,
@@ -7956,6 +8021,10 @@
 
     /**
      * Returns the current runtime nearby app streaming policy set by the device or profile owner.
+     * <p>
+     * The caller must be the target user's device owner/profile owner or hold the
+     * {@link android.Manifest.permission#READ_NEARBY_STREAMING_POLICY READ_NEARBY_STREAMING_POLICY}
+     * permission.
      */
     @RequiresPermission(
             value = android.Manifest.permission.READ_NEARBY_STREAMING_POLICY,
@@ -10964,7 +11033,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.
@@ -10972,75 +11041,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();
         }
@@ -11050,18 +11116,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();
         }
@@ -13545,13 +13609,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>
@@ -13570,7 +13639,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)
      */
@@ -13587,20 +13657,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)
      */
@@ -13618,16 +13694,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)
      */
@@ -14728,17 +14810,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 {
@@ -15123,7 +15208,7 @@
      * the combination of {@link DevicePolicyDrawableResource#getDrawableId()} and
      * {@link DevicePolicyDrawableResource#getDrawableStyle()}, (see
      * {@link DevicePolicyResources.Drawables} and {@link DevicePolicyResources.Drawables.Style}) to
-     * the drawable with ID {@link DevicePolicyDrawableResource#getCallingPackageResourceId()},
+     * the drawable with ID {@link DevicePolicyDrawableResource#getResourceIdInCallingPackage()},
      * meaning any system UI surface calling {@link #getDrawable}
      * with {@code drawableId} and {@code drawableStyle} will get the new resource after this API
      * is called.
@@ -15138,12 +15223,12 @@
      * <p>Important notes to consider when using this API:
      * <ul>
      * <li>{@link #getDrawable} references the resource
-     * {@link DevicePolicyDrawableResource#getCallingPackageResourceId()} in the
+     * {@link DevicePolicyDrawableResource#getResourceIdInCallingPackage()} in the
      * calling package each time it gets called. You have to ensure that the resource is always
      * available in the calling package as long as it is used as an updated resource.
      * <li>You still have to re-call {@code setDrawables} even if you only make changes to the
      * content of the resource with ID
-     * {@link DevicePolicyDrawableResource#getCallingPackageResourceId()} as the content might be
+     * {@link DevicePolicyDrawableResource#getResourceIdInCallingPackage()} as the content might be
      * cached and would need updating.
      * </ul>
      *
@@ -15204,7 +15289,7 @@
      *
      * <p>This API uses the screen density returned from {@link Resources#getConfiguration()}, to
      * set a different value use
-     * {@link #getDrawableForDensity(String, String, int, Callable)}.
+     * {@link #getDrawableForDensity(String, String, int, Supplier)}.
      *
      * <p>Callers should register for {@link #ACTION_DEVICE_POLICY_RESOURCE_UPDATED} to get
      * notified when a resource has been updated.
@@ -15221,16 +15306,16 @@
     public Drawable getDrawable(
             @NonNull @DevicePolicyResources.UpdatableDrawableId String drawableId,
             @NonNull @DevicePolicyResources.UpdatableDrawableStyle String drawableStyle,
-            @NonNull Callable<Drawable> defaultDrawableLoader) {
+            @NonNull Supplier<Drawable> defaultDrawableLoader) {
         return getDrawable(
                 drawableId, drawableStyle, Drawables.Source.UNDEFINED, defaultDrawableLoader);
     }
 
     /**
-     * Similar to {@link #getDrawable(String, String, Callable)}, but also accepts
+     * Similar to {@link #getDrawable(String, String, Supplier)}, but also accepts
      * a {@code drawableSource} (see {@link DevicePolicyResources.Drawables.Source}) which
      * could result in returning a different drawable than
-     * {@link #getDrawable(String, String, Callable)}
+     * {@link #getDrawable(String, String, Supplier)}
      * if an override was set for that specific source.
      *
      * <p>Calls to this API will not return {@code null} unless no updated drawable was found
@@ -15250,7 +15335,7 @@
             @NonNull @DevicePolicyResources.UpdatableDrawableId String drawableId,
             @NonNull @DevicePolicyResources.UpdatableDrawableStyle String drawableStyle,
             @NonNull @DevicePolicyResources.UpdatableDrawableSource String drawableSource,
-            @NonNull Callable<Drawable> defaultDrawableLoader) {
+            @NonNull Supplier<Drawable> defaultDrawableLoader) {
 
         Objects.requireNonNull(drawableId, "drawableId can't be null");
         Objects.requireNonNull(drawableStyle, "drawableStyle can't be null");
@@ -15285,7 +15370,7 @@
     }
 
     /**
-     * Similar to {@link #getDrawable(String, String, Callable)}, but also accepts
+     * Similar to {@link #getDrawable(String, String, Supplier)}, but also accepts
      * {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
      *
      * <p>Calls to this API will not return {@code null} unless no updated drawable was found
@@ -15307,7 +15392,7 @@
             @NonNull @DevicePolicyResources.UpdatableDrawableId String drawableId,
             @NonNull @DevicePolicyResources.UpdatableDrawableStyle String drawableStyle,
             int density,
-            @NonNull Callable<Drawable> defaultDrawableLoader) {
+            @NonNull Supplier<Drawable> defaultDrawableLoader) {
         return getDrawableForDensity(
                 drawableId,
                 drawableStyle,
@@ -15317,7 +15402,7 @@
     }
 
      /**
-     * Similar to {@link #getDrawable(String, String, String, Callable)}, but also accepts
+     * Similar to {@link #getDrawable(String, String, String, Supplier)}, but also accepts
      * {@code density}. See {@link Resources#getDrawableForDensity(int, int, Resources.Theme)}.
      *
       * <p>Calls to this API will not return {@code null} unless no updated drawable was found
@@ -15341,7 +15426,7 @@
             @NonNull @DevicePolicyResources.UpdatableDrawableStyle String drawableStyle,
             @NonNull @DevicePolicyResources.UpdatableDrawableSource String drawableSource,
             int density,
-            @NonNull Callable<Drawable> defaultDrawableLoader) {
+            @NonNull Supplier<Drawable> defaultDrawableLoader) {
 
         Objects.requireNonNull(drawableId, "drawableId can't be null");
         Objects.requireNonNull(drawableStyle, "drawableStyle can't be null");
@@ -15372,7 +15457,7 @@
     }
 
     /**
-     * Similar to {@link #getDrawable(String, String, String, Callable)} but returns an
+     * Similar to {@link #getDrawable(String, String, String, Supplier)} but returns an
      * {@link Icon} instead of a {@link Drawable}.
      *
      * @param drawableId The drawable ID to get the updated resource for.
@@ -15414,7 +15499,7 @@
     }
 
     /**
-     * Similar to {@link #getDrawable(String, String, Callable)} but returns an {@link Icon}
+     * Similar to {@link #getDrawable(String, String, Supplier)} but returns an {@link Icon}
      * instead of a {@link Drawable}.
      *
      * @param drawableId The drawable ID to get the updated resource for.
@@ -15520,7 +15605,7 @@
     @Nullable
     public String getString(
             @NonNull @DevicePolicyResources.UpdatableStringId String stringId,
-            @NonNull Callable<String> defaultStringLoader) {
+            @NonNull Supplier<String> defaultStringLoader) {
 
         Objects.requireNonNull(stringId, "stringId can't be null");
         Objects.requireNonNull(defaultStringLoader, "defaultStringLoader can't be null");
@@ -15547,7 +15632,7 @@
     }
 
     /**
-     * Similar to {@link #getString(String, Callable)} but accepts {@code formatArgs} and returns a
+     * Similar to {@link #getString(String, Supplier)} but accepts {@code formatArgs} and returns a
      * localized formatted string, substituting the format arguments as defined in
      * {@link java.util.Formatter} and {@link java.lang.String#format}, (see
      * {@link Resources#getString(int, Object...)}).
@@ -15567,7 +15652,7 @@
     @SuppressLint("SamShouldBeLast")
     public String getString(
             @NonNull @DevicePolicyResources.UpdatableStringId String stringId,
-            @NonNull Callable<String> defaultStringLoader,
+            @NonNull Supplier<String> defaultStringLoader,
             @NonNull Object... formatArgs) {
 
         Objects.requireNonNull(stringId, "stringId can't be null");
@@ -15595,7 +15680,9 @@
     }
 
     /**
-     * Returns a boolean for whether the DPC has been downloaded during provisioning.
+     * Returns a boolean for whether the DPC
+     * (Device Policy Controller, the agent responsible for enforcing policy)
+     * has been downloaded during provisioning.
      *
      * <p>If true is returned, then any attempts to begin setup again should result in factory reset
      *
@@ -15616,9 +15703,11 @@
     }
 
     /**
-     * Use to indicate that the DPC has or has not been downloaded during provisioning.
+     * Indicates that the DPC (Device Policy Controller, the agent responsible for enforcing policy)
+     * has or has not been downloaded during provisioning.
      *
-     * @param downloaded {@code true} if the dpc has been downloaded during provisioning. false otherwise.
+     * @param downloaded {@code true} if the dpc has been downloaded during provisioning.
+     *                               {@code false} otherwise.
      *
      * @hide
      */
@@ -15636,14 +15725,15 @@
     }
 
     /**
-     * Returns the package name of the device manager role holder.
+     * Returns the package name of the device policy management role holder.
      *
-     * <p>If the device manager role holder is not configured for this device, returns {@code null}.
+     * <p>If the device policy management role holder is not configured for this device, returns
+     * {@code null}.
      */
     @Nullable
-    public String getDeviceManagerRoleHolderPackageName() {
-        String deviceManagerConfig =
-                mContext.getString(com.android.internal.R.string.config_deviceManager);
+    public String getDevicePolicyManagementRoleHolderPackage() {
+        String deviceManagerConfig = mContext.getString(
+                com.android.internal.R.string.config_devicePolicyManagement);
         return extractPackageNameFromDeviceManagerConfig(deviceManagerConfig);
     }
 
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 9045147..b6f0916 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -218,21 +218,27 @@
     public abstract List<String> getDefaultCrossProfilePackages();
 
     /**
-     * Sends the {@code intent} to the packages with cross profile capabilities.
+     * Sends the {@code intent} to the package holding the
+     * {@link android.app.role.RoleManager#ROLE_DEVICE_MANAGER} role and packages with cross
+     * profile capabilities, meaning the application must have the {@code crossProfile}
+     * property and at least one of the following permissions:
      *
-     * <p>This means the application must have the {@code crossProfile} property and the
-     * corresponding permissions, defined by
-     * {@link
-     * android.content.pm.CrossProfileAppsInternal#verifyPackageHasInteractAcrossProfilePermission}.
+     * <ul>
+     *     <li>{@link android.Manifest.permission.INTERACT_ACROSS_PROFILES}
+     *     <li>{@link android.Manifest.permission.INTERACT_ACROSS_USERS}
+     *     <li>{@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL}
+     *     <li>{@link AppOpsManager.OP_INTERACT_ACROSS_PROFILES} appop
+     * </ul>
      *
-     * <p>Note: This method doesn't modify {@code intent} but copies it before use.
-     *
-     * @param intent Template for the intent sent to the package.
+     * <p>Note: The intent itself is not modified but copied before use.
+     *`
+     * @param intent Template for the intent sent to the packages.
      * @param parentHandle Handle of the user that will receive the intents.
      * @param requiresPermission If false, all packages with the {@code crossProfile} property
-     *                           will receive the intent.
+     *                           will receive the intent without requiring the additional
+     *                           permissions.
      */
-    public abstract void broadcastIntentToCrossProfileManifestReceiversAsUser(Intent intent,
+    public abstract void broadcastIntentToManifestReceivers(Intent intent,
             UserHandle parentHandle, boolean requiresPermission);
 
     /**
diff --git a/core/java/android/app/admin/DevicePolicyStringResource.java b/core/java/android/app/admin/DevicePolicyStringResource.java
index 5f09bfd..b36f1408 100644
--- a/core/java/android/app/admin/DevicePolicyStringResource.java
+++ b/core/java/android/app/admin/DevicePolicyStringResource.java
@@ -35,7 +35,7 @@
 @SystemApi
 public final class DevicePolicyStringResource implements Parcelable {
     @NonNull private final @DevicePolicyResources.UpdatableStringId String mStringId;
-    private final @StringRes int mCallingPackageResourceId;
+    private final @StringRes int mResourceIdInCallingPackage;
     @NonNull private ParcelableResource mResource;
 
     /**
@@ -43,32 +43,32 @@
      * resource using {@link DevicePolicyManager#setStrings}.
      *
      * <p>It will be used to update the string defined by {@code stringId} to the string with ID
-     * {@code callingPackageResourceId} in the calling package</p>
+     * {@code resourceIdInCallingPackage} in the calling package</p>
      *
      * @param stringId The ID of the string to update.
-     * @param callingPackageResourceId The ID of the {@link StringRes} in the calling package to
+     * @param resourceIdInCallingPackage The ID of the {@link StringRes} in the calling package to
      * use as an updated resource.
      *
-     * @throws IllegalStateException if the resource with ID {@code callingPackageResourceId}
+     * @throws IllegalStateException if the resource with ID {@code resourceIdInCallingPackage}
      * doesn't exist in the {@code context} package.
      */
     public DevicePolicyStringResource(
             @NonNull Context context,
             @NonNull @DevicePolicyResources.UpdatableStringId String stringId,
-            @StringRes int callingPackageResourceId) {
-        this(stringId, callingPackageResourceId, new ParcelableResource(
-                context, callingPackageResourceId, ParcelableResource.RESOURCE_TYPE_STRING));
+            @StringRes int resourceIdInCallingPackage) {
+        this(stringId, resourceIdInCallingPackage, new ParcelableResource(
+                context, resourceIdInCallingPackage, ParcelableResource.RESOURCE_TYPE_STRING));
     }
 
     private DevicePolicyStringResource(
             @NonNull @DevicePolicyResources.UpdatableStringId String stringId,
-            @StringRes int callingPackageResourceId,
+            @StringRes int resourceIdInCallingPackage,
             @NonNull ParcelableResource resource) {
         Objects.requireNonNull(stringId, "stringId must be provided.");
         Objects.requireNonNull(resource, "ParcelableResource must be provided.");
 
         this.mStringId = stringId;
-        this.mCallingPackageResourceId = callingPackageResourceId;
+        this.mResourceIdInCallingPackage = resourceIdInCallingPackage;
         this.mResource = resource;
     }
 
@@ -85,8 +85,8 @@
      * Returns the ID of the {@link StringRes} in the calling package to use as an updated
      * resource.
      */
-    public int getCallingPackageResourceId() {
-        return mCallingPackageResourceId;
+    public int getResourceIdInCallingPackage() {
+        return mResourceIdInCallingPackage;
     }
 
     /**
@@ -105,13 +105,13 @@
         if (o == null || getClass() != o.getClass()) return false;
         DevicePolicyStringResource other = (DevicePolicyStringResource) o;
         return mStringId == other.mStringId
-                && mCallingPackageResourceId == other.mCallingPackageResourceId
+                && mResourceIdInCallingPackage == other.mResourceIdInCallingPackage
                 && mResource.equals(other.mResource);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mStringId, mCallingPackageResourceId, mResource);
+        return Objects.hash(mStringId, mResourceIdInCallingPackage, mResource);
     }
 
     @Override
@@ -122,7 +122,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeString(mStringId);
-        dest.writeInt(mCallingPackageResourceId);
+        dest.writeInt(mResourceIdInCallingPackage);
         dest.writeTypedObject(mResource, flags);
     }
 
@@ -131,10 +131,10 @@
         @Override
         public DevicePolicyStringResource createFromParcel(Parcel in) {
             String stringId = in.readString();
-            int callingPackageResourceId = in.readInt();
+            int resourceIdInCallingPackage = in.readInt();
             ParcelableResource resource = in.readTypedObject(ParcelableResource.CREATOR);
 
-            return new DevicePolicyStringResource(stringId, callingPackageResourceId, resource);
+            return new DevicePolicyStringResource(stringId, resourceIdInCallingPackage, resource);
         }
 
         @Override
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/ParcelableResource.java b/core/java/android/app/admin/ParcelableResource.java
index 0b1b166..bcae284 100644
--- a/core/java/android/app/admin/ParcelableResource.java
+++ b/core/java/android/app/admin/ParcelableResource.java
@@ -39,7 +39,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
-import java.util.concurrent.Callable;
+import java.util.function.Supplier;
 
 /**
  * Used to store the required information to load a resource that was updated using
@@ -179,7 +179,7 @@
     public Drawable getDrawable(
             Context context,
             int density,
-            @NonNull Callable<Drawable> defaultDrawableLoader) {
+            @NonNull Supplier<Drawable> defaultDrawableLoader) {
         // TODO(b/203548565): properly handle edge case when the device manager role holder is
         //  unavailable because it's being updated.
         try {
@@ -203,7 +203,7 @@
     @Nullable
     public String getString(
             Context context,
-            @NonNull Callable<String> defaultStringLoader) {
+            @NonNull Supplier<String> defaultStringLoader) {
         // TODO(b/203548565): properly handle edge case when the device manager role holder is
         //  unavailable because it's being updated.
         try {
@@ -227,7 +227,7 @@
     @Nullable
     public String getString(
             Context context,
-            @NonNull Callable<String> defaultStringLoader,
+            @NonNull Supplier<String> defaultStringLoader,
             @NonNull Object... formatArgs) {
         // TODO(b/203548565): properly handle edge case when the device manager role holder is
         //  unavailable because it's being updated.
@@ -268,26 +268,18 @@
      * returns the {@link Drawable} loaded from calling {@code defaultDrawableLoader}.
      */
     @Nullable
-    public static Drawable loadDefaultDrawable(@NonNull Callable<Drawable> defaultDrawableLoader) {
-        try {
-            Objects.requireNonNull(defaultDrawableLoader, "defaultDrawableLoader can't be null");
-            return defaultDrawableLoader.call();
-        } catch (Exception e) {
-            throw new RuntimeException("Couldn't load default drawable: ", e);
-        }
+    public static Drawable loadDefaultDrawable(@NonNull Supplier<Drawable> defaultDrawableLoader) {
+        Objects.requireNonNull(defaultDrawableLoader, "defaultDrawableLoader can't be null");
+        return defaultDrawableLoader.get();
     }
 
     /**
      * returns the {@link String} loaded from calling {@code defaultStringLoader}.
      */
     @Nullable
-    public static String loadDefaultString(@NonNull Callable<String> defaultStringLoader) {
-        try {
-            Objects.requireNonNull(defaultStringLoader, "defaultStringLoader can't be null");
-            return defaultStringLoader.call();
-        } catch (Exception e) {
-            throw new RuntimeException("Couldn't load default string: ", e);
-        }
+    public static String loadDefaultString(@NonNull Supplier<String> defaultStringLoader) {
+        Objects.requireNonNull(defaultStringLoader, "defaultStringLoader can't be null");
+        return defaultStringLoader.get();
     }
 
     /**
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/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/core/java/android/app/admin/WifiSsidPolicy.aidl
similarity index 68%
copy from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
copy to core/java/android/app/admin/WifiSsidPolicy.aidl
index 2894780..150705d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/core/java/android/app/admin/WifiSsidPolicy.aidl
@@ -1,5 +1,6 @@
 /*
- * 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 +15,6 @@
  * limitations under the License.
  */
 
-package com.android.systemui.dagger;
+package android.app.admin;
 
-import dagger.Module;
-
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
-}
+parcelable WifiSsidPolicy;
\ No newline at end of file
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/smartspace/SmartspaceTarget.java b/core/java/android/app/smartspace/SmartspaceTarget.java
index fd7088f..be077435 100644
--- a/core/java/android/app/smartspace/SmartspaceTarget.java
+++ b/core/java/android/app/smartspace/SmartspaceTarget.java
@@ -159,6 +159,24 @@
     public static final int FEATURE_TIMER = 21;
     public static final int FEATURE_STOPWATCH = 22;
     public static final int FEATURE_UPCOMING_ALARM = 23;
+    public static final int FEATURE_GAS_STATION_PAYMENT = 24;
+    public static final int FEATURE_PAIRED_DEVICE_STATE = 25;
+    public static final int FEATURE_DRIVING_MODE = 26;
+    public static final int FEATURE_SLEEP_SUMMARY = 27;
+    public static final int FEATURE_FLASHLIGHT = 28;
+    public static final int FEATURE_TIME_TO_LEAVE = 29;
+    public static final int FEATURE_DOORBELL = 30;
+    public static final int FEATURE_MEDIA_RESUME = 31;
+    public static final int FEATURE_CROSS_DEVICE_TIMER = 32;
+    public static final int FEATURE_SEVERE_WEATHER_ALERT = 33;
+    public static final int FEATURE_HOLIDAY_ALARM = 34;
+    public static final int FEATURE_SAFETY_CHECK = 35;
+    public static final int FEATURE_MEDIA_HEADS_UP = 36;
+    public static final int FEATURE_STEP_COUNTING = 37;
+    public static final int FEATURE_EARTHQUAKE_ALERT = 38;
+    public static final int FEATURE_STEP_DATE = 39;
+    public static final int FEATURE_BLAZE_BUILD_PROGRESS = 40;
+    public static final int FEATURE_EARTHQUAKE_OCCURRED = 41;
 
     /**
      * @hide
@@ -187,7 +205,25 @@
             FEATURE_PACKAGE_TRACKING,
             FEATURE_TIMER,
             FEATURE_STOPWATCH,
-            FEATURE_UPCOMING_ALARM
+            FEATURE_UPCOMING_ALARM,
+            FEATURE_GAS_STATION_PAYMENT,
+            FEATURE_PAIRED_DEVICE_STATE,
+            FEATURE_DRIVING_MODE,
+            FEATURE_SLEEP_SUMMARY,
+            FEATURE_FLASHLIGHT,
+            FEATURE_TIME_TO_LEAVE,
+            FEATURE_DOORBELL,
+            FEATURE_MEDIA_RESUME,
+            FEATURE_CROSS_DEVICE_TIMER,
+            FEATURE_SEVERE_WEATHER_ALERT,
+            FEATURE_HOLIDAY_ALARM,
+            FEATURE_SAFETY_CHECK,
+            FEATURE_MEDIA_HEADS_UP,
+            FEATURE_STEP_COUNTING,
+            FEATURE_EARTHQUAKE_ALERT,
+            FEATURE_STEP_DATE,
+            FEATURE_BLAZE_BUILD_PROGRESS,
+            FEATURE_EARTHQUAKE_OCCURRED
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface FeatureType {
diff --git a/core/java/android/app/smartspace/uitemplatedata/BaseTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/BaseTemplateData.java
index 584b176..e3cb67a 100644
--- a/core/java/android/app/smartspace/uitemplatedata/BaseTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/BaseTemplateData.java
@@ -20,10 +20,12 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
+import android.app.smartspace.SmartspaceTarget.FeatureType;
 import android.app.smartspace.SmartspaceTarget.UiTemplateType;
 import android.app.smartspace.SmartspaceUtils;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.text.TextUtils;
 
 import java.util.Objects;
 
@@ -57,81 +59,39 @@
     /**
      * Title text and title icon are shown at the first row. When both are absent, the date view
      * will be used, which has its own tap action applied to the title area.
+     *
+     * Primary tap action for the entire card, including the blank spaces, except: 1. When title is
+     * absent, the date view's default tap action is used; 2. Subtitle/Supplemental subtitle uses
+     * its own tap action if being set; 3. Secondary card uses its own tap action if being set.
      */
     @Nullable
-    private final Text mTitleText;
+    private final SubItemInfo mPrimaryItem;
 
-    @Nullable
-    private final Icon mTitleIcon;
 
     /** Subtitle text and icon are shown at the second row. */
     @Nullable
-    private final Text mSubtitleText;
-
-    @Nullable
-    private final Icon mSubtitleIcon;
-
-    /**
-     * Primary tap action for the entire card, including the blank spaces, except: 1. When title is
-     * absent, the date view's default tap action is used; 2. Supplemental subtitle uses its own tap
-     * action if being set; 3. Secondary card uses its own tap action if being set.
-     */
-    @Nullable
-    private final TapAction mPrimaryTapAction;
-
-    /**
-     * Primary logging info for the entire card. This will only be used when rendering a sub card
-     * within the base card. For the base card itself, BcSmartspaceCardLoggingInfo should be used,
-     * which has the display-specific info (e.g. display surface).
-     */
-    @Nullable
-    private final SubItemLoggingInfo mPrimaryLoggingInfo;
+    private final SubItemInfo mSubtitleItem;
 
     /**
      * Supplemental subtitle text and icon are shown at the second row following the subtitle text.
      * Mainly used for weather info on non-weather card.
      */
     @Nullable
-    private final Text mSupplementalSubtitleText;
-
-    @Nullable
-    private final Icon mSupplementalSubtitleIcon;
+    private final SubItemInfo mSubtitleSupplementalItem;
 
     /**
-     * Tap action for the supplemental subtitle's text and icon. Uses the primary tap action if
-     * not being set.
+     * Supplemental line is shown at the third row.
      */
     @Nullable
-    private final TapAction mSupplementalSubtitleTapAction;
+    private final SubItemInfo mSupplementalLineItem;
 
     /**
-     * Logging info for the supplemental subtitle's are. Uses the primary logging info if not being
-     * set.
+     * Supplemental alarm item is specifically used for holiday alarm, which is appended to "next
+     * alarm". This is also shown at the third row, but won't be shown the same time with
+     * mSupplementalLineItem.
      */
     @Nullable
-    private final SubItemLoggingInfo mSupplementalSubtitleLoggingInfo;
-
-    @Nullable
-    private final Text mSupplementalText;
-
-    @Nullable
-    private final Icon mSupplementalIcon;
-
-    @Nullable
-    private final TapAction mSupplementalTapAction;
-
-    /**
-     * Logging info for the supplemental line. Uses the primary logging info if not being set.
-     */
-    @Nullable
-    private final SubItemLoggingInfo mSupplementalLoggingInfo;
-
-    /**
-     * Supplemental alarm text is specifically used for holiday alarm, which is appended to "next
-     * alarm".
-     */
-    @Nullable
-    private final Text mSupplementalAlarmText;
+    private final SubItemInfo mSupplementalAlarmItem;
 
     /**
      * The layout weight info for the card, which indicates how much space it should occupy on the
@@ -141,21 +101,11 @@
 
     BaseTemplateData(@NonNull Parcel in) {
         mTemplateType = in.readInt();
-        mTitleText = in.readTypedObject(Text.CREATOR);
-        mTitleIcon = in.readTypedObject(Icon.CREATOR);
-        mSubtitleText = in.readTypedObject(Text.CREATOR);
-        mSubtitleIcon = in.readTypedObject(Icon.CREATOR);
-        mPrimaryTapAction = in.readTypedObject(TapAction.CREATOR);
-        mPrimaryLoggingInfo = in.readTypedObject(SubItemLoggingInfo.CREATOR);
-        mSupplementalSubtitleText = in.readTypedObject(Text.CREATOR);
-        mSupplementalSubtitleIcon = in.readTypedObject(Icon.CREATOR);
-        mSupplementalSubtitleTapAction = in.readTypedObject(TapAction.CREATOR);
-        mSupplementalSubtitleLoggingInfo = in.readTypedObject(SubItemLoggingInfo.CREATOR);
-        mSupplementalText = in.readTypedObject(Text.CREATOR);
-        mSupplementalIcon = in.readTypedObject(Icon.CREATOR);
-        mSupplementalTapAction = in.readTypedObject(TapAction.CREATOR);
-        mSupplementalLoggingInfo = in.readTypedObject(SubItemLoggingInfo.CREATOR);
-        mSupplementalAlarmText = in.readTypedObject(Text.CREATOR);
+        mPrimaryItem = in.readTypedObject(SubItemInfo.CREATOR);
+        mSubtitleItem = in.readTypedObject(SubItemInfo.CREATOR);
+        mSubtitleSupplementalItem = in.readTypedObject(SubItemInfo.CREATOR);
+        mSupplementalLineItem = in.readTypedObject(SubItemInfo.CREATOR);
+        mSupplementalAlarmItem = in.readTypedObject(SubItemInfo.CREATOR);
         mLayoutWeight = in.readInt();
     }
 
@@ -164,38 +114,18 @@
      * SmartspaceDefaultUiTemplateData.Builder.
      */
     BaseTemplateData(@UiTemplateType int templateType,
-            @Nullable Text titleText,
-            @Nullable Icon titleIcon,
-            @Nullable Text subtitleText,
-            @Nullable Icon subtitleIcon,
-            @Nullable TapAction primaryTapAction,
-            @Nullable SubItemLoggingInfo primaryLoggingInfo,
-            @Nullable Text supplementalSubtitleText,
-            @Nullable Icon supplementalSubtitleIcon,
-            @Nullable TapAction supplementalSubtitleTapAction,
-            @Nullable SubItemLoggingInfo supplementalSubtitleLoggingInfo,
-            @Nullable Text supplementalText,
-            @Nullable Icon supplementalIcon,
-            @Nullable TapAction supplementalTapAction,
-            @Nullable SubItemLoggingInfo supplementalLoggingInfo,
-            @Nullable Text supplementalAlarmText,
+            @Nullable SubItemInfo primaryItem,
+            @Nullable SubItemInfo subtitleItem,
+            @Nullable SubItemInfo subtitleSupplementalItem,
+            @Nullable SubItemInfo supplementalLineItem,
+            @Nullable SubItemInfo supplementalAlarmItem,
             int layoutWeight) {
         mTemplateType = templateType;
-        mTitleText = titleText;
-        mTitleIcon = titleIcon;
-        mSubtitleText = subtitleText;
-        mSubtitleIcon = subtitleIcon;
-        mPrimaryTapAction = primaryTapAction;
-        mPrimaryLoggingInfo = primaryLoggingInfo;
-        mSupplementalSubtitleText = supplementalSubtitleText;
-        mSupplementalSubtitleIcon = supplementalSubtitleIcon;
-        mSupplementalSubtitleTapAction = supplementalSubtitleTapAction;
-        mSupplementalSubtitleLoggingInfo = supplementalSubtitleLoggingInfo;
-        mSupplementalText = supplementalText;
-        mSupplementalIcon = supplementalIcon;
-        mSupplementalTapAction = supplementalTapAction;
-        mSupplementalLoggingInfo = supplementalLoggingInfo;
-        mSupplementalAlarmText = supplementalAlarmText;
+        mPrimaryItem = primaryItem;
+        mSubtitleItem = subtitleItem;
+        mSubtitleSupplementalItem = subtitleSupplementalItem;
+        mSupplementalLineItem = supplementalLineItem;
+        mSupplementalAlarmItem = supplementalAlarmItem;
         mLayoutWeight = layoutWeight;
     }
 
@@ -205,94 +135,34 @@
         return mTemplateType;
     }
 
-    /** Returns the title's text. */
+    /** Returns the primary item (the first line). */
     @Nullable
-    public Text getTitleText() {
-        return mTitleText;
+    public SubItemInfo getPrimaryItem() {
+        return mPrimaryItem;
     }
 
-    /** Returns the title's icon. */
+    /** Returns the subtitle item (the second line). */
     @Nullable
-    public Icon getTitleIcon() {
-        return mTitleIcon;
+    public SubItemInfo getSubtitleItem() {
+        return mSubtitleItem;
     }
 
-    /** Returns the subtitle's text. */
+    /** Returns the subtitle's supplemental item (the second line following the subtitle). */
     @Nullable
-    public Text getSubtitleText() {
-        return mSubtitleText;
+    public SubItemInfo getSubtitleSupplementalItem() {
+        return mSubtitleSupplementalItem;
     }
 
-    /** Returns the subtitle's icon. */
+    /** Returns the supplemental line item (the 3rd line). */
     @Nullable
-    public Icon getSubtitleIcon() {
-        return mSubtitleIcon;
+    public SubItemInfo getSupplementalLineItem() {
+        return mSupplementalLineItem;
     }
 
-    /** Returns the card's primary tap action. */
+    /** Returns the supplemental alarm item (the 3rd line). */
     @Nullable
-    public TapAction getPrimaryTapAction() {
-        return mPrimaryTapAction;
-    }
-
-    /** Returns the card's primary logging info. */
-    @Nullable
-    public SubItemLoggingInfo getPrimaryLoggingInfo() {
-        return mPrimaryLoggingInfo;
-    }
-
-    /** Returns the supplemental subtitle's text. */
-    @Nullable
-    public Text getSupplementalSubtitleText() {
-        return mSupplementalSubtitleText;
-    }
-
-    /** Returns the supplemental subtitle's icon. */
-    @Nullable
-    public Icon getSupplementalSubtitleIcon() {
-        return mSupplementalSubtitleIcon;
-    }
-
-    /** Returns the supplemental subtitle's tap action. Can be null if not being set. */
-    @Nullable
-    public TapAction getSupplementalSubtitleTapAction() {
-        return mSupplementalSubtitleTapAction;
-    }
-
-    /** Returns the card's supplemental title's logging info. */
-    @Nullable
-    public SubItemLoggingInfo getSupplementalSubtitleLoggingInfo() {
-        return mSupplementalSubtitleLoggingInfo;
-    }
-
-    /** Returns the supplemental text. */
-    @Nullable
-    public Text getSupplementalText() {
-        return mSupplementalText;
-    }
-
-    /** Returns the supplemental icon. */
-    @Nullable
-    public Icon getSupplementalIcon() {
-        return mSupplementalIcon;
-    }
-
-    /** Returns the supplemental line's tap action. Can be null if not being set. */
-    @Nullable
-    public TapAction getSupplementalTapAction() {
-        return mSupplementalTapAction;
-    }
-
-    /** Returns the card's supplemental line logging info. */
-    @Nullable
-    public SubItemLoggingInfo getSupplementalLoggingInfo() {
-        return mSupplementalLoggingInfo;
-    }
-
-    /** Returns the supplemental alarm text. */
-    @Nullable
-    public Text getSupplementalAlarmText() {
-        return mSupplementalAlarmText;
+    public SubItemInfo getSupplementalAlarmItem() {
+        return mSupplementalAlarmItem;
     }
 
     /** Returns the card layout weight info. Default weight is 0. */
@@ -325,21 +195,11 @@
     @Override
     public void writeToParcel(@NonNull Parcel out, int flags) {
         out.writeInt(mTemplateType);
-        out.writeTypedObject(mTitleText, flags);
-        out.writeTypedObject(mTitleIcon, flags);
-        out.writeTypedObject(mSubtitleText, flags);
-        out.writeTypedObject(mSubtitleIcon, flags);
-        out.writeTypedObject(mPrimaryTapAction, flags);
-        out.writeTypedObject(mPrimaryLoggingInfo, flags);
-        out.writeTypedObject(mSupplementalSubtitleText, flags);
-        out.writeTypedObject(mSupplementalSubtitleIcon, flags);
-        out.writeTypedObject(mSupplementalSubtitleTapAction, flags);
-        out.writeTypedObject(mSupplementalSubtitleLoggingInfo, flags);
-        out.writeTypedObject(mSupplementalText, flags);
-        out.writeTypedObject(mSupplementalIcon, flags);
-        out.writeTypedObject(mSupplementalTapAction, flags);
-        out.writeTypedObject(mSupplementalLoggingInfo, flags);
-        out.writeTypedObject(mSupplementalAlarmText, flags);
+        out.writeTypedObject(mPrimaryItem, flags);
+        out.writeTypedObject(mSubtitleItem, flags);
+        out.writeTypedObject(mSubtitleSupplementalItem, flags);
+        out.writeTypedObject(mSupplementalLineItem, flags);
+        out.writeTypedObject(mSupplementalAlarmItem, flags);
         out.writeInt(mLayoutWeight);
     }
 
@@ -348,58 +208,29 @@
         if (this == o) return true;
         if (!(o instanceof BaseTemplateData)) return false;
         BaseTemplateData that = (BaseTemplateData) o;
-        return mTemplateType == that.mTemplateType && SmartspaceUtils.isEqual(mTitleText,
-                that.mTitleText)
-                && Objects.equals(mTitleIcon, that.mTitleIcon)
-                && SmartspaceUtils.isEqual(mSubtitleText, that.mSubtitleText)
-                && Objects.equals(mSubtitleIcon, that.mSubtitleIcon)
-                && Objects.equals(mPrimaryTapAction, that.mPrimaryTapAction)
-                && Objects.equals(mPrimaryLoggingInfo, that.mPrimaryLoggingInfo)
-                && SmartspaceUtils.isEqual(mSupplementalSubtitleText,
-                that.mSupplementalSubtitleText)
-                && Objects.equals(mSupplementalSubtitleIcon, that.mSupplementalSubtitleIcon)
-                && Objects.equals(mSupplementalSubtitleTapAction,
-                that.mSupplementalSubtitleTapAction)
-                && Objects.equals(mSupplementalSubtitleLoggingInfo,
-                that.mSupplementalSubtitleLoggingInfo)
-                && SmartspaceUtils.isEqual(mSupplementalText,
-                that.mSupplementalText)
-                && Objects.equals(mSupplementalIcon, that.mSupplementalIcon)
-                && Objects.equals(mSupplementalTapAction, that.mSupplementalTapAction)
-                && Objects.equals(mSupplementalLoggingInfo, that.mSupplementalLoggingInfo)
-                && SmartspaceUtils.isEqual(mSupplementalAlarmText, that.mSupplementalAlarmText)
-                && mLayoutWeight == that.mLayoutWeight;
+        return mTemplateType == that.mTemplateType && mLayoutWeight == that.mLayoutWeight
+                && Objects.equals(mPrimaryItem, that.mPrimaryItem)
+                && Objects.equals(mSubtitleItem, that.mSubtitleItem)
+                && Objects.equals(mSubtitleSupplementalItem, that.mSubtitleSupplementalItem)
+                && Objects.equals(mSupplementalLineItem, that.mSupplementalLineItem)
+                && Objects.equals(mSupplementalAlarmItem, that.mSupplementalAlarmItem);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mTemplateType, mTitleText, mTitleIcon, mSubtitleText, mSubtitleIcon,
-                mPrimaryTapAction, mPrimaryLoggingInfo, mSupplementalSubtitleText,
-                mSupplementalSubtitleIcon, mSupplementalSubtitleTapAction,
-                mSupplementalSubtitleLoggingInfo,
-                mSupplementalText, mSupplementalIcon, mSupplementalTapAction,
-                mSupplementalLoggingInfo, mSupplementalAlarmText, mLayoutWeight);
+        return Objects.hash(mTemplateType, mPrimaryItem, mSubtitleItem, mSubtitleSupplementalItem,
+                mSupplementalLineItem, mSupplementalAlarmItem, mLayoutWeight);
     }
 
     @Override
     public String toString() {
-        return "SmartspaceDefaultUiTemplateData{"
+        return "BaseTemplateData{"
                 + "mTemplateType=" + mTemplateType
-                + ", mTitleText=" + mTitleText
-                + ", mTitleIcon=" + mTitleIcon
-                + ", mSubtitleText=" + mSubtitleText
-                + ", mSubTitleIcon=" + mSubtitleIcon
-                + ", mPrimaryTapAction=" + mPrimaryTapAction
-                + ", mPrimaryLoggingInfo=" + mPrimaryLoggingInfo
-                + ", mSupplementalSubtitleText=" + mSupplementalSubtitleText
-                + ", mSupplementalSubtitleIcon=" + mSupplementalSubtitleIcon
-                + ", mSupplementalSubtitleTapAction=" + mSupplementalSubtitleTapAction
-                + ", mSupplementalSubtitleLoggingInfo=" + mSupplementalSubtitleLoggingInfo
-                + ", mSupplementalText=" + mSupplementalText
-                + ", mSupplementalIcon=" + mSupplementalIcon
-                + ", mSupplementalTapAction=" + mSupplementalTapAction
-                + ", mSupplementalLoggingInfo=" + mSupplementalLoggingInfo
-                + ", mSupplementalAlarmText=" + mSupplementalAlarmText
+                + ", mPrimaryItem=" + mPrimaryItem
+                + ", mSubtitleItem=" + mSubtitleItem
+                + ", mSubtitleSupplementalItem=" + mSubtitleSupplementalItem
+                + ", mSupplementalLineItem=" + mSupplementalLineItem
+                + ", mSupplementalAlarmItem=" + mSupplementalAlarmItem
                 + ", mLayoutWeight=" + mLayoutWeight
                 + '}';
     }
@@ -414,21 +245,12 @@
     public static class Builder {
         @UiTemplateType
         private final int mTemplateType;
-        private Text mTitleText;
-        private Icon mTitleIcon;
-        private Text mSubtitleText;
-        private Icon mSubtitleIcon;
-        private TapAction mPrimaryTapAction;
-        private SubItemLoggingInfo mPrimaryLoggingInfo;
-        private Text mSupplementalSubtitleText;
-        private Icon mSupplementalSubtitleIcon;
-        private TapAction mSupplementalSubtitleTapAction;
-        private SubItemLoggingInfo mSupplementalSubtitleLoggingInfo;
-        private Text mSupplementalText;
-        private Icon mSupplementalIcon;
-        private TapAction mSupplementalTapAction;
-        private SubItemLoggingInfo mSupplementalLoggingInfo;
-        private Text mSupplementalAlarmText;
+
+        private SubItemInfo mPrimaryItem;
+        private SubItemInfo mSubtitleItem;
+        private SubItemInfo mSubtitleSupplementalItem;
+        private SubItemInfo mSupplementalLineItem;
+        private SubItemInfo mSupplementalAlarmItem;
         private int mLayoutWeight;
 
         /**
@@ -451,106 +273,36 @@
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        Text getTitleText() {
-            return mTitleText;
+        SubItemInfo getPrimaryItem() {
+            return mPrimaryItem;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        Icon getTitleIcon() {
-            return mTitleIcon;
+        SubItemInfo getSubtitleItem() {
+            return mSubtitleItem;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        Text getSubtitleText() {
-            return mSubtitleText;
+        SubItemInfo getSubtitleSupplemtnalItem() {
+            return mSubtitleSupplementalItem;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        Icon getSubtitleIcon() {
-            return mSubtitleIcon;
+        SubItemInfo getSupplementalLineItem() {
+            return mSupplementalLineItem;
         }
 
         /** Should ONLY be used by the subclasses */
         @Nullable
         @SuppressLint("GetterOnBuilder")
-        TapAction getPrimaryTapAction() {
-            return mPrimaryTapAction;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        SubItemLoggingInfo getPrimaryLoggingInfo() {
-            return mPrimaryLoggingInfo;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        Text getSupplementalSubtitleText() {
-            return mSupplementalSubtitleText;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        Icon getSupplementalSubtitleIcon() {
-            return mSupplementalSubtitleIcon;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        TapAction getSupplementalSubtitleTapAction() {
-            return mSupplementalSubtitleTapAction;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        SubItemLoggingInfo getSupplementalSubtitleLoggingInfo() {
-            return mSupplementalSubtitleLoggingInfo;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        Text getSupplementalText() {
-            return mSupplementalText;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        Icon getSupplementalIcon() {
-            return mSupplementalIcon;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        TapAction getSupplementalTapAction() {
-            return mSupplementalTapAction;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        SubItemLoggingInfo getSupplementalLoggingInfo() {
-            return mSupplementalLoggingInfo;
-        }
-
-        /** Should ONLY be used by the subclasses */
-        @Nullable
-        @SuppressLint("GetterOnBuilder")
-        Text getSupplementalAlarmText() {
-            return mSupplementalAlarmText;
+        SubItemInfo getSupplementalAlarmItem() {
+            return mSupplementalAlarmItem;
         }
 
         /** Should ONLY be used by the subclasses */
@@ -560,144 +312,47 @@
         }
 
         /**
-         * Sets the card title.
+         * Sets the card primary item.
          */
         @NonNull
-        public Builder setTitleText(@NonNull Text titleText) {
-            mTitleText = titleText;
+        public Builder setPrimaryItem(@NonNull SubItemInfo primaryItem) {
+            mPrimaryItem = primaryItem;
             return this;
         }
 
         /**
-         * Sets the card title icon.
+         * Sets the card subtitle item.
          */
         @NonNull
-        public Builder setTitleIcon(@NonNull Icon titleIcon) {
-            mTitleIcon = titleIcon;
+        public Builder setSubtitleItem(@NonNull SubItemInfo subtitleItem) {
+            mSubtitleItem = subtitleItem;
             return this;
         }
 
         /**
-         * Sets the card subtitle.
+         * Sets the card subtitle's supplemental item.
          */
         @NonNull
-        public Builder setSubtitleText(@NonNull Text subtitleText) {
-            mSubtitleText = subtitleText;
+        public Builder setSubtitleSupplementalItem(@NonNull SubItemInfo subtitleSupplementalItem) {
+            mSubtitleSupplementalItem = subtitleSupplementalItem;
             return this;
         }
 
         /**
-         * Sets the card subtitle icon.
+         * Sets the card supplemental line item.
          */
         @NonNull
-        public Builder setSubtitleIcon(@NonNull Icon subtitleIcon) {
-            mSubtitleIcon = subtitleIcon;
+        public Builder setSupplementalLineItem(@NonNull SubItemInfo supplementalLineItem) {
+            mSupplementalLineItem = supplementalLineItem;
             return this;
         }
 
         /**
-         * Sets the card primary tap action.
+         * Sets the card supplemental alarm item.
          */
         @NonNull
-        public Builder setPrimaryTapAction(@NonNull TapAction primaryTapAction) {
-            mPrimaryTapAction = primaryTapAction;
-            return this;
-        }
-
-        /**
-         * Sets the card primary logging info.
-         */
-        @NonNull
-        public Builder setPrimaryLoggingInfo(@NonNull SubItemLoggingInfo primaryLoggingInfo) {
-            mPrimaryLoggingInfo = primaryLoggingInfo;
-            return this;
-        }
-
-        /**
-         * Sets the supplemental subtitle text.
-         */
-        @NonNull
-        public Builder setSupplementalSubtitleText(
-                @NonNull Text supplementalSubtitleText) {
-            mSupplementalSubtitleText = supplementalSubtitleText;
-            return this;
-        }
-
-        /**
-         * Sets the supplemental subtitle icon.
-         */
-        @NonNull
-        public Builder setSupplementalSubtitleIcon(
-                @NonNull Icon supplementalSubtitleIcon) {
-            mSupplementalSubtitleIcon = supplementalSubtitleIcon;
-            return this;
-        }
-
-        /**
-         * Sets the supplemental subtitle tap action. {@code mPrimaryTapAction} will be used if not
-         * being set.
-         */
-        @NonNull
-        public Builder setSupplementalSubtitleTapAction(
-                @NonNull TapAction supplementalSubtitleTapAction) {
-            mSupplementalSubtitleTapAction = supplementalSubtitleTapAction;
-            return this;
-        }
-
-        /**
-         * Sets the card supplemental title's logging info.
-         */
-        @NonNull
-        public Builder setSupplementalSubtitleLoggingInfo(
-                @NonNull SubItemLoggingInfo supplementalSubtitleLoggingInfo) {
-            mSupplementalSubtitleLoggingInfo = supplementalSubtitleLoggingInfo;
-            return this;
-        }
-
-        /**
-         * Sets the supplemental text.
-         */
-        @NonNull
-        public Builder setSupplementalText(@NonNull Text supplementalText) {
-            mSupplementalText = supplementalText;
-            return this;
-        }
-
-        /**
-         * Sets the supplemental icon.
-         */
-        @NonNull
-        public Builder setSupplementalIcon(@NonNull Icon supplementalIcon) {
-            mSupplementalIcon = supplementalIcon;
-            return this;
-        }
-
-        /**
-         * Sets the supplemental line tap action. {@code mPrimaryTapAction} will be used if not
-         * being set.
-         */
-        @NonNull
-        public Builder setSupplementalTapAction(@NonNull TapAction supplementalTapAction) {
-            mSupplementalTapAction = supplementalTapAction;
-            return this;
-        }
-
-        /**
-         * Sets the card supplemental line's logging info.
-         */
-        @NonNull
-        public Builder setSupplementalLoggingInfo(
-                @NonNull SubItemLoggingInfo supplementalLoggingInfo) {
-            mSupplementalLoggingInfo = supplementalLoggingInfo;
-            return this;
-        }
-
-        /**
-         * Sets the supplemental alarm text.
-         */
-        @NonNull
-        public Builder setSupplementalAlarmText(@NonNull Text supplementalAlarmText) {
-            mSupplementalAlarmText = supplementalAlarmText;
+        public Builder setSupplementalAlarmItem(@NonNull SubItemInfo supplementalAlarmItem) {
+            mSupplementalAlarmItem = supplementalAlarmItem;
             return this;
         }
 
@@ -715,14 +370,197 @@
          */
         @NonNull
         public BaseTemplateData build() {
-            return new BaseTemplateData(mTemplateType, mTitleText, mTitleIcon,
-                    mSubtitleText, mSubtitleIcon, mPrimaryTapAction,
-                    mPrimaryLoggingInfo,
-                    mSupplementalSubtitleText, mSupplementalSubtitleIcon,
-                    mSupplementalSubtitleTapAction, mSupplementalSubtitleLoggingInfo,
-                    mSupplementalText, mSupplementalIcon,
-                    mSupplementalTapAction, mSupplementalLoggingInfo,
-                    mSupplementalAlarmText, mLayoutWeight);
+            return new BaseTemplateData(
+                    mTemplateType,
+                    mPrimaryItem,
+                    mSubtitleItem,
+                    mSubtitleSupplementalItem,
+                    mSupplementalLineItem,
+                    mSupplementalAlarmItem,
+                    mLayoutWeight);
+        }
+    }
+
+    /**
+     * Holds all the rendering and logging info needed for a sub item within the base card.
+     */
+    public static final class SubItemInfo implements Parcelable {
+
+        /** The text information for the subitem, which will be rendered as it's text content. */
+        @Nullable
+        private final Text mText;
+
+        /** The icon for the subitem, which will be rendered as a drawable in front of the text. */
+        @Nullable
+        private final Icon mIcon;
+
+        /** The tap action for the subitem. */
+        @Nullable
+        private final TapAction mTapAction;
+
+        /** The logging info for the subitem. */
+        @Nullable
+        private final SubItemLoggingInfo mLoggingInfo;
+
+        SubItemInfo(@NonNull Parcel in) {
+            mText = in.readTypedObject(Text.CREATOR);
+            mIcon = in.readTypedObject(Icon.CREATOR);
+            mTapAction = in.readTypedObject(TapAction.CREATOR);
+            mLoggingInfo = in.readTypedObject(SubItemLoggingInfo.CREATOR);
+        }
+
+        private SubItemInfo(@Nullable Text text,
+                @Nullable Icon icon,
+                @Nullable TapAction tapAction,
+                @Nullable SubItemLoggingInfo loggingInfo) {
+            mText = text;
+            mIcon = icon;
+            mTapAction = tapAction;
+            mLoggingInfo = loggingInfo;
+        }
+
+        /** Returns the subitem's text. */
+        @Nullable
+        public Text getText() {
+            return mText;
+        }
+
+        /** Returns the subitem's icon. */
+        @Nullable
+        public Icon getIcon() {
+            return mIcon;
+        }
+
+        /** Returns the subitem's tap action. */
+        @Nullable
+        public TapAction getTapAction() {
+            return mTapAction;
+        }
+
+        /** Returns the subitem's logging info. */
+        @Nullable
+        public SubItemLoggingInfo getLoggingInfo() {
+            return mLoggingInfo;
+        }
+
+        /**
+         * @see Parcelable.Creator
+         */
+        @NonNull
+        public static final Creator<SubItemInfo> CREATOR =
+                new Creator<SubItemInfo>() {
+                    @Override
+                    public SubItemInfo createFromParcel(Parcel in) {
+                        return new SubItemInfo(in);
+                    }
+
+                    @Override
+                    public SubItemInfo[] newArray(int size) {
+                        return new SubItemInfo[size];
+                    }
+                };
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel out, int flags) {
+            out.writeTypedObject(mText, flags);
+            out.writeTypedObject(mIcon, flags);
+            out.writeTypedObject(mTapAction, flags);
+            out.writeTypedObject(mLoggingInfo, flags);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof SubItemInfo)) return false;
+            SubItemInfo that = (SubItemInfo) o;
+            return SmartspaceUtils.isEqual(mText, that.mText) && Objects.equals(mIcon,
+                    that.mIcon) && Objects.equals(mTapAction, that.mTapAction)
+                    && Objects.equals(mLoggingInfo, that.mLoggingInfo);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mText, mIcon, mTapAction, mLoggingInfo);
+        }
+
+        @Override
+        public String toString() {
+            return "SubItemInfo{"
+                    + "mText=" + mText
+                    + ", mIcon=" + mIcon
+                    + ", mTapAction=" + mTapAction
+                    + ", mLoggingInfo=" + mLoggingInfo
+                    + '}';
+        }
+
+        /**
+         * A builder for {@link SubItemInfo} object.
+         *
+         * @hide
+         */
+        @SystemApi
+        public static final class Builder {
+
+            private Text mText;
+            private Icon mIcon;
+            private TapAction mTapAction;
+            private SubItemLoggingInfo mLoggingInfo;
+
+            /**
+             * Sets the sub item's text.
+             */
+            @NonNull
+            public Builder setText(@NonNull Text text) {
+                mText = text;
+                return this;
+            }
+
+            /**
+             * Sets the sub item's icon.
+             */
+            @NonNull
+            public Builder setIcon(@NonNull Icon icon) {
+                mIcon = icon;
+                return this;
+            }
+
+            /**
+             * Sets the sub item's tap action.
+             */
+            @NonNull
+            public Builder setTapAction(@NonNull TapAction tapAction) {
+                mTapAction = tapAction;
+                return this;
+            }
+
+            /**
+             * Sets the sub item's logging info.
+             */
+            @NonNull
+            public Builder setLoggingInfo(@NonNull SubItemLoggingInfo loggingInfo) {
+                mLoggingInfo = loggingInfo;
+                return this;
+            }
+
+            /**
+             * Builds a new {@link SubItemInfo} instance.
+             *
+             * @throws IllegalStateException if all the data field is empty.
+             */
+            @NonNull
+            public SubItemInfo build() {
+                if (SmartspaceUtils.isEmpty(mText) && mIcon == null && mTapAction == null
+                        && mLoggingInfo == null) {
+                    throw new IllegalStateException("SubItem data is empty");
+                }
+
+                return new SubItemInfo(mText, mIcon, mTapAction, mLoggingInfo);
+            }
         }
     }
 
@@ -735,27 +573,45 @@
         /** A unique instance id for the sub item. */
         private final int mInstanceId;
 
-        /** The feature type for this sub item. */
+        /**
+         * {@link FeatureType} indicating the feature type of this subitem.
+         *
+         * @see FeatureType
+         */
+        @FeatureType
         private final int mFeatureType;
 
+        /** The data source's package name for this sub item. */
+        @Nullable
+        private final CharSequence mPackageName;
+
         SubItemLoggingInfo(@NonNull Parcel in) {
             mInstanceId = in.readInt();
             mFeatureType = in.readInt();
+            mPackageName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         }
 
-        private SubItemLoggingInfo(int instanceId, int featureType) {
+        private SubItemLoggingInfo(int instanceId, @FeatureType int featureType,
+                @Nullable CharSequence packageName) {
             mInstanceId = instanceId;
             mFeatureType = featureType;
+            mPackageName = packageName;
         }
 
         public int getInstanceId() {
             return mInstanceId;
         }
 
+        @FeatureType
         public int getFeatureType() {
             return mFeatureType;
         }
 
+        @Nullable
+        public CharSequence getPackageName() {
+            return mPackageName;
+        }
+
         /**
          * @see Parcelable.Creator
          */
@@ -782,6 +638,7 @@
         public void writeToParcel(@NonNull Parcel out, int flags) {
             out.writeInt(mInstanceId);
             out.writeInt(mFeatureType);
+            TextUtils.writeToParcel(mPackageName, out, flags);
         }
 
         @Override
@@ -789,12 +646,13 @@
             if (this == o) return true;
             if (!(o instanceof SubItemLoggingInfo)) return false;
             SubItemLoggingInfo that = (SubItemLoggingInfo) o;
-            return mInstanceId == that.mInstanceId && mFeatureType == that.mFeatureType;
+            return mInstanceId == that.mInstanceId && mFeatureType == that.mFeatureType
+                    && SmartspaceUtils.isEqual(mPackageName, that.mPackageName);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(mInstanceId, mFeatureType);
+            return Objects.hash(mInstanceId, mFeatureType, mPackageName);
         }
 
         @Override
@@ -802,6 +660,7 @@
             return "SubItemLoggingInfo{"
                     + "mInstanceId=" + mInstanceId
                     + ", mFeatureType=" + mFeatureType
+                    + ", mPackageName=" + mPackageName
                     + '}';
         }
 
@@ -815,22 +674,32 @@
 
             private final int mInstanceId;
             private final int mFeatureType;
+            private CharSequence mPackageName;
 
             /**
              * A builder for {@link SubItemLoggingInfo}.
              *
              * @param instanceId  A unique instance id for the sub item
-             * @param featureType The feature type for this sub item
+             * @param featureType The feature type id for this sub item
              */
-            public Builder(int instanceId, int featureType) {
+            public Builder(int instanceId, @FeatureType int featureType) {
                 mInstanceId = instanceId;
                 mFeatureType = featureType;
             }
 
+            /**
+             * Sets the sub item's data source package name.
+             */
+            @NonNull
+            public Builder setPackageName(@NonNull CharSequence packageName) {
+                mPackageName = packageName;
+                return this;
+            }
+
             /** Builds a new {@link SubItemLoggingInfo} instance. */
             @NonNull
             public SubItemLoggingInfo build() {
-                return new SubItemLoggingInfo(mInstanceId, mFeatureType);
+                return new SubItemLoggingInfo(mInstanceId, mFeatureType, mPackageName);
             }
         }
     }
diff --git a/core/java/android/app/smartspace/uitemplatedata/CarouselTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/CarouselTemplateData.java
index fbdb7be..c1378f1 100644
--- a/core/java/android/app/smartspace/uitemplatedata/CarouselTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/CarouselTemplateData.java
@@ -56,31 +56,16 @@
     }
 
     private CarouselTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable Text titleText,
-            @Nullable Icon titleIcon,
-            @Nullable Text subtitleText,
-            @Nullable Icon subtitleIcon,
-            @Nullable TapAction primaryTapAction,
-            @Nullable SubItemLoggingInfo primaryLoggingInfo,
-            @Nullable Text supplementalSubtitleText,
-            @Nullable Icon supplementalSubtitleIcon,
-            @Nullable TapAction supplementalSubtitleTapAction,
-            @Nullable SubItemLoggingInfo supplementalSubtitleLoggingInfo,
-            @Nullable Text supplementalText,
-            @Nullable Icon supplementalIcon,
-            @Nullable TapAction supplementalTapAction,
-            @Nullable SubItemLoggingInfo supplementalLoggingInfo,
-            @Nullable Text supplementalAlarmText,
+            @Nullable SubItemInfo primaryItem,
+            @Nullable SubItemInfo subtitleItem,
+            @Nullable SubItemInfo subtitleSupplementalItem,
+            @Nullable SubItemInfo supplementalLineItem,
+            @Nullable SubItemInfo supplementalAlarmItem,
             int layoutWeight,
             @NonNull List<CarouselItem> carouselItems,
             @Nullable TapAction carouselAction) {
-        super(templateType, titleText, titleIcon, subtitleText, subtitleIcon,
-                primaryTapAction, primaryLoggingInfo,
-                supplementalSubtitleText, supplementalSubtitleIcon,
-                supplementalSubtitleTapAction, supplementalSubtitleLoggingInfo,
-                supplementalText, supplementalIcon,
-                supplementalTapAction, supplementalLoggingInfo,
-                supplementalAlarmText, layoutWeight);
+        super(templateType, primaryItem, subtitleItem, subtitleSupplementalItem,
+                supplementalLineItem, supplementalAlarmItem, layoutWeight);
 
         mCarouselItems = carouselItems;
         mCarouselAction = carouselAction;
@@ -190,14 +175,9 @@
                 throw new IllegalStateException("Carousel data is empty");
             }
 
-            return new CarouselTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(),
-                    getPrimaryTapAction(), getPrimaryLoggingInfo(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalSubtitleLoggingInfo(),
-                    getSupplementalText(), getSupplementalIcon(),
-                    getSupplementalTapAction(), getSupplementalLoggingInfo(),
-                    getSupplementalAlarmText(), getLayoutWeight(),
+            return new CarouselTemplateData(getTemplateType(), getPrimaryItem(),
+                    getSubtitleItem(), getSubtitleSupplemtnalItem(),
+                    getSupplementalLineItem(), getSupplementalAlarmItem(), getLayoutWeight(),
                     mCarouselItems, mCarouselAction);
         }
     }
diff --git a/core/java/android/app/smartspace/uitemplatedata/CombinedCardsTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/CombinedCardsTemplateData.java
index 1d13066..836f414 100644
--- a/core/java/android/app/smartspace/uitemplatedata/CombinedCardsTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/CombinedCardsTemplateData.java
@@ -51,30 +51,16 @@
     }
 
     private CombinedCardsTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable Text titleText,
-            @Nullable Icon titleIcon,
-            @Nullable Text subtitleText,
-            @Nullable Icon subtitleIcon,
-            @Nullable TapAction primaryTapAction,
-            @Nullable SubItemLoggingInfo primaryLoggingInfo,
-            @Nullable Text supplementalSubtitleText,
-            @Nullable Icon supplementalSubtitleIcon,
-            @Nullable TapAction supplementalSubtitleTapAction,
-            @Nullable SubItemLoggingInfo supplementalSubtitleLoggingInfo,
-            @Nullable Text supplementalText,
-            @Nullable Icon supplementalIcon,
-            @Nullable TapAction supplementalTapAction,
-            @Nullable SubItemLoggingInfo supplementalLoggingInfo,
-            @Nullable Text supplementalAlarmText,
+            @Nullable SubItemInfo primaryItem,
+            @Nullable SubItemInfo subtitleItem,
+            @Nullable SubItemInfo subtitleSupplementalItem,
+            @Nullable SubItemInfo supplementalLineItem,
+            @Nullable SubItemInfo supplementalAlarmItem,
             int layoutWeight,
             @NonNull List<BaseTemplateData> combinedCardDataList) {
-        super(templateType, titleText, titleIcon, subtitleText, subtitleIcon,
-                primaryTapAction, primaryLoggingInfo,
-                supplementalSubtitleText, supplementalSubtitleIcon,
-                supplementalSubtitleTapAction, supplementalSubtitleLoggingInfo,
-                supplementalText, supplementalIcon,
-                supplementalTapAction, supplementalLoggingInfo,
-                supplementalAlarmText, layoutWeight);
+        super(templateType, primaryItem, subtitleItem, subtitleSupplementalItem,
+                supplementalLineItem, supplementalAlarmItem, layoutWeight);
+
         mCombinedCardDataList = combinedCardDataList;
     }
 
@@ -161,14 +147,9 @@
             if (mCombinedCardDataList == null) {
                 throw new IllegalStateException("Please assign a value to all @NonNull args.");
             }
-            return new CombinedCardsTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(),
-                    getPrimaryTapAction(), getPrimaryLoggingInfo(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalSubtitleLoggingInfo(),
-                    getSupplementalText(), getSupplementalIcon(),
-                    getSupplementalTapAction(), getSupplementalLoggingInfo(),
-                    getSupplementalAlarmText(), getLayoutWeight(),
+            return new CombinedCardsTemplateData(getTemplateType(), getPrimaryItem(),
+                    getSubtitleItem(), getSubtitleSupplemtnalItem(),
+                    getSupplementalLineItem(), getSupplementalAlarmItem(), getLayoutWeight(),
                     mCombinedCardDataList);
         }
     }
diff --git a/core/java/android/app/smartspace/uitemplatedata/HeadToHeadTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/HeadToHeadTemplateData.java
index 19177df..29df018 100644
--- a/core/java/android/app/smartspace/uitemplatedata/HeadToHeadTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/HeadToHeadTemplateData.java
@@ -66,21 +66,11 @@
     }
 
     private HeadToHeadTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable Text titleText,
-            @Nullable Icon titleIcon,
-            @Nullable Text subtitleText,
-            @Nullable Icon subtitleIcon,
-            @Nullable TapAction primaryTapAction,
-            @Nullable SubItemLoggingInfo primaryLoggingInfo,
-            @Nullable Text supplementalSubtitleText,
-            @Nullable Icon supplementalSubtitleIcon,
-            @Nullable TapAction supplementalSubtitleTapAction,
-            @Nullable SubItemLoggingInfo supplementalSubtitleLoggingInfo,
-            @Nullable Text supplementalText,
-            @Nullable Icon supplementalIcon,
-            @Nullable TapAction supplementalTapAction,
-            @Nullable SubItemLoggingInfo supplementalLoggingInfo,
-            @Nullable Text supplementalAlarmText,
+            @Nullable SubItemInfo primaryItem,
+            @Nullable SubItemInfo subtitleItem,
+            @Nullable SubItemInfo subtitleSupplementalItem,
+            @Nullable SubItemInfo supplementalLineItem,
+            @Nullable SubItemInfo supplementalAlarmItem,
             int layoutWeight,
             @Nullable Text headToHeadTitle,
             @Nullable Icon headToHeadFirstCompetitorIcon,
@@ -88,13 +78,8 @@
             @Nullable Text headToHeadFirstCompetitorText,
             @Nullable Text headToHeadSecondCompetitorText,
             @Nullable TapAction headToHeadAction) {
-        super(templateType, titleText, titleIcon, subtitleText, subtitleIcon,
-                primaryTapAction, primaryLoggingInfo,
-                supplementalSubtitleText, supplementalSubtitleIcon,
-                supplementalSubtitleTapAction, supplementalSubtitleLoggingInfo,
-                supplementalText, supplementalIcon,
-                supplementalTapAction, supplementalLoggingInfo,
-                supplementalAlarmText, layoutWeight);
+        super(templateType, primaryItem, subtitleItem, subtitleSupplementalItem,
+                supplementalLineItem, supplementalAlarmItem, layoutWeight);
 
         mHeadToHeadTitle = headToHeadTitle;
         mHeadToHeadFirstCompetitorIcon = headToHeadFirstCompetitorIcon;
@@ -296,14 +281,9 @@
          */
         @NonNull
         public HeadToHeadTemplateData build() {
-            return new HeadToHeadTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(),
-                    getPrimaryTapAction(), getPrimaryLoggingInfo(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalSubtitleLoggingInfo(),
-                    getSupplementalText(), getSupplementalIcon(),
-                    getSupplementalTapAction(), getSupplementalLoggingInfo(),
-                    getSupplementalAlarmText(), getLayoutWeight(),
+            return new HeadToHeadTemplateData(getTemplateType(), getPrimaryItem(),
+                    getSubtitleItem(), getSubtitleSupplemtnalItem(),
+                    getSupplementalLineItem(), getSupplementalAlarmItem(), getLayoutWeight(),
                     mHeadToHeadTitle,
                     mHeadToHeadFirstCompetitorIcon,
                     mHeadToHeadSecondCompetitorIcon, mHeadToHeadFirstCompetitorText,
diff --git a/core/java/android/app/smartspace/uitemplatedata/SubCardTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SubCardTemplateData.java
index 48af9c1..b87e5b3 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SubCardTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/SubCardTemplateData.java
@@ -59,32 +59,17 @@
     }
 
     private SubCardTemplateData(int templateType,
-            @Nullable Text titleText,
-            @Nullable Icon titleIcon,
-            @Nullable Text subtitleText,
-            @Nullable Icon subtitleIcon,
-            @Nullable TapAction primaryTapAction,
-            @Nullable SubItemLoggingInfo primaryLoggingInfo,
-            @Nullable Text supplementalSubtitleText,
-            @Nullable Icon supplementalSubtitleIcon,
-            @Nullable TapAction supplementalSubtitleTapAction,
-            @Nullable SubItemLoggingInfo supplementalSubtitleLoggingInfo,
-            @Nullable Text supplementalText,
-            @Nullable Icon supplementalIcon,
-            @Nullable TapAction supplementalTapAction,
-            @Nullable SubItemLoggingInfo supplementalLoggingInfo,
-            @Nullable Text supplementalAlarmText,
+            @Nullable SubItemInfo primaryItem,
+            @Nullable SubItemInfo subtitleItem,
+            @Nullable SubItemInfo subtitleSupplementalItem,
+            @Nullable SubItemInfo supplementalLineItem,
+            @Nullable SubItemInfo supplementalAlarmItem,
             int layoutWeight,
             @NonNull Icon subCardIcon,
             @Nullable Text subCardText,
             @Nullable TapAction subCardAction) {
-        super(templateType, titleText, titleIcon, subtitleText, subtitleIcon,
-                primaryTapAction, primaryLoggingInfo,
-                supplementalSubtitleText, supplementalSubtitleIcon,
-                supplementalSubtitleTapAction, supplementalSubtitleLoggingInfo,
-                supplementalText, supplementalIcon,
-                supplementalTapAction, supplementalLoggingInfo,
-                supplementalAlarmText, layoutWeight);
+        super(templateType, primaryItem, subtitleItem, subtitleSupplementalItem,
+                supplementalLineItem, supplementalAlarmItem, layoutWeight);
 
         mSubCardIcon = subCardIcon;
         mSubCardText = subCardText;
@@ -207,14 +192,9 @@
          */
         @NonNull
         public SubCardTemplateData build() {
-            return new SubCardTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(),
-                    getPrimaryTapAction(), getPrimaryLoggingInfo(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalSubtitleLoggingInfo(),
-                    getSupplementalText(), getSupplementalIcon(),
-                    getSupplementalTapAction(), getSupplementalLoggingInfo(),
-                    getSupplementalAlarmText(), getLayoutWeight(),
+            return new SubCardTemplateData(getTemplateType(), getPrimaryItem(),
+                    getSubtitleItem(), getSubtitleSupplemtnalItem(),
+                    getSupplementalLineItem(), getSupplementalAlarmItem(), getLayoutWeight(),
                     mSubCardIcon,
                     mSubCardText,
                     mSubCardAction);
diff --git a/core/java/android/app/smartspace/uitemplatedata/SubImageTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SubImageTemplateData.java
index 38692cd..430d79c 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SubImageTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/SubImageTemplateData.java
@@ -60,32 +60,17 @@
     }
 
     private SubImageTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable Text titleText,
-            @Nullable Icon titleIcon,
-            @Nullable Text subtitleText,
-            @Nullable Icon subtitleIcon,
-            @Nullable TapAction primaryTapAction,
-            @Nullable SubItemLoggingInfo primaryLoggingInfo,
-            @Nullable Text supplementalSubtitleText,
-            @Nullable Icon supplementalSubtitleIcon,
-            @Nullable TapAction supplementalSubtitleTapAction,
-            @Nullable SubItemLoggingInfo supplementalSubtitleLoggingInfo,
-            @Nullable Text supplementalText,
-            @Nullable Icon supplementalIcon,
-            @Nullable TapAction supplementalTapAction,
-            @Nullable SubItemLoggingInfo supplementalLoggingInfo,
-            @Nullable Text supplementalAlarmText,
+            @Nullable SubItemInfo primaryItem,
+            @Nullable SubItemInfo subtitleItem,
+            @Nullable SubItemInfo subtitleSupplementalItem,
+            @Nullable SubItemInfo supplementalLineItem,
+            @Nullable SubItemInfo supplementalAlarmItem,
             int layoutWeight,
             @NonNull List<Text> subImageTexts,
             @NonNull List<Icon> subImages,
             @Nullable TapAction subImageAction) {
-        super(templateType, titleText, titleIcon, subtitleText, subtitleIcon,
-                primaryTapAction, primaryLoggingInfo,
-                supplementalSubtitleText, supplementalSubtitleIcon,
-                supplementalSubtitleTapAction, supplementalSubtitleLoggingInfo,
-                supplementalText, supplementalIcon,
-                supplementalTapAction, supplementalLoggingInfo,
-                supplementalAlarmText, layoutWeight);
+        super(templateType, primaryItem, subtitleItem, subtitleSupplementalItem,
+                supplementalLineItem, supplementalAlarmItem, layoutWeight);
 
         mSubImageTexts = subImageTexts;
         mSubImages = subImages;
@@ -204,14 +189,9 @@
          */
         @NonNull
         public SubImageTemplateData build() {
-            return new SubImageTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(),
-                    getPrimaryTapAction(), getPrimaryLoggingInfo(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalSubtitleLoggingInfo(),
-                    getSupplementalText(), getSupplementalIcon(),
-                    getSupplementalTapAction(), getSupplementalLoggingInfo(),
-                    getSupplementalAlarmText(), getLayoutWeight(),
+            return new SubImageTemplateData(getTemplateType(), getPrimaryItem(),
+                    getSubtitleItem(), getSubtitleSupplemtnalItem(),
+                    getSupplementalLineItem(), getSupplementalAlarmItem(), getLayoutWeight(),
                     mSubImageTexts,
                     mSubImages,
                     mSubImageAction);
diff --git a/core/java/android/app/smartspace/uitemplatedata/SubListTemplateData.java b/core/java/android/app/smartspace/uitemplatedata/SubListTemplateData.java
index b1535f1..ae43fc4 100644
--- a/core/java/android/app/smartspace/uitemplatedata/SubListTemplateData.java
+++ b/core/java/android/app/smartspace/uitemplatedata/SubListTemplateData.java
@@ -59,32 +59,17 @@
     }
 
     private SubListTemplateData(@SmartspaceTarget.UiTemplateType int templateType,
-            @Nullable Text titleText,
-            @Nullable Icon titleIcon,
-            @Nullable Text subtitleText,
-            @Nullable Icon subtitleIcon,
-            @Nullable TapAction primaryTapAction,
-            @Nullable SubItemLoggingInfo primaryLoggingInfo,
-            @Nullable Text supplementalSubtitleText,
-            @Nullable Icon supplementalSubtitleIcon,
-            @Nullable TapAction supplementalSubtitleTapAction,
-            @Nullable SubItemLoggingInfo supplementalSubtitleLoggingInfo,
-            @Nullable Text supplementalText,
-            @Nullable Icon supplementalIcon,
-            @Nullable TapAction supplementalTapAction,
-            @Nullable SubItemLoggingInfo supplementalLoggingInfo,
-            @Nullable Text supplementalAlarmText,
+            @Nullable SubItemInfo primaryItem,
+            @Nullable SubItemInfo subtitleItem,
+            @Nullable SubItemInfo subtitleSupplementalItem,
+            @Nullable SubItemInfo supplementalLineItem,
+            @Nullable SubItemInfo supplementalAlarmItem,
             int layoutWeight,
             @Nullable Icon subListIcon,
             @NonNull List<Text> subListTexts,
             @Nullable TapAction subListAction) {
-        super(templateType, titleText, titleIcon, subtitleText, subtitleIcon,
-                primaryTapAction, primaryLoggingInfo,
-                supplementalSubtitleText, supplementalSubtitleIcon,
-                supplementalSubtitleTapAction, supplementalSubtitleLoggingInfo,
-                supplementalText, supplementalIcon,
-                supplementalTapAction, supplementalLoggingInfo,
-                supplementalAlarmText, layoutWeight);
+        super(templateType, primaryItem, subtitleItem, subtitleSupplementalItem,
+                supplementalLineItem, supplementalAlarmItem, layoutWeight);
 
         mSubListIcon = subListIcon;
         mSubListTexts = subListTexts;
@@ -207,14 +192,9 @@
          */
         @NonNull
         public SubListTemplateData build() {
-            return new SubListTemplateData(getTemplateType(), getTitleText(),
-                    getTitleIcon(), getSubtitleText(), getSubtitleIcon(),
-                    getPrimaryTapAction(), getPrimaryLoggingInfo(),
-                    getSupplementalSubtitleText(), getSupplementalSubtitleIcon(),
-                    getSupplementalSubtitleTapAction(), getSupplementalSubtitleLoggingInfo(),
-                    getSupplementalText(), getSupplementalIcon(),
-                    getSupplementalTapAction(), getSupplementalLoggingInfo(),
-                    getSupplementalAlarmText(), getLayoutWeight(),
+            return new SubListTemplateData(getTemplateType(), getPrimaryItem(),
+                    getSubtitleItem(), getSubtitleSupplemtnalItem(),
+                    getSupplementalLineItem(), getSupplementalAlarmItem(), getLayoutWeight(),
                     mSubListIcon,
                     mSubListTexts,
                     mSubListAction);
diff --git a/core/java/android/app/smartspace/uitemplatedata/Text.java b/core/java/android/app/smartspace/uitemplatedata/Text.java
index e1afce7..cb2f432 100644
--- a/core/java/android/app/smartspace/uitemplatedata/Text.java
+++ b/core/java/android/app/smartspace/uitemplatedata/Text.java
@@ -109,6 +109,15 @@
         out.writeInt(mMaxLines);
     }
 
+    @Override
+    public String toString() {
+        return "Text{"
+                + "mText=" + mText
+                + ", mTruncateAtType=" + mTruncateAtType
+                + ", mMaxLines=" + mMaxLines
+                + '}';
+    }
+
     /**
      * A builder for {@link Text} object.
      *
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/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index a430714..2a2a9c6 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -53,6 +53,7 @@
     void setAppStandbyBucket(String packageName, int bucket, int userId);
     ParceledListSlice getAppStandbyBuckets(String callingPackage, int userId);
     void setAppStandbyBuckets(in ParceledListSlice appBuckets, int userId);
+    int getAppMinStandbyBucket(String packageName, String callingPackage, int userId);
     void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime, int userId);
     void setEstimatedLaunchTimes(in ParceledListSlice appLaunchTimes, int userId);
     void registerAppUsageObserver(int observerId, in String[] packages, long timeLimitMs,
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index d7152b3..3a335f9 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -787,6 +787,23 @@
     }
 
     /**
+     * Return the lowest bucket this app can ever enter.
+     *
+     * @param packageName the package for which to fetch the minimum allowed standby bucket.
+     * {@hide}
+     */
+    @StandbyBuckets
+    @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
+    public int getAppMinStandbyBucket(String packageName) {
+        try {
+            return mService.getAppMinStandbyBucket(packageName, mContext.getOpPackageName(),
+                    mContext.getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Changes an app's estimated launch time. An app is considered "launched" when a user opens
      * one of its {@link android.app.Activity Activities}. The provided time is persisted across
      * reboots and is used unless 1) the time is more than a week in the future and the platform
diff --git a/core/java/android/companion/virtual/IVirtualDeviceManager.aidl b/core/java/android/companion/virtual/IVirtualDeviceManager.aidl
index b7f826a..a1640ee 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceManager.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceManager.aidl
@@ -37,6 +37,7 @@
      *   CDM. Virtual devices must have a corresponding association with CDM in order to be created.
      * @param params The parameters for creating this virtual device. See {@link
      *   VirtualDeviceManager.VirtualDeviceParams}.
+     * @param activityListener The listener to listen for activity changes in a virtual device.
      */
     IVirtualDevice createVirtualDevice(
             in IBinder token, String packageName, int associationId,
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 99ce147..a1983ca 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -48,7 +48,6 @@
 import android.util.ArrayMap;
 import android.view.Surface;
 
-import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -223,7 +222,8 @@
          * {@link DisplayManager#VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY
          * VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY}.
          * @param executor The executor on which {@code callback} will be invoked. This is ignored
-         * if {@code callback} is {@code null}.
+         * if {@code callback} is {@code null}. If {@code callback} is specified, this executor must
+         * not be null.
          * @param callback Callback to call when the state of the {@link VirtualDisplay} changes
          * @return The newly created virtual display, or {@code null} if the application could
          * not create the virtual display.
@@ -237,7 +237,7 @@
                 @IntRange(from = 1) int densityDpi,
                 @Nullable Surface surface,
                 @VirtualDisplayFlag int flags,
-                @NonNull @CallbackExecutor Executor executor,
+                @Nullable @CallbackExecutor Executor executor,
                 @Nullable VirtualDisplay.Callback callback) {
             // TODO(b/205343547): Handle display groups properly instead of creating a new display
             //  group for every new virtual display created using this API.
@@ -253,7 +253,7 @@
                             .setFlags(getVirtualDisplayFlags(flags))
                             .build(),
                     callback,
-                    Objects.requireNonNull(executor));
+                    executor);
         }
 
         /**
@@ -278,8 +278,8 @@
          *
          * @param display the display that the events inputted through this device should target
          * @param inputDeviceName the name to call this input device
-         * @param vendorId the vendor id, as defined by uinput's uinput_setup struct (PCI vendor id)
-         * @param productId the product id, as defined by uinput's uinput_setup struct
+         * @param vendorId the PCI vendor id
+         * @param productId the product id, as defined by the vendor
          */
         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
         @NonNull
@@ -304,8 +304,8 @@
          *
          * @param display the display that the events inputted through this device should target
          * @param inputDeviceName the name to call this input device
-         * @param vendorId the vendor id, as defined by uinput's uinput_setup struct (PCI vendor id)
-         * @param productId the product id, as defined by uinput's uinput_setup struct
+         * @param vendorId the PCI vendor id
+         * @param productId the product id, as defined by the vendor
          */
         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
         @NonNull
@@ -330,8 +330,8 @@
          *
          * @param display the display that the events inputted through this device should target
          * @param inputDeviceName the name to call this input device
-         * @param vendorId the vendor id, as defined by uinput's uinput_setup struct (PCI vendor id)
-         * @param productId the product id, as defined by uinput's uinput_setup struct
+         * @param vendorId the PCI vendor id
+         * @param productId the product id, as defined by the vendor
          */
         @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE)
         @NonNull
@@ -425,23 +425,12 @@
          * Adds an activity listener to listen for events such as top activity change or virtual
          * display task stack became empty.
          *
+         * @param executor The executor where the listener is executed on.
          * @param listener The listener to add.
          * @see #removeActivityListener(ActivityListener)
          */
-        public void addActivityListener(@NonNull ActivityListener listener) {
-            addActivityListener(listener, mContext.getMainExecutor());
-        }
-
-        /**
-         * Adds an activity listener to listen for events such as top activity change or virtual
-         * display task stack became empty.
-         *
-         * @param listener The listener to add.
-         * @param executor The executor where the callback is executed on.
-         * @see #removeActivityListener(ActivityListener)
-         */
         public void addActivityListener(
-                @NonNull ActivityListener listener, @NonNull Executor executor) {
+                @CallbackExecutor @NonNull Executor executor, @NonNull ActivityListener listener) {
             mActivityListeners.put(listener, new ActivityListenerDelegate(listener, executor));
         }
 
diff --git a/core/java/android/companion/virtual/VirtualDeviceParams.java b/core/java/android/companion/virtual/VirtualDeviceParams.java
index 45d0ad5..41b1a1f 100644
--- a/core/java/android/companion/virtual/VirtualDeviceParams.java
+++ b/core/java/android/companion/virtual/VirtualDeviceParams.java
@@ -20,9 +20,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.os.Parcel;
@@ -64,20 +62,43 @@
      */
     public static final int LOCK_STATE_ALWAYS_UNLOCKED = 1;
 
+    /** @hide */
+    @IntDef(prefix = "ACTIVITY_POLICY_",
+            value = {ACTIVITY_POLICY_DEFAULT_ALLOWED, ACTIVITY_POLICY_DEFAULT_BLOCKED})
+    @Retention(RetentionPolicy.SOURCE)
+    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+    public @interface ActivityPolicy {}
+
+    /**
+     * Indicates that activities are allowed by default on this virtual device, unless they are
+     * explicitly blocked by {@link Builder#setBlockedActivities}.
+     */
+    public static final int ACTIVITY_POLICY_DEFAULT_ALLOWED = 0;
+
+    /**
+     * Indicates that activities are blocked by default on this virtual device, unless they are
+     * allowed by {@link Builder#setAllowedActivities}.
+     */
+    public static final int ACTIVITY_POLICY_DEFAULT_BLOCKED = 1;
+
     private final int mLockState;
     private final ArraySet<UserHandle> mUsersWithMatchingAccounts;
-    @Nullable private final ArraySet<ComponentName> mAllowedActivities;
-    @Nullable private final ArraySet<ComponentName> mBlockedActivities;
+    @NonNull private final ArraySet<ComponentName> mAllowedActivities;
+    @NonNull private final ArraySet<ComponentName> mBlockedActivities;
+    @ActivityPolicy
+    private final int mDefaultActivityPolicy;
 
     private VirtualDeviceParams(
             @LockState int lockState,
             @NonNull Set<UserHandle> usersWithMatchingAccounts,
-            @Nullable Set<ComponentName> allowedActivities,
-            @Nullable Set<ComponentName> blockedActivities) {
+            @NonNull Set<ComponentName> allowedActivities,
+            @NonNull Set<ComponentName> blockedActivities,
+            @ActivityPolicy int defaultActivityPolicy) {
         mLockState = lockState;
         mUsersWithMatchingAccounts = new ArraySet<>(usersWithMatchingAccounts);
         mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities);
         mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities);
+        mDefaultActivityPolicy = defaultActivityPolicy;
     }
 
     @SuppressWarnings("unchecked")
@@ -86,6 +107,7 @@
         mUsersWithMatchingAccounts = (ArraySet<UserHandle>) parcel.readArraySet(null);
         mAllowedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null);
         mBlockedActivities = (ArraySet<ComponentName>) parcel.readArraySet(null);
+        mDefaultActivityPolicy = parcel.readInt();
     }
 
     /**
@@ -113,12 +135,10 @@
      *
      * @see Builder#setAllowedActivities(Set)
      */
-    // Null and empty have different semantics - Null allows all activities to be streamed
-    @SuppressLint("NullableCollection")
-    @Nullable
+    @NonNull
     public Set<ComponentName> getAllowedActivities() {
         if (mAllowedActivities == null) {
-            return null;
+            return Collections.emptySet();
         }
         return Collections.unmodifiableSet(mAllowedActivities);
     }
@@ -129,16 +149,27 @@
      *
      * @see Builder#setBlockedActivities(Set)
      */
-    // Allowing null to enforce that at most one of allowed / blocked activities can be non-null
-    @SuppressLint("NullableCollection")
-    @Nullable
+    @NonNull
     public Set<ComponentName> getBlockedActivities() {
         if (mBlockedActivities == null) {
-            return null;
+            return Collections.emptySet();
         }
         return Collections.unmodifiableSet(mBlockedActivities);
     }
 
+    /**
+     * Returns {@link #ACTIVITY_POLICY_DEFAULT_ALLOWED} if activities are allowed to launch on this
+     * virtual device by default, or {@link #ACTIVITY_POLICY_DEFAULT_BLOCKED} if activities must be
+     * allowed by {@link Builder#setAllowedActivities} to launch here.
+     *
+     * @see Builder#setBlockedActivities
+     * @see Builder#setAllowedActivities
+     */
+    @ActivityPolicy
+    public int getDefaultActivityPolicy() {
+        return mDefaultActivityPolicy;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -150,6 +181,7 @@
         dest.writeArraySet(mUsersWithMatchingAccounts);
         dest.writeArraySet(mAllowedActivities);
         dest.writeArraySet(mBlockedActivities);
+        dest.writeInt(mDefaultActivityPolicy);
     }
 
     @Override
@@ -164,12 +196,15 @@
         return mLockState == that.mLockState
                 && mUsersWithMatchingAccounts.equals(that.mUsersWithMatchingAccounts)
                 && Objects.equals(mAllowedActivities, that.mAllowedActivities)
-                && Objects.equals(mBlockedActivities, that.mBlockedActivities);
+                && Objects.equals(mBlockedActivities, that.mBlockedActivities)
+                && mDefaultActivityPolicy == that.mDefaultActivityPolicy;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mLockState, mUsersWithMatchingAccounts);
+        return Objects.hash(
+                mLockState, mUsersWithMatchingAccounts, mAllowedActivities, mBlockedActivities,
+                mDefaultActivityPolicy);
     }
 
     @Override
@@ -180,6 +215,7 @@
                 + " mUsersWithMatchingAccounts=" + mUsersWithMatchingAccounts
                 + " mAllowedActivities=" + mAllowedActivities
                 + " mBlockedActivities=" + mBlockedActivities
+                + " mDefaultActivityPolicy=" + mDefaultActivityPolicy
                 + ")";
     }
 
@@ -202,8 +238,11 @@
 
         private @LockState int mLockState = LOCK_STATE_DEFAULT;
         private Set<UserHandle> mUsersWithMatchingAccounts;
-        @Nullable private Set<ComponentName> mBlockedActivities;
-        @Nullable private Set<ComponentName> mAllowedActivities;
+        @NonNull private Set<ComponentName> mBlockedActivities = Collections.emptySet();
+        @NonNull private Set<ComponentName> mAllowedActivities = Collections.emptySet();
+        @ActivityPolicy
+        private int mDefaultActivityPolicy = ACTIVITY_POLICY_DEFAULT_ALLOWED;
+        private boolean mDefaultActivityPolicyConfigured = false;
 
         /**
          * Sets the lock state of the device. The permission {@code ADD_ALWAYS_UNLOCKED_DISPLAY}
@@ -248,53 +287,53 @@
         }
 
         /**
-         * Sets the activities allowed to be launched in the virtual device. If
-         * {@code allowedActivities} is non-null, all activities other than the ones in the set will
-         * be blocked from launching.
+         * Sets the activities allowed to be launched in the virtual device. Calling this method
+         * will cause {@link #getDefaultActivityPolicy()} to be
+         * {@link #ACTIVITY_POLICY_DEFAULT_BLOCKED}, meaning activities not in
+         * {@code allowedActivities} will be blocked from launching here.
          *
-         * <p>{@code allowedActivities} and the set in {@link #setBlockedActivities(Set)} cannot
-         * both be non-null at the same time.
+         * <p>This method must not be called if {@link #setBlockedActivities(Set)} has been called.
          *
-         * @throws IllegalArgumentException if {@link #setBlockedActivities(Set)} has been set to a
-         *   non-null value.
+         * @throws IllegalArgumentException if {@link #setBlockedActivities(Set)} has been called.
          *
          * @param allowedActivities A set of activity {@link ComponentName} allowed to be launched
          *   in the virtual device.
          */
-        // Null and empty have different semantics - Null allows all activities to be streamed
-        @SuppressLint("NullableCollection")
         @NonNull
-        public Builder setAllowedActivities(@Nullable Set<ComponentName> allowedActivities) {
-            if (mBlockedActivities != null && allowedActivities != null) {
+        public Builder setAllowedActivities(@NonNull Set<ComponentName> allowedActivities) {
+            if (mDefaultActivityPolicyConfigured
+                    && mDefaultActivityPolicy != ACTIVITY_POLICY_DEFAULT_BLOCKED) {
                 throw new IllegalArgumentException(
                         "Allowed activities and Blocked activities cannot both be set.");
             }
+            mDefaultActivityPolicy = ACTIVITY_POLICY_DEFAULT_BLOCKED;
+            mDefaultActivityPolicyConfigured = true;
             mAllowedActivities = allowedActivities;
             return this;
         }
 
         /**
-         * Sets the activities blocked from launching in the virtual device. If the {@code
-         * blockedActivities} is non-null, activities in the set are blocked from launching in the
-         * virtual device.
+         * Sets the activities blocked from launching in the virtual device. Calling this method
+         * will cause {@link #getDefaultActivityPolicy()} to be
+         * {@link #ACTIVITY_POLICY_DEFAULT_ALLOWED}, meaning activities are allowed to launch here
+         * unless they are in {@code blockedActivities}.
          *
-         * {@code blockedActivities} and the set in {@link #setAllowedActivities(Set)} cannot both
-         * be non-null at the same time.
+         * <p>This method must not be called if {@link #setAllowedActivities(Set)} has been called.
          *
-         * @throws IllegalArgumentException if {@link #setAllowedActivities(Set)} has been set to a
-         *   non-null value.
+         * @throws IllegalArgumentException if {@link #setAllowedActivities(Set)} has been called.
          *
          * @param blockedActivities A set of {@link ComponentName} to be blocked launching from
          *   virtual device.
          */
-        // Allowing null to enforce that at most one of allowed / blocked activities can be non-null
-        @SuppressLint("NullableCollection")
         @NonNull
-        public Builder setBlockedActivities(@Nullable Set<ComponentName> blockedActivities) {
-            if (mAllowedActivities != null && blockedActivities != null) {
+        public Builder setBlockedActivities(@NonNull Set<ComponentName> blockedActivities) {
+            if (mDefaultActivityPolicyConfigured
+                    && mDefaultActivityPolicy != ACTIVITY_POLICY_DEFAULT_ALLOWED) {
                 throw new IllegalArgumentException(
                         "Allowed activities and Blocked activities cannot both be set.");
             }
+            mDefaultActivityPolicy = ACTIVITY_POLICY_DEFAULT_ALLOWED;
+            mDefaultActivityPolicyConfigured = true;
             mBlockedActivities = blockedActivities;
             return this;
         }
@@ -307,13 +346,12 @@
             if (mUsersWithMatchingAccounts == null) {
                 mUsersWithMatchingAccounts = Collections.emptySet();
             }
-            if (mAllowedActivities != null && mBlockedActivities != null) {
-                // Should never reach here because the setters block this as well.
-                throw new IllegalStateException(
-                        "Allowed activities and Blocked activities cannot both be set.");
-            }
-            return new VirtualDeviceParams(mLockState, mUsersWithMatchingAccounts,
-                    mAllowedActivities, mBlockedActivities);
+            return new VirtualDeviceParams(
+                    mLockState,
+                    mUsersWithMatchingAccounts,
+                    mAllowedActivities,
+                    mBlockedActivities,
+                    mDefaultActivityPolicy);
         }
     }
 }
diff --git a/core/java/android/companion/virtual/audio/AudioCapture.java b/core/java/android/companion/virtual/audio/AudioCapture.java
index ebe17db..d6d0d2b 100644
--- a/core/java/android/companion/virtual/audio/AudioCapture.java
+++ b/core/java/android/companion/virtual/audio/AudioCapture.java
@@ -16,13 +16,16 @@
 
 package android.companion.virtual.audio;
 
+import static android.media.AudioRecord.READ_BLOCKING;
 import static android.media.AudioRecord.RECORDSTATE_RECORDING;
 import static android.media.AudioRecord.RECORDSTATE_STOPPED;
+import static android.media.AudioRecord.STATE_INITIALIZED;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
+import android.media.AudioFormat;
 import android.media.AudioRecord;
 import android.util.Log;
 
@@ -42,12 +45,12 @@
 public final class AudioCapture {
     private static final String TAG = "AudioCapture";
 
+    private final AudioFormat mAudioFormat;
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
     @Nullable
     private AudioRecord mAudioRecord;
-
     @GuardedBy("mLock")
     private int mRecordingState = RECORDSTATE_STOPPED;
 
@@ -63,12 +66,12 @@
     void setAudioRecord(@Nullable AudioRecord audioRecord) {
         Log.d(TAG, "set AudioRecord with " + audioRecord);
         synchronized (mLock) {
-            // Release old reference.
-            if (mAudioRecord != null) {
-                mAudioRecord.release();
-            }
             // Sync recording state for new reference.
             if (audioRecord != null) {
+                if (audioRecord.getState() != STATE_INITIALIZED) {
+                    throw new IllegalStateException("set an uninitialized AudioRecord.");
+                }
+
                 if (mRecordingState == RECORDSTATE_RECORDING
                         && audioRecord.getRecordingState() != RECORDSTATE_RECORDING) {
                     audioRecord.startRecording();
@@ -78,16 +81,97 @@
                     audioRecord.stop();
                 }
             }
+
+            // Release old reference before assigning the new reference.
+            if (mAudioRecord != null) {
+                mAudioRecord.release();
+            }
             mAudioRecord = audioRecord;
         }
     }
 
-    /** See {@link AudioRecord#read(ByteBuffer, int)}. */
-    public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes) {
+    AudioCapture(@NonNull AudioFormat audioFormat) {
+        mAudioFormat = audioFormat;
+    }
+
+    void close() {
+        synchronized (mLock) {
+            if (mAudioRecord != null) {
+                mAudioRecord.release();
+                mAudioRecord = null;
+            }
+        }
+    }
+
+    /** See {@link AudioRecord#getFormat()} */
+    public @NonNull AudioFormat getFormat() {
+        return mAudioFormat;
+    }
+
+    /** See {@link AudioRecord#read(byte[], int, int)} */
+    public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) {
+        return read(audioData, offsetInBytes, sizeInBytes, READ_BLOCKING);
+    }
+
+    /** See {@link AudioRecord#read(byte[], int, int, int)} */
+    public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
+            @AudioRecord.ReadMode int readMode) {
         final int sizeRead;
         synchronized (mLock) {
             if (mAudioRecord != null) {
-                sizeRead = mAudioRecord.read(audioBuffer, sizeInBytes);
+                sizeRead = mAudioRecord.read(audioData, offsetInBytes, sizeInBytes, readMode);
+            } else {
+                sizeRead = 0;
+            }
+        }
+        return sizeRead;
+    }
+
+    /** See {@link AudioRecord#read(ByteBuffer, int)}. */
+    public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes) {
+        return read(audioBuffer, sizeInBytes, READ_BLOCKING);
+    }
+
+    /** See {@link AudioRecord#read(ByteBuffer, int, int)}. */
+    public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes,
+            @AudioRecord.ReadMode int readMode) {
+        final int sizeRead;
+        synchronized (mLock) {
+            if (mAudioRecord != null) {
+                sizeRead = mAudioRecord.read(audioBuffer, sizeInBytes, readMode);
+            } else {
+                sizeRead = 0;
+            }
+        }
+        return sizeRead;
+    }
+
+    /** See {@link AudioRecord#read(float[], int, int, int)}. */
+    public int read(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
+            @AudioRecord.ReadMode int readMode) {
+        final int sizeRead;
+        synchronized (mLock) {
+            if (mAudioRecord != null) {
+                sizeRead = mAudioRecord.read(audioData, offsetInFloats, sizeInFloats, readMode);
+            } else {
+                sizeRead = 0;
+            }
+        }
+        return sizeRead;
+    }
+
+    /** See {@link AudioRecord#read(short[], int, int)}. */
+    public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) {
+        return read(audioData, offsetInShorts, sizeInShorts, READ_BLOCKING);
+    }
+
+    /** See {@link AudioRecord#read(short[], int, int, int)}. */
+    public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
+            @AudioRecord.ReadMode int readMode) {
+        final int sizeRead;
+        synchronized (mLock) {
+            if (mAudioRecord != null) {
+                sizeRead = mAudioRecord.read(audioData, offsetInShorts, sizeInShorts, readMode);
             } else {
                 sizeRead = 0;
             }
diff --git a/core/java/android/companion/virtual/audio/AudioInjection.java b/core/java/android/companion/virtual/audio/AudioInjection.java
index 5e8e0a4..9d6a3eb 100644
--- a/core/java/android/companion/virtual/audio/AudioInjection.java
+++ b/core/java/android/companion/virtual/audio/AudioInjection.java
@@ -18,11 +18,14 @@
 
 import static android.media.AudioTrack.PLAYSTATE_PLAYING;
 import static android.media.AudioTrack.PLAYSTATE_STOPPED;
+import static android.media.AudioTrack.STATE_INITIALIZED;
+import static android.media.AudioTrack.WRITE_BLOCKING;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
+import android.media.AudioFormat;
 import android.media.AudioTrack;
 import android.util.Log;
 
@@ -42,7 +45,9 @@
 public final class AudioInjection {
     private static final String TAG = "AudioInjection";
 
+    private final AudioFormat mAudioFormat;
     private final Object mLock = new Object();
+
     @GuardedBy("mLock")
     @Nullable
     private AudioTrack mAudioTrack;
@@ -70,12 +75,12 @@
     void setAudioTrack(@Nullable AudioTrack audioTrack) {
         Log.d(TAG, "set AudioTrack with " + audioTrack);
         synchronized (mLock) {
-            // Release old reference.
-            if (mAudioTrack != null) {
-                mAudioTrack.release();
-            }
             // Sync play state for new reference.
             if (audioTrack != null) {
+                if (audioTrack.getState() != STATE_INITIALIZED) {
+                    throw new IllegalStateException("set an uninitialized AudioTrack.");
+                }
+
                 if (mPlayState == PLAYSTATE_PLAYING
                         && audioTrack.getPlayState() != PLAYSTATE_PLAYING) {
                     audioTrack.play();
@@ -85,10 +90,52 @@
                     audioTrack.stop();
                 }
             }
+
+            // Release old reference before assigning the new reference.
+            if (mAudioTrack != null) {
+                mAudioTrack.release();
+            }
             mAudioTrack = audioTrack;
         }
     }
 
+    AudioInjection(@NonNull AudioFormat audioFormat) {
+        mAudioFormat = audioFormat;
+    }
+
+    void close() {
+        synchronized (mLock) {
+            if (mAudioTrack != null) {
+                mAudioTrack.release();
+                mAudioTrack = null;
+            }
+        }
+    }
+
+    /** See {@link AudioTrack#getFormat()}. */
+    public @NonNull AudioFormat getFormat() {
+        return mAudioFormat;
+    }
+
+    /** See {@link AudioTrack#write(byte[], int, int)}. */
+    public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) {
+        return write(audioData, offsetInBytes, sizeInBytes, WRITE_BLOCKING);
+    }
+
+    /** See {@link AudioTrack#write(byte[], int, int, int)}. */
+    public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
+            @AudioTrack.WriteMode int writeMode) {
+        final int sizeWrite;
+        synchronized (mLock) {
+            if (mAudioTrack != null && !mIsSilent) {
+                sizeWrite = mAudioTrack.write(audioData, offsetInBytes, sizeInBytes, writeMode);
+            } else {
+                sizeWrite = 0;
+            }
+        }
+        return sizeWrite;
+    }
+
     /** See {@link AudioTrack#write(ByteBuffer, int, int)}. */
     public int write(@NonNull ByteBuffer audioBuffer, int sizeInBytes, int writeMode) {
         final int sizeWrite;
@@ -102,6 +149,53 @@
         return sizeWrite;
     }
 
+    /** See {@link AudioTrack#write(ByteBuffer, int, int, long)}. */
+    public int write(@NonNull ByteBuffer audioBuffer, int sizeInBytes,
+            @AudioTrack.WriteMode int writeMode, long timestamp) {
+        final int sizeWrite;
+        synchronized (mLock) {
+            if (mAudioTrack != null && !mIsSilent) {
+                sizeWrite = mAudioTrack.write(audioBuffer, sizeInBytes, writeMode, timestamp);
+            } else {
+                sizeWrite = 0;
+            }
+        }
+        return sizeWrite;
+    }
+
+    /** See {@link AudioTrack#write(float[], int, int, int)}. */
+    public int write(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
+            @AudioTrack.WriteMode int writeMode) {
+        final int sizeWrite;
+        synchronized (mLock) {
+            if (mAudioTrack != null && !mIsSilent) {
+                sizeWrite = mAudioTrack.write(audioData, offsetInFloats, sizeInFloats, writeMode);
+            } else {
+                sizeWrite = 0;
+            }
+        }
+        return sizeWrite;
+    }
+
+    /** See {@link AudioTrack#write(short[], int, int)}. */
+    public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) {
+        return write(audioData, offsetInShorts, sizeInShorts, WRITE_BLOCKING);
+    }
+
+    /** See {@link AudioTrack#write(short[], int, int, int)}. */
+    public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
+            @AudioTrack.WriteMode int writeMode) {
+        final int sizeWrite;
+        synchronized (mLock) {
+            if (mAudioTrack != null && !mIsSilent) {
+                sizeWrite = mAudioTrack.write(audioData, offsetInShorts, sizeInShorts, writeMode);
+            } else {
+                sizeWrite = 0;
+            }
+        }
+        return sizeWrite;
+    }
+
     /** See {@link AudioTrack#play()}. */
     public void play() {
         synchronized (mLock) {
diff --git a/core/java/android/companion/virtual/audio/VirtualAudioSession.java b/core/java/android/companion/virtual/audio/VirtualAudioSession.java
index c6a1045..524f6e2 100644
--- a/core/java/android/companion/virtual/audio/VirtualAudioSession.java
+++ b/core/java/android/companion/virtual/audio/VirtualAudioSession.java
@@ -68,12 +68,6 @@
     private AudioPolicy mAudioPolicy;
     @Nullable
     @GuardedBy("mLock")
-    private AudioFormat mCaptureFormat;
-    @Nullable
-    @GuardedBy("mLock")
-    private AudioFormat mInjectionFormat;
-    @Nullable
-    @GuardedBy("mLock")
     private AudioCapture mAudioCapture;
     @Nullable
     @GuardedBy("mLock")
@@ -104,8 +98,7 @@
                         "Cannot start capture while another capture is ongoing.");
             }
 
-            mCaptureFormat = captureFormat;
-            mAudioCapture = new AudioCapture();
+            mAudioCapture = new AudioCapture(captureFormat);
             mAudioCapture.startRecording();
             return mAudioCapture;
         }
@@ -127,8 +120,7 @@
                         "Cannot start injection while injection is already ongoing.");
             }
 
-            mInjectionFormat = injectionFormat;
-            mAudioInjection = new AudioInjection();
+            mAudioInjection = new AudioInjection(injectionFormat);
             mAudioInjection.play();
 
             mUserRestrictionsDetector.register(/* callback= */ this);
@@ -179,10 +171,14 @@
         mUserRestrictionsDetector.unregister();
         releaseAudioStreams();
         synchronized (mLock) {
-            mAudioCapture = null;
-            mAudioInjection = null;
-            mCaptureFormat = null;
-            mInjectionFormat = null;
+            if (mAudioCapture != null) {
+                mAudioCapture.close();
+                mAudioCapture = null;
+            }
+            if (mAudioInjection != null) {
+                mAudioInjection.close();
+                mAudioInjection = null;
+            }
         }
     }
 
@@ -198,9 +194,9 @@
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
     private void createAudioStreams(int[] appUids) {
         synchronized (mLock) {
-            if (mCaptureFormat == null && mInjectionFormat == null) {
+            if (mAudioCapture == null && mAudioInjection == null) {
                 throw new IllegalStateException(
-                        "At least one of captureFormat and injectionFormat must be specified.");
+                        "At least one of AudioCapture and AudioInjection must be started.");
             }
             if (mAudioPolicy != null) {
                 throw new IllegalStateException(
@@ -218,12 +214,12 @@
             AudioMix audioRecordMix = null;
             AudioMix audioTrackMix = null;
             AudioPolicy.Builder builder = new AudioPolicy.Builder(mContext);
-            if (mCaptureFormat != null) {
-                audioRecordMix = createAudioRecordMix(mCaptureFormat, appUids);
+            if (mAudioCapture != null) {
+                audioRecordMix = createAudioRecordMix(mAudioCapture.getFormat(), appUids);
                 builder.addMix(audioRecordMix);
             }
-            if (mInjectionFormat != null) {
-                audioTrackMix = createAudioTrackMix(mInjectionFormat, appUids);
+            if (mAudioInjection != null) {
+                audioTrackMix = createAudioTrackMix(mAudioInjection.getFormat(), appUids);
                 builder.addMix(audioTrackMix);
             }
             mAudioPolicy = builder.build();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8f82a0a..2bda020 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3571,11 +3571,11 @@
      *          <li>{@link #BIND_INCLUDE_CAPABILITIES}
      *      </ul>
      *
-      * @return {@code true} if the system is in the process of bringing up a
-     *         service that your client has permission to bind to; {@code false}
-     *         if the system couldn't find the service or if your client doesn't
-     *         have permission to bind to it. You should call {@link #unbindService}
-     *         to release the connection even if this method returned {@code false}.
+     * @return {@code true} if the system is in the process of bringing up a
+     *      service that your client has permission to bind to; {@code false}
+     *      if the system couldn't find the service or if your client doesn't
+     *      have permission to bind to it. Regardless of the return value, you
+     *      should later call {@link #unbindService} to release the connection.
      *
      * @throws SecurityException If the caller does not have permission to
      *      access the service or the service cannot be found. Call
@@ -3589,10 +3589,16 @@
             @NonNull ServiceConnection conn, @BindServiceFlags int flags);
 
     /**
-     * Same as {@link #bindService(Intent, ServiceConnection, int)} with executor to control
-     * ServiceConnection callbacks.
+     * Same as {@link #bindService(Intent, ServiceConnection, int)
+     * bindService(Intent, ServiceConnection, int)} with executor to control ServiceConnection
+     * callbacks.
+     *
      * @param executor Callbacks on ServiceConnection will be called on executor. Must use same
      *      instance for the same instance of ServiceConnection.
+     *
+     * @return The result of the binding as described in
+     *      {@link #bindService(Intent, ServiceConnection, int)
+     *      bindService(Intent, ServiceConnection, int)}.
      */
     public boolean bindService(@RequiresPermission @NonNull Intent service,
             @BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor,
@@ -3618,12 +3624,13 @@
      * @param instanceName 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.
-     * @return Returns success of binding as per {@link #bindService}.
      * @param executor Callbacks on ServiceConnection will be called on executor.
      *      Must use same instance for the same instance of ServiceConnection.
      * @param conn Receives information as the service is started and stopped.
      *      This must be a valid ServiceConnection object; it must not be null.
      *
+     * @return Returns success of binding as per {@link #bindService}.
+     *
      * @throws SecurityException If the caller does not have permission to access the service
      * @throws IllegalArgumentException If the instanceName is invalid.
      *
@@ -3638,8 +3645,7 @@
     }
 
     /**
-     * Binds to a service in the given {@code user} in the same manner as
-     * {@link #bindService(Intent, ServiceConnection, int)}.
+     * Binds to a service in the given {@code user} in the same manner as {@link #bindService}.
      *
      * <p>Requires that one of the following conditions are met:
      * <ul>
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0aa25ef..478befd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2054,7 +2054,7 @@
             "android.intent.action.VIEW_PERMISSION_USAGE_FOR_PERIOD";
 
     /**
-     * Activity action: Launch the Safety Hub UI.
+     * Activity action: Launch the Safety Center Quick Settings UI.
      *
      * <p>
      * Input: Nothing.
@@ -2062,11 +2062,14 @@
      * <p>
      * Output: Nothing.
      * </p>
+     *
+     * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     @RequiresPermission(Manifest.permission.MANAGE_SENSOR_PRIVACY)
-    public static final String ACTION_VIEW_SAFETY_HUB =
-            "android.intent.action.VIEW_SAFETY_HUB";
+    public static final String ACTION_VIEW_SAFETY_CENTER_QS =
+            "android.intent.action.VIEW_SAFETY_CENTER_QS";
 
     /**
      * Activity action: Launch UI to manage a default app.
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index fbb03ca..2961b55 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -40,7 +40,7 @@
 import android.util.Printer;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
-import android.view.OnBackInvokedCallback;
+import android.window.OnBackInvokedCallback;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Parcelling;
@@ -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();
@@ -2582,7 +2582,7 @@
     }
 
     /**
-     * Returns whether the application will use the {@link android.view.OnBackInvokedCallback}
+     * Returns whether the application will use the {@link android.window.OnBackInvokedCallback}
      * navigation system instead of the {@link android.view.KeyEvent#KEYCODE_BACK} and related
      * callbacks.
      *
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 30aed8b..0f236df 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.
@@ -653,7 +642,7 @@
 
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     String getPermissionControllerPackageName();
-    String getSupplementalProcessPackageName();
+    String getSdkSandboxPackageName();
 
     ParceledListSlice getInstantApps(int userId);
     byte[] getInstantAppCookie(String packageName, int userId);
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 a162c41..78dddb5 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,
@@ -5772,16 +5783,16 @@
     }
 
     /**
-     * Returns the package name of the component implementing supplemental process service.
+     * Returns the package name of the component implementing sdk sandbox service.
      *
-     * @return the package name of the component implementing supplemental process service
+     * @return the package name of the component implementing sdk sandbox service
      *
      * @hide
      */
     @NonNull
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @TestApi
-    public String getSupplementalProcessPackageName() {
+    public String getSdkSandboxPackageName() {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
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/res/Resources.java b/core/java/android/content/res/Resources.java
index ebef053..a03286d3 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2674,9 +2674,8 @@
         // Putting into a map keyed on the apk assets to deduplicate resources that are different
         // objects but ultimately represent the same assets
         Map<List<ApkAssets>, Resources> history = new ArrayMap<>();
-        for (Resources r : sResourcesHistory) {
-            history.put(Arrays.asList(r.mResourcesImpl.mAssets.getApkAssets()), r);
-        }
+        sResourcesHistory.forEach(
+                r -> history.put(Arrays.asList(r.mResourcesImpl.mAssets.getApkAssets()), r));
         int i = 0;
         for (Resources r : history.values()) {
             if (r != null) {
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 85890c1..7b24cc4 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;
@@ -47,7 +48,7 @@
     private int mHistogramType;
     private float[] mHistogramBins;
     private long[] mHistogramCounts;
-    private int mDynamicRangeProfile;
+    private long mDynamicRangeProfile;
     private int 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, int dynamicRangeProfile,
+            int startLatencyMs, int maxHalBuffers, int maxAppBuffers, long dynamicRangeProfile,
             int 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);
@@ -130,7 +134,7 @@
         dest.writeInt(mHistogramType);
         dest.writeFloatArray(mHistogramBins);
         dest.writeLongArray(mHistogramCounts);
-        dest.writeInt(mDynamicRangeProfile);
+        dest.writeLong(mDynamicRangeProfile);
         dest.writeInt(mStreamUseCase);
     }
 
@@ -138,6 +142,7 @@
         mWidth = in.readInt();
         mHeight = in.readInt();
         mFormat = in.readInt();
+        mMaxPreviewFps = in.readFloat();
         mDataSpace = in.readInt();
         mUsage = in.readLong();
         mRequestCount = in.readLong();
@@ -148,7 +153,7 @@
         mHistogramType = in.readInt();
         mHistogramBins = in.createFloatArray();
         mHistogramCounts = in.createLongArray();
-        mDynamicRangeProfile = in.readInt();
+        mDynamicRangeProfile = in.readLong();
         mStreamUseCase = in.readInt();
     }
 
@@ -164,6 +169,10 @@
         return mFormat;
     }
 
+    public float getMaxPreviewFps() {
+        return mMaxPreviewFps;
+    }
+
     public int getDataSpace() {
         return mDataSpace;
     }
@@ -204,7 +213,7 @@
         return mHistogramCounts;
     }
 
-    public int getDynamicRangeProfile() {
+    public long getDynamicRangeProfile() {
         return mDynamicRangeProfile;
     }
 
diff --git a/core/java/android/hardware/SensorPrivacyManager.java b/core/java/android/hardware/SensorPrivacyManager.java
index a3cc01c..0460e58 100644
--- a/core/java/android/hardware/SensorPrivacyManager.java
+++ b/core/java/android/hardware/SensorPrivacyManager.java
@@ -136,9 +136,9 @@
         public static final int OTHER = SensorPrivacyToggleSourceProto.OTHER;
 
         /**
-         * Constant for SAFETY_HUB.
+         * Constant for SAFETY_CENTER.
          */
-        public static final int SAFETY_HUB = SensorPrivacyToggleSourceProto.SAFETY_HUB;
+        public static final int SAFETY_CENTER = SensorPrivacyToggleSourceProto.SAFETY_CENTER;
 
         /**
          * Source for toggling sensors
@@ -151,7 +151,7 @@
                 DIALOG,
                 SHELL,
                 OTHER,
-                SAFETY_HUB
+                SAFETY_CENTER
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface Source {}
@@ -652,7 +652,7 @@
         String packageName = mContext.getOpPackageName();
         if (Objects.equals(packageName,
                 mContext.getPackageManager().getPermissionControllerPackageName())) {
-            return Sources.SAFETY_HUB;
+            return Sources.SAFETY_CENTER;
         }
         return Sources.OTHER;
     }
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/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index ada5155..3f139f0 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -104,16 +104,16 @@
     public static final int BIOMETRIC_MULTI_SENSOR_DEFAULT = 0;
 
     /**
-     * Prefer the face sensor and fall back to fingerprint when needed.
+     * Use face and fingerprint sensors together.
      * @hide
      */
-    public static final int BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT = 1;
+    public static final int BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE = 1;
 
     /**
      * @hide
      */
     @IntDef({BIOMETRIC_MULTI_SENSOR_DEFAULT,
-            BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT})
+            BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE})
     @Retention(RetentionPolicy.SOURCE)
     public @interface BiometricMultiSensorMode {}
 
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 2c3c8c3..42aad36 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -63,7 +63,7 @@
 
     // Notify BiometricService when <Biometric>Service is ready to start the prepared client.
     // Client lifecycle is still managed in <Biometric>Service.
-    void onReadyForAuthentication(int cookie);
+    void onReadyForAuthentication(long requestId, int cookie);
 
     // Requests all BIOMETRIC_STRONG sensors to have their authenticatorId invalidated for the
     // specified user. This happens when enrollments have been added on devices with multiple
diff --git a/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl
index 5d9b5f3..450c5ce 100644
--- a/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricSysuiReceiver.aidl
@@ -30,6 +30,4 @@
     void onSystemEvent(int event);
     // Notifies that the dialog has finished animating.
     void onDialogAnimatedIn();
-    // For multi-sensor devices, notifies that the fingerprint should start now.
-    void onStartFingerprintNow();
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 524fe79..7bebe1f 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -2448,8 +2448,8 @@
      * @see #REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX
      * @hide
      */
-    public static final Key<int[]> REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP =
-            new Key<int[]>("android.request.availableDynamicRangeProfilesMap", int[].class);
+    public static final Key<long[]> REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP =
+            new Key<long[]>("android.request.availableDynamicRangeProfilesMap", long[].class);
 
     /**
      * <p>Recommended 10-bit dynamic range profile.</p>
@@ -2464,8 +2464,8 @@
      */
     @PublicKey
     @NonNull
-    public static final Key<Integer> REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE =
-            new Key<Integer>("android.request.recommendedTenBitDynamicRangeProfile", int.class);
+    public static final Key<Long> REQUEST_RECOMMENDED_TEN_BIT_DYNAMIC_RANGE_PROFILE =
+            new Key<Long>("android.request.recommendedTenBitDynamicRangeProfile", long.class);
 
     /**
      * <p>The list of image formats that are supported by this
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 8f42b1f..73735ed 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -990,7 +990,7 @@
      * <p>Reprocessing with 10-bit output targets on 10-bit capable
      * {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT} devices is
      * not supported. Trying to initialize a repreocessable capture session with one ore more
-     * output configurations set {@link OutputConfiguration#setDynamicRangeProfile(int)} to use
+     * output configurations set {@link OutputConfiguration#setDynamicRangeProfile} to use
      * a 10-bit dynamic range profile {@link android.hardware.camera2.params.DynamicRangeProfiles}
      * will trigger {@link IllegalArgumentException}.</p>
      *
@@ -1179,7 +1179,7 @@
      * @see #createCaptureSessionByOutputConfigurations
      * @see #createReprocessableCaptureSession
      * @see #createConstrainedHighSpeedCaptureSession
-     * @see OutputConfiguration#setDynamicRangeProfile(int)
+     * @see OutputConfiguration#setDynamicRangeProfile
      * @see android.hardware.camera2.params.DynamicRangeProfiles
      */
     public void createCaptureSession(
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 4fb496d..468e604 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -1058,7 +1058,7 @@
     }
 
     private DynamicRangeProfiles getDynamicRangeProfiles() {
-        int[] profileArray = getBase(
+        long[] profileArray = getBase(
                 CameraCharacteristics.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
 
         if (profileArray == null) {
diff --git a/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java b/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
index 5c1a4aa..14ed689 100644
--- a/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
+++ b/core/java/android/hardware/camera2/params/DynamicRangeProfiles.java
@@ -16,7 +16,7 @@
 
 package android.hardware.camera2.params;
 
-import android.annotation.IntDef;
+import android.annotation.LongDef;
 import android.annotation.NonNull;
 
 import android.hardware.camera2.CameraMetadata;
@@ -27,7 +27,6 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -44,20 +43,20 @@
  *
  * <p>Some devices may not be able to support 8-bit and/or 10-bit output with different dynamic
  * range profiles within the same capture request. Such device specific constraints can be queried
- * by calling {@link #getProfileCaptureRequestConstraints(int)}. Do note that unsupported
+ * by calling {@link #getProfileCaptureRequestConstraints}. Do note that unsupported
  * combinations will result in {@link IllegalArgumentException} when trying to submit a capture
  * request. Capture requests that only reference outputs configured using the same dynamic range
  * profile value will never fail due to such constraints.</p>
  *
- * @see OutputConfiguration#setDynamicRangeProfile(int)
+ * @see OutputConfiguration#setDynamicRangeProfile
  */
 public final class DynamicRangeProfiles {
     /**
      * This the default 8-bit standard profile that will be used in case where camera clients do not
      * explicitly configure a supported dynamic range profile by calling
-     * {@link OutputConfiguration#setDynamicRangeProfile(int)}.
+     * {@link OutputConfiguration#setDynamicRangeProfile}.
      */
-    public static final int STANDARD =
+    public static final long STANDARD =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
 
     /**
@@ -65,7 +64,7 @@
      *
      * <p>All 10-bit output capable devices are required to support this profile.</p>
      */
-    public static final int HLG10  =
+    public static final long HLG10  =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HLG10;
 
     /**
@@ -74,7 +73,7 @@
      * <p>This profile utilizes internal static metadata to increase the quality
      * of the capture.</p>
      */
-    public static final int HDR10  =
+    public static final long HDR10  =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10;
 
     /**
@@ -83,7 +82,7 @@
      * <p>In contrast to HDR10, this profile uses internal per-frame metadata
      * to further enhance the quality of the capture.</p>
      */
-    public static final int HDR10_PLUS =
+    public static final long HDR10_PLUS =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS;
 
     /**
@@ -91,13 +90,13 @@
      * accurate capture. This would typically differ from what a specific device
      * might want to tune for a consumer optimized Dolby Vision general capture.</p>
      */
-    public static final int DOLBY_VISION_10B_HDR_REF =
+    public static final long DOLBY_VISION_10B_HDR_REF =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF;
 
     /**
      * <p>This is the power optimized mode for 10-bit Dolby Vision HDR Reference Mode.</p>
      */
-    public static final int DOLBY_VISION_10B_HDR_REF_PO =
+    public static final long DOLBY_VISION_10B_HDR_REF_PO =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_REF_PO;
 
     /**
@@ -107,52 +106,52 @@
      * that each specific device would have a different look for their default
      * Dolby Vision capture.</p>
      */
-    public static final int DOLBY_VISION_10B_HDR_OEM =
+    public static final long DOLBY_VISION_10B_HDR_OEM =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM;
 
     /**
      * <p>This is the power optimized mode for 10-bit Dolby Vision HDR device specific capture
      * Mode.</p>
      */
-    public static final int DOLBY_VISION_10B_HDR_OEM_PO =
+    public static final long DOLBY_VISION_10B_HDR_OEM_PO =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_10B_HDR_OEM_PO;
 
     /**
      * <p>This is the 8-bit version of the Dolby Vision reference capture mode optimized
      * for scene accuracy.</p>
      */
-    public static final int DOLBY_VISION_8B_HDR_REF =
+    public static final long DOLBY_VISION_8B_HDR_REF =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF;
 
     /**
      * <p>This is the power optimized mode for 8-bit Dolby Vision HDR Reference Mode.</p>
      */
-    public static final int DOLBY_VISION_8B_HDR_REF_PO =
+    public static final long DOLBY_VISION_8B_HDR_REF_PO =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_REF_PO;
 
     /**
      * <p>This is the 8-bit version of device specific tuned and optimized Dolby Vision
      * capture mode.</p>
      */
-    public static final int DOLBY_VISION_8B_HDR_OEM =
+    public static final long DOLBY_VISION_8B_HDR_OEM =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM;
 
     /**
      * <p>This is the power optimized mode for 8-bit Dolby Vision HDR device specific
      * capture Mode.</p>
      */
-    public static final int DOLBY_VISION_8B_HDR_OEM_PO =
+    public static final long DOLBY_VISION_8B_HDR_OEM_PO =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_DOLBY_VISION_8B_HDR_OEM_PO;
 
     /*
      * @hide
      */
-    public static final int PUBLIC_MAX =
+    public static final long PUBLIC_MAX =
             CameraMetadata.REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX;
 
      /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"PROFILE_"}, value =
+    @LongDef(prefix = {"PROFILE_"}, value =
             {STANDARD,
              HLG10,
              HDR10,
@@ -168,7 +167,8 @@
     public @interface Profile {
     }
 
-    private final HashMap<Integer, Set<Integer>> mProfileMap = new HashMap<>();
+    private final HashMap<Long, Set<Long>> mProfileMap = new HashMap<>();
+    private final HashMap<Long, Boolean> mLookahedLatencyMap = new HashMap<>();
 
     /**
      * Create a new immutable DynamicRangeProfiles instance.
@@ -193,23 +193,23 @@
      *            if {@code elements} is {@code null}
      *
      */
-    public DynamicRangeProfiles(@NonNull final int[] elements) {
-        if ((elements.length % 2) != 0) {
+    public DynamicRangeProfiles(@NonNull final long[] elements) {
+        if ((elements.length % 3) != 0) {
             throw new IllegalArgumentException("Dynamic range profile map length " +
                     elements.length + " is not even!");
         }
 
-        for (int i = 0; i < elements.length; i += 2) {
+        for (int i = 0; i < elements.length; i += 3) {
             checkProfileValue(elements[i]);
             // STANDARD is not expected to be included
             if (elements[i] == STANDARD) {
                 throw new IllegalArgumentException("Dynamic range profile map must not include a"
                         + " STANDARD profile entry!");
             }
-            HashSet<Integer> profiles = new HashSet<>();
+            HashSet<Long> profiles = new HashSet<>();
 
             if (elements[i+1] != 0) {
-                for (int profile = STANDARD; profile < PUBLIC_MAX; profile <<= 1) {
+                for (long profile = STANDARD; profile < PUBLIC_MAX; profile <<= 1) {
                     if ((elements[i+1] & profile) != 0) {
                         profiles.add(profile);
                     }
@@ -217,42 +217,35 @@
             }
 
             mProfileMap.put(elements[i], profiles);
+            mLookahedLatencyMap.put(elements[i], elements[i+2] != 0L);
         }
 
         // Build the STANDARD constraints depending on the advertised 10-bit limitations
-        HashSet<Integer> standardConstraints = new HashSet<>();
+        HashSet<Long> standardConstraints = new HashSet<>();
         standardConstraints.add(STANDARD);
-        for(Integer profile : mProfileMap.keySet()) {
+        for(Long profile : mProfileMap.keySet()) {
             if (mProfileMap.get(profile).isEmpty() || mProfileMap.get(profile).contains(STANDARD)) {
                 standardConstraints.add(profile);
             }
         }
 
         mProfileMap.put(STANDARD, standardConstraints);
+        mLookahedLatencyMap.put(STANDARD, false);
     }
 
 
     /**
      * @hide
      */
-    public static void checkProfileValue(int profile) {
-        switch (profile) {
-            case STANDARD:
-            case HLG10:
-            case HDR10:
-            case HDR10_PLUS:
-            case DOLBY_VISION_10B_HDR_REF:
-            case DOLBY_VISION_10B_HDR_REF_PO:
-            case DOLBY_VISION_10B_HDR_OEM:
-            case DOLBY_VISION_10B_HDR_OEM_PO:
-            case DOLBY_VISION_8B_HDR_REF:
-            case DOLBY_VISION_8B_HDR_REF_PO:
-            case DOLBY_VISION_8B_HDR_OEM:
-            case DOLBY_VISION_8B_HDR_OEM_PO:
-                //No-op
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown profile " + profile);
+    public static void checkProfileValue(long profile) {
+        if (profile == STANDARD || profile == HLG10 || profile == HDR10 || profile == HDR10_PLUS
+                || profile == DOLBY_VISION_10B_HDR_REF || profile == DOLBY_VISION_10B_HDR_REF_PO
+                || profile == DOLBY_VISION_10B_HDR_OEM || profile == DOLBY_VISION_10B_HDR_OEM_PO
+                || profile == DOLBY_VISION_8B_HDR_REF || profile == DOLBY_VISION_8B_HDR_REF_PO
+                || profile == DOLBY_VISION_8B_HDR_OEM
+                || profile == DOLBY_VISION_8B_HDR_OEM_PO) {//No-op
+        } else {
+            throw new IllegalArgumentException("Unknown profile " + profile);
         }
     }
 
@@ -261,7 +254,7 @@
      *
      * @return non-modifiable set of dynamic range profiles
      */
-     public @NonNull Set<Integer> getSupportedProfiles() {
+     public @NonNull Set<Long> getSupportedProfiles() {
          return Collections.unmodifiableSet(mProfileMap.keySet());
      }
 
@@ -272,7 +265,7 @@
      *
      * <p>For example if assume that a particular 10-bit output capable device
      * returns ({@link #STANDARD}, {@link #HLG10}, {@link #HDR10}) as result from calling
-     * {@link #getSupportedProfiles()} and {@link #getProfileCaptureRequestConstraints(int)}
+     * {@link #getSupportedProfiles()} and {@link #getProfileCaptureRequestConstraints}
      * returns ({@link #STANDARD}, {@link #HLG10}) when given an argument of {@link #STANDARD}.
      * This means that the corresponding camera device will only accept and process capture requests
      * that reference outputs configured using {@link #HDR10} dynamic profile or alternatively
@@ -288,14 +281,40 @@
      *                                    within the list returned by
      *                                    getSupportedProfiles()
      *
-     * @see OutputConfiguration#setDynamicRangeProfile(int)
+     * @see OutputConfiguration#setDynamicRangeProfile
      */
-     public @NonNull Set<Integer> getProfileCaptureRequestConstraints(@Profile int profile) {
-         Set<Integer> ret = mProfileMap.get(profile);
+     public @NonNull Set<Long> getProfileCaptureRequestConstraints(@Profile long profile) {
+         Set<Long> ret = mProfileMap.get(profile);
          if (ret == null) {
              throw new IllegalArgumentException("Unsupported profile!");
          }
 
          return Collections.unmodifiableSet(ret);
      }
+
+    /**
+     * Check whether a given dynamic range profile is suitable for latency sensitive use cases.
+     *
+     * <p>Due to internal lookahead logic, camera outputs configured with some dynamic range
+     * profiles may experience additional latency greater than 3 buffers. Using camera outputs
+     * with such profiles for latency sensitive use cases such as camera preview is not
+     * recommended. Profiles that have such extra streaming delay are typically utilized for
+     * scenarios such as offscreen video recording.</p>
+     *
+     * @return true if the given profile is not suitable for latency sensitive use cases, false
+     *         otherwise
+     * @throws IllegalArgumentException - If the profile argument is not
+     *                                    within the list returned by
+     *                                    getSupportedProfiles()
+     *
+     * @see OutputConfiguration#setDynamicRangeProfile
+     */
+    public boolean isExtraLatencyPresent(@Profile long profile) {
+        Boolean ret = mLookahedLatencyMap.get(profile);
+        if (ret == null) {
+            throw new IllegalArgumentException("Unsupported profile!");
+        }
+
+        return ret;
+    }
 }
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index 8c0dcfc..465abfb 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -246,7 +246,7 @@
          * @return true if stream is able to output 10-bit pixels
          *
          * @see android.hardware.camera2.CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT
-         * @see OutputConfiguration#setDynamicRangeProfile(int)
+         * @see OutputConfiguration#setDynamicRangeProfile
          */
         public boolean is10BitCapable() {
             return mIs10BitCapable;
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 8093764..2350b7c 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -421,7 +421,7 @@
      * {@link android.media.MediaCodec} etc.)
      * or {@link ImageFormat#YCBCR_P010}.</p>
      */
-    public void setDynamicRangeProfile(@Profile int profile) {
+    public void setDynamicRangeProfile(@Profile long profile) {
         mDynamicRangeProfile = profile;
     }
 
@@ -430,7 +430,7 @@
      *
      * @return the currently set dynamic range profile
      */
-    public @Profile int getDynamicRangeProfile() {
+    public @Profile long getDynamicRangeProfile() {
         return mDynamicRangeProfile;
     }
 
@@ -1070,7 +1070,7 @@
         int streamUseCase = source.readInt();
 
         checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
-        int dynamicRangeProfile = source.readInt();
+        long dynamicRangeProfile = source.readLong();
         DynamicRangeProfiles.checkProfileValue(dynamicRangeProfile);
 
         int timestampBase = source.readInt();
@@ -1217,7 +1217,7 @@
         dest.writeInt(mIsMultiResolution ? 1 : 0);
         // writeList doesn't seem to work well with Integer list.
         dest.writeIntArray(convertIntegerToIntList(mSensorPixelModesUsed));
-        dest.writeInt(mDynamicRangeProfile);
+        dest.writeLong(mDynamicRangeProfile);
         dest.writeInt(mStreamUseCase);
         dest.writeInt(mTimestampBase);
         dest.writeInt(mMirrorMode);
@@ -1335,7 +1335,7 @@
     // The sensor pixel modes that this OutputConfiguration will use
     private ArrayList<Integer> mSensorPixelModesUsed;
     // Dynamic range profile
-    private int mDynamicRangeProfile;
+    private long mDynamicRangeProfile;
     // Stream use case
     private int mStreamUseCase;
     // Timestamp base
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index c053c92..c341731 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -957,7 +957,7 @@
     public VirtualDisplay createVirtualDisplay(@Nullable IVirtualDevice virtualDevice,
             @NonNull VirtualDisplayConfig virtualDisplayConfig,
             @Nullable VirtualDisplay.Callback callback,
-            @NonNull Executor executor) {
+            @Nullable Executor executor) {
         return mGlobal.createVirtualDisplay(mContext, null /* projection */, virtualDevice,
                 virtualDisplayConfig, callback, executor, null);
     }
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 889100d..a62bbf6 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -1054,6 +1054,14 @@
         @Nullable private final VirtualDisplay.Callback mCallback;
         @Nullable private final Executor mExecutor;
 
+        /**
+         * Creates a virtual display callback.
+         *
+         * @param callback The callback to call for virtual display events, or {@code null} if the
+         * caller does not wish to receive callback events.
+         * @param executor The executor to call the {@code callback} on. Must not be {@code null} if
+         * the callback is not {@code null}.
+         */
         VirtualDisplayCallback(VirtualDisplay.Callback callback, Executor executor) {
             mCallback = callback;
             mExecutor = mCallback != null ? Objects.requireNonNull(executor) : null;
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 83e1061..be482c9 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -21,7 +21,6 @@
 import android.graphics.Point;
 import android.hardware.SensorManager;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.PowerManager;
 import android.util.IntArray;
 import android.util.Slog;
@@ -351,24 +350,17 @@
     public abstract List<RefreshRateLimitation> getRefreshRateLimitations(int displayId);
 
     /**
-     * Returns the window token of the level of the WindowManager hierarchy to mirror. Returns null
-     * if layer mirroring by SurfaceFlinger should not be performed for the given displayId.
-     * For now, only used for mirroring started from MediaProjection.
-     */
-    public abstract IBinder getWindowTokenClientToMirror(int displayId);
-
-    /**
-     * For the given displayId, updates the window token of the level of the WindowManager hierarchy
-     * to mirror. If windowToken is null, then SurfaceFlinger performs no layer mirroring to the
+     * For the given displayId, updates if WindowManager is responsible for mirroring on that
+     * display. If {@code false}, then SurfaceFlinger performs no layer mirroring to the
      * given display.
-     * For now, only used for mirroring started from MediaProjection.
+     * Only used for mirroring started from MediaProjection.
      */
-    public abstract void setWindowTokenClientToMirror(int displayId, IBinder windowToken);
+    public abstract void setWindowManagerMirroring(int displayId, boolean isMirroring);
 
     /**
      * Returns the default size of the surface associated with the display, or null if the surface
      * is not provided for layer mirroring by SurfaceFlinger.
-     * For now, only used for mirroring started from MediaProjection.
+     * Only used for mirroring started from MediaProjection.
      */
     public abstract Point getDisplaySurfaceDefaultSize(int displayId);
 
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index e292394..b76b98d 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -24,7 +24,6 @@
 import android.hardware.display.DisplayManager.VirtualDisplayFlag;
 import android.media.projection.MediaProjection;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.view.Surface;
@@ -95,11 +94,10 @@
     private int mDisplayIdToMirror = DEFAULT_DISPLAY;
 
     /**
-     * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
-     * should not be performed.
+     * Indicates if WindowManager is responsible for mirroring content to this VirtualDisplay, or
+     * if DisplayManager should record contents instead.
      */
-    @Nullable
-    private IBinder mWindowTokenClientToMirror = null;
+    private boolean mWindowManagerMirroring = false;
 
 
 
@@ -126,7 +124,7 @@
             @Nullable Surface surface,
             @Nullable String uniqueId,
             int displayIdToMirror,
-            @Nullable IBinder windowTokenClientToMirror) {
+            boolean windowManagerMirroring) {
         this.mName = name;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, mName);
@@ -148,7 +146,7 @@
         this.mSurface = surface;
         this.mUniqueId = uniqueId;
         this.mDisplayIdToMirror = displayIdToMirror;
-        this.mWindowTokenClientToMirror = windowTokenClientToMirror;
+        this.mWindowManagerMirroring = windowManagerMirroring;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -227,12 +225,12 @@
     }
 
     /**
-     * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
-     * should not be performed.
+     * Indicates if WindowManager is responsible for mirroring content to this VirtualDisplay, or
+     * if DisplayManager should record contents instead.
      */
     @DataClass.Generated.Member
-    public @Nullable IBinder getWindowTokenClientToMirror() {
-        return mWindowTokenClientToMirror;
+    public boolean isWindowManagerMirroring() {
+        return mWindowManagerMirroring;
     }
 
     @Override
@@ -242,9 +240,9 @@
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
         int flg = 0;
+        if (mWindowManagerMirroring) flg |= 0x100;
         if (mSurface != null) flg |= 0x20;
         if (mUniqueId != null) flg |= 0x40;
-        if (mWindowTokenClientToMirror != null) flg |= 0x100;
         dest.writeInt(flg);
         dest.writeString(mName);
         dest.writeInt(mWidth);
@@ -254,7 +252,6 @@
         if (mSurface != null) dest.writeTypedObject(mSurface, flags);
         if (mUniqueId != null) dest.writeString(mUniqueId);
         dest.writeInt(mDisplayIdToMirror);
-        if (mWindowTokenClientToMirror != null) dest.writeStrongBinder(mWindowTokenClientToMirror);
     }
 
     @Override
@@ -269,6 +266,7 @@
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
         int flg = in.readInt();
+        boolean windowManagerMirroring = (flg & 0x100) != 0;
         String name = in.readString();
         int width = in.readInt();
         int height = in.readInt();
@@ -277,7 +275,6 @@
         Surface surface = (flg & 0x20) == 0 ? null : (Surface) in.readTypedObject(Surface.CREATOR);
         String uniqueId = (flg & 0x40) == 0 ? null : in.readString();
         int displayIdToMirror = in.readInt();
-        IBinder windowTokenClientToMirror = (flg & 0x100) == 0 ? null : (IBinder) in.readStrongBinder();
 
         this.mName = name;
         com.android.internal.util.AnnotationValidations.validate(
@@ -300,7 +297,7 @@
         this.mSurface = surface;
         this.mUniqueId = uniqueId;
         this.mDisplayIdToMirror = displayIdToMirror;
-        this.mWindowTokenClientToMirror = windowTokenClientToMirror;
+        this.mWindowManagerMirroring = windowManagerMirroring;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -334,7 +331,7 @@
         private @Nullable Surface mSurface;
         private @Nullable String mUniqueId;
         private int mDisplayIdToMirror;
-        private @Nullable IBinder mWindowTokenClientToMirror;
+        private boolean mWindowManagerMirroring;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -470,14 +467,14 @@
         }
 
         /**
-         * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring
-         * should not be performed.
+         * Indicates if WindowManager is responsible for mirroring content to this VirtualDisplay, or
+         * if DisplayManager should record contents instead.
          */
         @DataClass.Generated.Member
-        public @NonNull Builder setWindowTokenClientToMirror(@NonNull IBinder value) {
+        public @NonNull Builder setWindowManagerMirroring(boolean value) {
             checkNotUsed();
             mBuilderFieldsSet |= 0x100;
-            mWindowTokenClientToMirror = value;
+            mWindowManagerMirroring = value;
             return this;
         }
 
@@ -499,7 +496,7 @@
                 mDisplayIdToMirror = DEFAULT_DISPLAY;
             }
             if ((mBuilderFieldsSet & 0x100) == 0) {
-                mWindowTokenClientToMirror = null;
+                mWindowManagerMirroring = false;
             }
             VirtualDisplayConfig o = new VirtualDisplayConfig(
                     mName,
@@ -510,7 +507,7 @@
                     mSurface,
                     mUniqueId,
                     mDisplayIdToMirror,
-                    mWindowTokenClientToMirror);
+                    mWindowManagerMirroring);
             return o;
         }
 
@@ -523,10 +520,10 @@
     }
 
     @DataClass.Generated(
-            time = 1643938791506L,
+            time = 1646227247934L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java",
-            inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate @android.hardware.display.DisplayManager.VirtualDisplayFlag int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate  int mDisplayIdToMirror\nprivate @android.annotation.Nullable android.os.IBinder mWindowTokenClientToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
+            inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate @android.hardware.display.DisplayManager.VirtualDisplayFlag int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate  int mDisplayIdToMirror\nprivate  boolean mWindowManagerMirroring\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)")
     @Deprecated
     private void __metadata() {}
 
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/hardware/input/VirtualKeyEvent.java b/core/java/android/hardware/input/VirtualKeyEvent.java
index 26d74df..80a49c9 100644
--- a/core/java/android/hardware/input/VirtualKeyEvent.java
+++ b/core/java/android/hardware/input/VirtualKeyEvent.java
@@ -56,6 +56,124 @@
     public @interface Action {
     }
 
+    /**
+     * The set of allowed keycodes.
+     * @hide
+     */
+    @IntDef(prefix = { "KEYCODE_" }, value = {
+            KeyEvent.KEYCODE_0,
+            KeyEvent.KEYCODE_1,
+            KeyEvent.KEYCODE_2,
+            KeyEvent.KEYCODE_3,
+            KeyEvent.KEYCODE_4,
+            KeyEvent.KEYCODE_5,
+            KeyEvent.KEYCODE_6,
+            KeyEvent.KEYCODE_7,
+            KeyEvent.KEYCODE_8,
+            KeyEvent.KEYCODE_9,
+            KeyEvent.KEYCODE_A,
+            KeyEvent.KEYCODE_B,
+            KeyEvent.KEYCODE_C,
+            KeyEvent.KEYCODE_D,
+            KeyEvent.KEYCODE_E,
+            KeyEvent.KEYCODE_F,
+            KeyEvent.KEYCODE_G,
+            KeyEvent.KEYCODE_H,
+            KeyEvent.KEYCODE_I,
+            KeyEvent.KEYCODE_J,
+            KeyEvent.KEYCODE_K,
+            KeyEvent.KEYCODE_L,
+            KeyEvent.KEYCODE_M,
+            KeyEvent.KEYCODE_N,
+            KeyEvent.KEYCODE_O,
+            KeyEvent.KEYCODE_P,
+            KeyEvent.KEYCODE_Q,
+            KeyEvent.KEYCODE_R,
+            KeyEvent.KEYCODE_S,
+            KeyEvent.KEYCODE_T,
+            KeyEvent.KEYCODE_U,
+            KeyEvent.KEYCODE_V,
+            KeyEvent.KEYCODE_W,
+            KeyEvent.KEYCODE_X,
+            KeyEvent.KEYCODE_Y,
+            KeyEvent.KEYCODE_Z,
+            KeyEvent.KEYCODE_F1,
+            KeyEvent.KEYCODE_F2,
+            KeyEvent.KEYCODE_F3,
+            KeyEvent.KEYCODE_F4,
+            KeyEvent.KEYCODE_F5,
+            KeyEvent.KEYCODE_F6,
+            KeyEvent.KEYCODE_F7,
+            KeyEvent.KEYCODE_F8,
+            KeyEvent.KEYCODE_F9,
+            KeyEvent.KEYCODE_F10,
+            KeyEvent.KEYCODE_F11,
+            KeyEvent.KEYCODE_F12,
+            KeyEvent.KEYCODE_NUMPAD_0,
+            KeyEvent.KEYCODE_NUMPAD_1,
+            KeyEvent.KEYCODE_NUMPAD_2,
+            KeyEvent.KEYCODE_NUMPAD_3,
+            KeyEvent.KEYCODE_NUMPAD_4,
+            KeyEvent.KEYCODE_NUMPAD_5,
+            KeyEvent.KEYCODE_NUMPAD_6,
+            KeyEvent.KEYCODE_NUMPAD_7,
+            KeyEvent.KEYCODE_NUMPAD_8,
+            KeyEvent.KEYCODE_NUMPAD_9,
+            KeyEvent.KEYCODE_NUMPAD_DIVIDE,
+            KeyEvent.KEYCODE_NUMPAD_MULTIPLY,
+            KeyEvent.KEYCODE_NUMPAD_SUBTRACT,
+            KeyEvent.KEYCODE_NUMPAD_ADD,
+            KeyEvent.KEYCODE_NUMPAD_DOT,
+            KeyEvent.KEYCODE_NUMPAD_COMMA,
+            KeyEvent.KEYCODE_NUMPAD_ENTER,
+            KeyEvent.KEYCODE_NUMPAD_EQUALS,
+            KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN,
+            KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN,
+            KeyEvent.KEYCODE_GRAVE,
+            KeyEvent.KEYCODE_MINUS,
+            KeyEvent.KEYCODE_EQUALS,
+            KeyEvent.KEYCODE_LEFT_BRACKET,
+            KeyEvent.KEYCODE_RIGHT_BRACKET,
+            KeyEvent.KEYCODE_BACKSLASH,
+            KeyEvent.KEYCODE_SEMICOLON,
+            KeyEvent.KEYCODE_APOSTROPHE,
+            KeyEvent.KEYCODE_COMMA,
+            KeyEvent.KEYCODE_PERIOD,
+            KeyEvent.KEYCODE_SLASH,
+            KeyEvent.KEYCODE_ALT_LEFT,
+            KeyEvent.KEYCODE_ALT_RIGHT,
+            KeyEvent.KEYCODE_CTRL_LEFT,
+            KeyEvent.KEYCODE_CTRL_RIGHT,
+            KeyEvent.KEYCODE_SHIFT_LEFT,
+            KeyEvent.KEYCODE_SHIFT_RIGHT,
+            KeyEvent.KEYCODE_META_LEFT,
+            KeyEvent.KEYCODE_META_RIGHT,
+            KeyEvent.KEYCODE_CAPS_LOCK,
+            KeyEvent.KEYCODE_SCROLL_LOCK,
+            KeyEvent.KEYCODE_NUM_LOCK,
+            KeyEvent.KEYCODE_ENTER,
+            KeyEvent.KEYCODE_TAB,
+            KeyEvent.KEYCODE_SPACE,
+            KeyEvent.KEYCODE_DPAD_DOWN,
+            KeyEvent.KEYCODE_DPAD_UP,
+            KeyEvent.KEYCODE_DPAD_LEFT,
+            KeyEvent.KEYCODE_DPAD_RIGHT,
+            KeyEvent.KEYCODE_MOVE_END,
+            KeyEvent.KEYCODE_MOVE_HOME,
+            KeyEvent.KEYCODE_PAGE_DOWN,
+            KeyEvent.KEYCODE_PAGE_UP,
+            KeyEvent.KEYCODE_DEL,
+            KeyEvent.KEYCODE_FORWARD_DEL,
+            KeyEvent.KEYCODE_INSERT,
+            KeyEvent.KEYCODE_ESCAPE,
+            KeyEvent.KEYCODE_BREAK,
+            KeyEvent.KEYCODE_BACK,
+            KeyEvent.KEYCODE_FORWARD,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SupportedKeycode {
+    }
+
     private final @Action int mAction;
     private final int mKeyCode;
 
@@ -114,60 +232,11 @@
         }
 
         /**
-         * Sets the Android key code of the event. The set of allowed keys include digits
-         *              {@link android.view.KeyEvent#KEYCODE_0} through
-         *              {@link android.view.KeyEvent#KEYCODE_9}, characters
-         *              {@link android.view.KeyEvent#KEYCODE_A} through
-         *              {@link android.view.KeyEvent#KEYCODE_Z}, function keys
-         *              {@link android.view.KeyEvent#KEYCODE_F1} through
-         *              {@link android.view.KeyEvent#KEYCODE_F12}, numpad keys
-         *              {@link android.view.KeyEvent#KEYCODE_NUMPAD_0} through
-         *              {@link android.view.KeyEvent#KEYCODE_NUMPAD_RIGHT_PAREN},
-         *              and these additional keys:
-         *              {@link android.view.KeyEvent#KEYCODE_GRAVE}
-         *              {@link android.view.KeyEvent#KEYCODE_MINUS}
-         *              {@link android.view.KeyEvent#KEYCODE_EQUALS}
-         *              {@link android.view.KeyEvent#KEYCODE_LEFT_BRACKET}
-         *              {@link android.view.KeyEvent#KEYCODE_RIGHT_BRACKET}
-         *              {@link android.view.KeyEvent#KEYCODE_BACKSLASH}
-         *              {@link android.view.KeyEvent#KEYCODE_SEMICOLON}
-         *              {@link android.view.KeyEvent#KEYCODE_APOSTROPHE}
-         *              {@link android.view.KeyEvent#KEYCODE_COMMA}
-         *              {@link android.view.KeyEvent#KEYCODE_PERIOD}
-         *              {@link android.view.KeyEvent#KEYCODE_SLASH}
-         *              {@link android.view.KeyEvent#KEYCODE_ALT_LEFT}
-         *              {@link android.view.KeyEvent#KEYCODE_ALT_RIGHT}
-         *              {@link android.view.KeyEvent#KEYCODE_CTRL_LEFT}
-         *              {@link android.view.KeyEvent#KEYCODE_CTRL_RIGHT}
-         *              {@link android.view.KeyEvent#KEYCODE_SHIFT_LEFT}
-         *              {@link android.view.KeyEvent#KEYCODE_SHIFT_RIGHT}
-         *              {@link android.view.KeyEvent#KEYCODE_META_LEFT}
-         *              {@link android.view.KeyEvent#KEYCODE_META_RIGHT}
-         *              {@link android.view.KeyEvent#KEYCODE_CAPS_LOCK}
-         *              {@link android.view.KeyEvent#KEYCODE_SCROLL_LOCK}
-         *              {@link android.view.KeyEvent#KEYCODE_NUM_LOCK}
-         *              {@link android.view.KeyEvent#KEYCODE_ENTER}
-         *              {@link android.view.KeyEvent#KEYCODE_TAB}
-         *              {@link android.view.KeyEvent#KEYCODE_SPACE}
-         *              {@link android.view.KeyEvent#KEYCODE_DPAD_DOWN}
-         *              {@link android.view.KeyEvent#KEYCODE_DPAD_UP}
-         *              {@link android.view.KeyEvent#KEYCODE_DPAD_LEFT}
-         *              {@link android.view.KeyEvent#KEYCODE_DPAD_RIGHT}
-         *              {@link android.view.KeyEvent#KEYCODE_MOVE_END}
-         *              {@link android.view.KeyEvent#KEYCODE_MOVE_HOME}
-         *              {@link android.view.KeyEvent#KEYCODE_PAGE_DOWN}
-         *              {@link android.view.KeyEvent#KEYCODE_PAGE_UP}
-         *              {@link android.view.KeyEvent#KEYCODE_DEL}
-         *              {@link android.view.KeyEvent#KEYCODE_FORWARD_DEL}
-         *              {@link android.view.KeyEvent#KEYCODE_INSERT}
-         *              {@link android.view.KeyEvent#KEYCODE_ESCAPE}
-         *              {@link android.view.KeyEvent#KEYCODE_BREAK}
-         *              {@link android.view.KeyEvent#KEYCODE_BACK}
-         *              {@link android.view.KeyEvent#KEYCODE_FORWARD}
+         * Sets the Android key code of the event.
          *
          * @return this builder, to allow for chaining of calls
          */
-        public @NonNull Builder setKeyCode(int keyCode) {
+        public @NonNull Builder setKeyCode(@SupportedKeycode int keyCode) {
             mKeyCode = keyCode;
             return this;
         }
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index bf4b514..eed92c1 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -37,6 +37,8 @@
 import android.os.RemoteException;
 import android.util.Log;
 
+import java.io.IOException;
+
 /**
  * The SoundTriggerModule provides APIs to control sound models and sound detection
  * on a given sound trigger hardware module.
@@ -137,13 +139,39 @@
             if (model instanceof SoundTrigger.GenericSoundModel) {
                 SoundModel aidlModel = ConversionUtil.api2aidlGenericSoundModel(
                         (SoundTrigger.GenericSoundModel) model);
-                soundModelHandle[0] = mService.loadModel(aidlModel);
+                try {
+                    soundModelHandle[0] = mService.loadModel(aidlModel);
+                } finally {
+                    // TODO(b/219825762): We should be able to use the entire object in a
+                    //  try-with-resources
+                    //   clause, instead of having to explicitly close internal fields.
+                    if (aidlModel.data != null) {
+                        try {
+                            aidlModel.data.close();
+                        } catch (IOException e) {
+                            Log.e(TAG, "Failed to close file", e);
+                        }
+                    }
+                }
                 return SoundTrigger.STATUS_OK;
             }
             if (model instanceof SoundTrigger.KeyphraseSoundModel) {
                 PhraseSoundModel aidlModel = ConversionUtil.api2aidlPhraseSoundModel(
                         (SoundTrigger.KeyphraseSoundModel) model);
-                soundModelHandle[0] = mService.loadPhraseModel(aidlModel);
+                try {
+                    soundModelHandle[0] = mService.loadPhraseModel(aidlModel);
+                } finally {
+                    // TODO(b/219825762): We should be able to use the entire object in a
+                    //  try-with-resources
+                    //   clause, instead of having to explicitly close internal fields.
+                    if (aidlModel.common.data != null) {
+                        try {
+                            aidlModel.common.data.close();
+                        } catch (IOException e) {
+                            Log.e(TAG, "Failed to close file", e);
+                        }
+                    }
+                }
                 return SoundTrigger.STATUS_OK;
             }
             return SoundTrigger.STATUS_BAD_VALUE;
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/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index c3e3180..656aea1 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -83,6 +83,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.Process;
 import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.os.SystemProperties;
@@ -139,6 +140,7 @@
 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.view.IInlineSuggestionsRequestCallback;
@@ -346,7 +348,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);
     }
 
     /**
@@ -659,7 +661,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.");
@@ -672,8 +674,7 @@
             if (stylusHwSupported) {
                 mInkWindow = new InkWindow(mWindow.getContext());
             }
-            mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
-                    shouldShowImeSwitcherWhenImeIsShown);
+            mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
             attachToken(token);
             Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
         }
@@ -783,10 +784,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 {
@@ -800,10 +800,8 @@
          */
         @MainThread
         @Override
-        public void onShouldShowImeSwitcherWhenImeIsShownChanged(
-                boolean shouldShowImeSwitcherWhenImeIsShown) {
-            mNavigationBarController.setShouldShowImeSwitcherWhenImeIsShown(
-                    shouldShowImeSwitcherWhenImeIsShown);
+        public void onNavButtonFlagsChanged(@InputMethodNavButtonFlags int navButtonFlags) {
+            mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
         }
 
         /**
@@ -926,7 +924,7 @@
                 mOnPreparedStylusHwCalled = true;
             }
             if (onStartStylusHandwriting()) {
-                mPrivOps.onStylusHandwritingReady(requestId);
+                mPrivOps.onStylusHandwritingReady(requestId, Process.myPid());
             } else {
                 Log.i(TAG, "IME is not ready. Can't start Stylus Handwriting");
                 // TODO(b/210039666): see if it's valuable to propagate this back to IMM.
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/RemoteInputConnection.java b/core/java/android/inputmethodservice/RemoteInputConnection.java
index 6b7815d..5b0129e 100644
--- a/core/java/android/inputmethodservice/RemoteInputConnection.java
+++ b/core/java/android/inputmethodservice/RemoteInputConnection.java
@@ -433,6 +433,26 @@
                 mCancellationGroup, MAX_WAIT_TIME_MILLIS);
     }
 
+    @Override
+    @AnyThread
+    public boolean requestCursorUpdates(@CursorUpdateMode int cursorUpdateMode,
+            @CursorUpdateFilter int cursorUpdateFilter) {
+        if (mCancellationGroup.isCanceled()) {
+            return false;
+        }
+
+        final InputMethodServiceInternal ims = mImsInternal.getAndWarnIfNull();
+        if (ims == null) {
+            return false;
+        }
+
+        final int displayId = ims.getContext().getDisplayId();
+        final CompletableFuture<Boolean> value =
+                mInvoker.requestCursorUpdates(cursorUpdateMode, cursorUpdateFilter, displayId);
+        return CompletableFutureUtil.getResultOrFalse(value, TAG, "requestCursorUpdates()",
+                mCancellationGroup, MAX_WAIT_TIME_MILLIS);
+    }
+
     @AnyThread
     public Handler getHandler() {
         // Nothing should happen when called from input method.
diff --git a/core/java/android/net/PlatformVpnProfile.java b/core/java/android/net/PlatformVpnProfile.java
index c0fb4cf..6b6f1ca 100644
--- a/core/java/android/net/PlatformVpnProfile.java
+++ b/core/java/android/net/PlatformVpnProfile.java
@@ -100,7 +100,7 @@
      * always gain the {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} capability
      * immediately after it connects, whether it can reach public Internet destinations or not.
      */
-    public final boolean getRequiresInternetValidation() {
+    public final boolean isInternetValidationRequired() {
         return mRequiresInternetValidation;
     }
 
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index 779d931..c51444c 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -108,7 +108,7 @@
      * <ul>
      *   <li>{@link #EXTRA_SESSION_KEY}, a {@code String} for the session key, as returned by
      *       {@link #startProvisionedVpnProfileSession}.
-     *   <li>{@link #EXTRA_TIMESTAMP}, a long for the timestamp at which the error occurred,
+     *   <li>{@link #EXTRA_TIMESTAMP_MILLIS}, a long for the timestamp at which the error occurred,
      *       in milliseconds since the epoch, as returned by
      *       {@link java.lang.System#currentTimeMillis}.
      *   <li>{@link #EXTRA_UNDERLYING_NETWORK}, a {@link Network} containing the underlying
@@ -196,7 +196,7 @@
      * This is a number of milliseconds since the epoch, suitable to be compared with
      * {@link java.lang.System#currentTimeMillis}.
      */
-    public static final String EXTRA_TIMESTAMP = "android.net.extra.TIMESTAMP";
+    public static final String EXTRA_TIMESTAMP_MILLIS = "android.net.extra.TIMESTAMP_MILLIS";
 
     /**
      * Extra for the error class, as an {@code int}.
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/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 9a780c8..2b34d86 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -25,6 +25,7 @@
 import android.app.ActivityThread;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.nfc.INfcCardEmulation;
@@ -62,7 +63,9 @@
      * replace the current default service with the service
      * identified with the ComponentName specified in
      * {@link #EXTRA_SERVICE_COMPONENT}, for the category
-     * specified in {@link #EXTRA_CATEGORY}
+     * specified in {@link #EXTRA_CATEGORY}. There is an optional
+     * extra field using {@link Intent#EXTRA_USER} to specify
+     * the {@link UserHandle} of the user that owns the app.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_CHANGE_DEFAULT =
diff --git a/core/java/android/os/AppZygote.java b/core/java/android/os/AppZygote.java
index c8b4226e..07fbe4a 100644
--- a/core/java/android/os/AppZygote.java
+++ b/core/java/android/os/AppZygote.java
@@ -17,9 +17,11 @@
 package android.os;
 
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ProcessInfo;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.Zygote;
 
 import dalvik.system.VMRuntime;
 
@@ -45,8 +47,6 @@
     // Last UID/GID of the range the AppZygote can setuid()/setgid() to
     private final int mZygoteUidGidMax;
 
-    private final int mZygoteRuntimeFlags;
-
     private final Object mLock = new Object();
 
     /**
@@ -57,14 +57,15 @@
     private ChildZygoteProcess mZygote;
 
     private final ApplicationInfo mAppInfo;
+    private final ProcessInfo mProcessInfo;
 
-    public AppZygote(ApplicationInfo appInfo, int zygoteUid, int uidGidMin, int uidGidMax,
-            int runtimeFlags) {
+    public AppZygote(ApplicationInfo appInfo, ProcessInfo processInfo, int zygoteUid, int uidGidMin,
+            int uidGidMax) {
         mAppInfo = appInfo;
+        mProcessInfo = processInfo;
         mZygoteUid = zygoteUid;
         mZygoteUidGidMin = uidGidMin;
         mZygoteUidGidMax = uidGidMax;
-        mZygoteRuntimeFlags = runtimeFlags;
     }
 
     /**
@@ -108,13 +109,15 @@
         String abi = mAppInfo.primaryCpuAbi != null ? mAppInfo.primaryCpuAbi :
                 Build.SUPPORTED_ABIS[0];
         try {
+            int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote(
+                    mAppInfo, mProcessInfo);
             mZygote = Process.ZYGOTE_PROCESS.startChildZygote(
                     "com.android.internal.os.AppZygoteInit",
                     mAppInfo.processName + "_zygote",
                     mZygoteUid,
                     mZygoteUid,
                     null,  // gids
-                    mZygoteRuntimeFlags,  // runtimeFlags
+                    runtimeFlags,
                     "app_zygote",  // seInfo
                     abi,  // abi
                     abi, // acceptedAbiList
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 45812e5..e5dab05 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -1453,7 +1453,7 @@
 
     @SuppressWarnings("unchecked")
     @Nullable
-    <T> ArrayList<T> getArrayList(@Nullable String key, @NonNull Class<T> clazz) {
+    <T> ArrayList<T> getArrayList(@Nullable String key, @NonNull Class<? extends T> clazz) {
         unparcel();
         try {
             return getValue(key, ArrayList.class, requireNonNull(clazz));
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 1d1f17d..1c85f69 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -285,13 +285,20 @@
         public static final String RELEASE = getString("ro.build.version.release");
 
         /**
-         * The version string we show to the user; may be {@link #RELEASE} or
-         * {@link #CODENAME} if not a final release build.
+         * The version string.  May be {@link #RELEASE} or {@link #CODENAME} if
+         * not a final release build.
          */
         @NonNull public static final String RELEASE_OR_CODENAME = getString(
                 "ro.build.version.release_or_codename");
 
         /**
+         * The version string we show to the user; may be {@link #RELEASE} or
+         * a descriptive string if not a final release build.
+         */
+        @NonNull public static final String RELEASE_OR_PREVIEW_DISPLAY = getString(
+                "ro.build.version.release_or_preview_display");
+
+        /**
          * The base OS build the product is based on.
          */
         public static final String BASE_OS = SystemProperties.get("ro.build.version.base_os", "");
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index edbbb59..a19b51b 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -1059,7 +1059,8 @@
     @SuppressLint("NullableCollection")
     @SuppressWarnings("unchecked")
     @Nullable
-    public <T> ArrayList<T> getParcelableArrayList(@Nullable String key, @NonNull Class<T> clazz) {
+    public <T> ArrayList<T> getParcelableArrayList(@Nullable String key,
+            @NonNull Class<? extends T> clazz) {
         // The reason for not using <T extends Parcelable> is because the caller could provide a
         // super class to restrict the children that doesn't implement Parcelable itself while the
         // children do, more details at b/210800751 (same reasoning applies here).
@@ -1107,7 +1108,7 @@
     @SuppressWarnings("unchecked")
     @Nullable
     public <T> SparseArray<T> getSparseParcelableArray(@Nullable String key,
-            @NonNull Class<T> clazz) {
+            @NonNull Class<? extends T> clazz) {
         // The reason for not using <T extends Parcelable> is because the caller could provide a
         // super class to restrict the children that doesn't implement Parcelable itself while the
         // children do, more details at b/210800751 (same reasoning applies here).
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 3d12941..0a7a407 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -29,7 +29,6 @@
 import android.compat.annotation.Disabled;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.os.storage.StorageManager;
@@ -101,6 +100,7 @@
     private static final File DIR_ANDROID_EXPAND = getDirectory(ENV_ANDROID_EXPAND, "/mnt/expand");
     private static final File DIR_ANDROID_STORAGE = getDirectory(ENV_ANDROID_STORAGE, "/storage");
     private static final File DIR_DOWNLOAD_CACHE = getDirectory(ENV_DOWNLOAD_CACHE, "/cache");
+    private static final File DIR_METADATA = new File("/metadata");
     private static final File DIR_OEM_ROOT = getDirectory(ENV_OEM_ROOT, "/oem");
     private static final File DIR_ODM_ROOT = getDirectory(ENV_ODM_ROOT, "/odm");
     private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
@@ -1098,6 +1098,15 @@
     }
 
     /**
+     * Return the metadata directory.
+     *
+     * @hide
+     */
+    public static @NonNull File getMetadataDirectory() {
+        return DIR_METADATA;
+    }
+
+    /**
      * Unknown storage state, such as when a path isn't backed by known storage
      * media.
      *
@@ -1333,7 +1342,7 @@
         final Context context = AppGlobals.getInitialApplication();
         final int uid = context.getApplicationInfo().uid;
         // Isolated processes and Instant apps are never allowed to be in scoped storage
-        if (Process.isIsolated(uid) || Process.isSupplemental(uid)) {
+        if (Process.isIsolated(uid) || Process.isSdkSandboxUid(uid)) {
             return false;
         }
 
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/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/OWNERS b/core/java/android/os/OWNERS
index 5d9f2189..8e5ed8f 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -52,6 +52,9 @@
 per-file *Telephony* = file:/telephony/OWNERS
 per-file *Zygote* = file:/ZYGOTE_OWNERS
 
+# Time
+per-file *Clock* = file:/services/core/java/com/android/server/timezonedetector/OWNERS
+
 # RecoverySystem
 per-file *Recovery* = file:/services/core/java/com/android/server/recoverysystem/OWNERS
 
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 09cfb6e..978e99d 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -201,7 +201,7 @@
  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
  * {@link #readFileDescriptor()}.
  *
- * <h3>Untyped Containers</h3>
+  * <h3>Parcelable Containers</h3>
  *
  * <p>A final class of methods are for writing and reading standard Java
  * containers of arbitrary types.  These all revolve around the
@@ -213,6 +213,19 @@
  * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
  * {@link #writeSparseArray(SparseArray)},
  * {@link #readSparseArray(ClassLoader)}.
+ *
+ * <h3>Restricted Parcelable Containers</h3>
+ *
+ * <p>A final class of methods are for reading standard Java containers of restricted types.
+ * These methods replace methods for reading containers of arbitrary types from previous section
+ * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. The pairing writing methods are
+ * still the same from previous section.
+ * These methods accepts additional {@code clazz} parameters as the required types.
+ * The Restricted Parcelable container methods are {@link #readArray(ClassLoader, Class)},
+ * {@link #readList(List, ClassLoader, Class)},
+ * {@link #readArrayList(ClassLoader, Class)},
+ * {@link #readMap(Map, ClassLoader, Class, Class)},
+ * {@link #readSparseArray(ClassLoader, Class)}.
  */
 public final class Parcel {
 
@@ -3839,7 +3852,7 @@
      */
     @NonNull
     public <T> List<T> readParcelableList(@NonNull List<T> list,
-            @Nullable ClassLoader cl, @NonNull Class<T> clazz) {
+            @Nullable ClassLoader cl, @NonNull Class<? extends T> clazz) {
         Objects.requireNonNull(list);
         Objects.requireNonNull(clazz);
         return readParcelableListInternal(list, cl, clazz);
@@ -3850,7 +3863,7 @@
      */
     @NonNull
     private <T> List<T> readParcelableListInternal(@NonNull List<T> list,
-            @Nullable ClassLoader cl, @Nullable Class<T> clazz) {
+            @Nullable ClassLoader cl, @Nullable Class<? extends T> clazz) {
         final int n = readInt();
         if (n == -1) {
             list.clear();
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 315eef7..e3be4d3 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -183,25 +183,29 @@
     /**
      * Wake lock flag: Turn the screen on when the wake lock is acquired.
      * <p>
-     * Normally wake locks don't actually wake the device, they just cause
-     * the screen to remain on once it's already on.  Think of the video player
-     * application as the normal behavior.  Notifications that pop up and want
-     * the device to be on are the exception; use this flag to be like them.
+     * Normally wake locks don't actually wake the device, they just cause the screen to remain on
+     * once it's already on. This flag will cause the device to wake up when the wake lock is
+     * acquired.
      * </p><p>
      * Android TV playback devices attempt to turn on the HDMI-connected TV via HDMI-CEC on any
      * wake-up, including wake-ups triggered by wake locks.
      * </p><p>
      * Cannot be used with {@link #PARTIAL_WAKE_LOCK}.
      * </p>
+     *
+     * @deprecated Most applications should use {@link android.R.attr#turnScreenOn} or
+     * {@link android.app.Activity#setTurnScreenOn(boolean)} instead, as this prevents the previous
+     * foreground app from being resumed first when the screen turns on. Note that this flag may
+     * require a permission in the future.
      */
+    @Deprecated
     public static final int ACQUIRE_CAUSES_WAKEUP = 0x10000000;
 
     /**
      * Wake lock flag: When this wake lock is released, poke the user activity timer
      * so the screen stays on for a little longer.
      * <p>
-     * Will not turn the screen on if it is not already on.
-     * See {@link #ACQUIRE_CAUSES_WAKEUP} if you want that.
+     * This will not turn the screen on if it is not already on.
      * </p><p>
      * Cannot be used with {@link #PARTIAL_WAKE_LOCK}.
      * </p>
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 17b5ec5..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
@@ -281,23 +289,23 @@
 
     /**
      * Defines the start of a range of UIDs going from this number to
-     * {@link #LAST_SUPPLEMENTAL_UID} that are reserved for assigning to
-     * supplemental processes. There is a 1-1 mapping between a supplemental
+     * {@link #LAST_SDK_SANDBOX_UID} that are reserved for assigning to
+     * sdk sandbox processes. There is a 1-1 mapping between a sdk sandbox
      * process UID and the app that it belongs to, which can be computed by
-     * subtracting (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID) from the
-     * uid of a supplemental process.
+     * subtracting (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID) from the
+     * uid of a sdk sandbox process.
      *
      * Note that there are no GIDs associated with these processes; storage
      * attribution for them will be done using project IDs.
      * @hide
      */
-    public static final int FIRST_SUPPLEMENTAL_UID = 20000;
+    public static final int FIRST_SDK_SANDBOX_UID = 20000;
 
     /**
-     * Last UID that is used for supplemental processes.
+     * Last UID that is used for sdk sandbox processes.
      * @hide
      */
-    public static final int LAST_SUPPLEMENTAL_UID = 29999;
+    public static final int LAST_SDK_SANDBOX_UID = 29999;
 
     /**
      * First uid used for fully isolated sandboxed processes spawned from an app zygote
@@ -374,7 +382,7 @@
      * ** Keep in sync with utils/threads.h **
      * ***************************************
      */
-    
+
     /**
      * Lowest available thread priority.  Only for those who really, really
      * don't want to run if anything else is happening.
@@ -383,7 +391,7 @@
      * {@link java.lang.Thread} class.
      */
     public static final int THREAD_PRIORITY_LOWEST = 19;
-    
+
     /**
      * Standard priority background threads.  This gives your thread a slightly
      * lower than normal priority, so that it will have less chance of impacting
@@ -393,7 +401,7 @@
      * {@link java.lang.Thread} class.
      */
     public static final int THREAD_PRIORITY_BACKGROUND = 10;
-    
+
     /**
      * Standard priority of threads that are currently running a user interface
      * that the user is interacting with.  Applications can not normally
@@ -404,7 +412,7 @@
      * {@link java.lang.Thread} class.
      */
     public static final int THREAD_PRIORITY_FOREGROUND = -2;
-    
+
     /**
      * Standard priority of system display threads, involved in updating
      * the user interface.  Applications can not
@@ -414,7 +422,7 @@
      * {@link java.lang.Thread} class.
      */
     public static final int THREAD_PRIORITY_DISPLAY = -4;
-    
+
     /**
      * Standard priority of the most important display threads, for compositing
      * the screen and retrieving input events.  Applications can not normally
@@ -654,19 +662,19 @@
 
     /**
      * Start a new process.
-     * 
+     *
      * <p>If processes are enabled, a new process is created and the
      * static main() function of a <var>processClass</var> is executed there.
      * The process will continue running after this function returns.
-     * 
+     *
      * <p>If processes are not enabled, a new thread in the caller's
      * process is created and main() of <var>processClass</var> called there.
-     * 
+     *
      * <p>The niceName parameter, if not an empty string, is a custom name to
      * give to the process instead of using processClass.  This allows you to
      * make easily identifyable processes even if you are using the same base
      * <var>processClass</var> to start them.
-     * 
+     *
      * When invokeWith is not null, the process will be started as a fresh app
      * and not a zygote fork. Note that this is only allowed for uid 0 or when
      * runtimeFlags contains DEBUG_ENABLE_DEBUGGER.
@@ -901,44 +909,46 @@
     }
 
     /**
-     * Returns whether the provided UID belongs to a supplemental process.
-     *
-     * @hide
-     */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final boolean isSupplemental(int uid) {
-        uid = UserHandle.getAppId(uid);
-        return (uid >= FIRST_SUPPLEMENTAL_UID && uid <= LAST_SUPPLEMENTAL_UID);
-    }
-
-    /**
-     *
-     * Returns the app process corresponding to a supplemental process.
-     *
-     * @hide
-     */
-    @SystemApi(client = MODULE_LIBRARIES)
-    public static final int toAppUid(int uid) {
-        return uid - (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID);
-    }
-
-    /**
-     *
-     * Returns the supplemental process corresponding to an app process.
+     * Returns whether the provided UID belongs to a SDK sandbox process.
      *
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
     @TestApi
-    public static final int toSupplementalUid(int uid) {
-        return uid + (FIRST_SUPPLEMENTAL_UID - FIRST_APPLICATION_UID);
+    public static final boolean isSdkSandboxUid(int uid) {
+        uid = UserHandle.getAppId(uid);
+        return (uid >= FIRST_SDK_SANDBOX_UID && uid <= LAST_SDK_SANDBOX_UID);
     }
 
     /**
-     * Returns whether the current process is a supplemental process.
+     *
+     * Returns the app process corresponding to an sdk sandbox process.
+     *
+     * @hide
      */
-    public static final boolean isSupplemental() {
-        return isSupplemental(myUid());
+    @SystemApi(client = MODULE_LIBRARIES)
+    @TestApi
+    public static final int getAppUidForSdkSandboxUid(int uid) {
+        return uid - (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID);
+    }
+
+    /**
+     *
+     * Returns the sdk sandbox process corresponding to an app process.
+     *
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @TestApi
+    public static final int toSdkSandboxUid(int uid) {
+        return uid + (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID);
+    }
+
+    /**
+     * Returns whether the current process is a sdk sandbox process.
+     */
+    public static final boolean isSdkSandbox() {
+        return isSdkSandboxUid(myUid());
     }
 
     /**
@@ -947,7 +957,7 @@
      * directly to a uid.
      */
     public static final native int getUidForName(String name);
-    
+
     /**
      * Returns the GID assigned to a particular user name, or -1 if there is
      * none.  If the given string consists of only numbers, it is converted
@@ -1002,11 +1012,11 @@
 
     /**
      * Set the priority of a thread, based on Linux priorities.
-     * 
+     *
      * @param tid The identifier of the thread/process to change.
      * @param priority A Linux priority level, from -20 for highest scheduling
      * priority to 19 for lowest scheduling priority.
-     * 
+     *
      * @throws IllegalArgumentException Throws IllegalArgumentException if
      * <var>tid</var> does not exist.
      * @throws SecurityException Throws SecurityException if your process does
@@ -1065,7 +1075,7 @@
      * @hide
      * @param pid The identifier of the process to change.
      * @param group The target group for this process from THREAD_GROUP_*.
-     * 
+     *
      * @throws IllegalArgumentException Throws IllegalArgumentException if
      * <var>tid</var> does not exist.
      * @throws SecurityException Throws SecurityException if your process does
@@ -1154,37 +1164,37 @@
     /**
      * Set the priority of the calling thread, based on Linux priorities.  See
      * {@link #setThreadPriority(int, int)} for more information.
-     * 
+     *
      * @param priority A Linux priority level, from -20 for highest scheduling
      * priority to 19 for lowest scheduling priority.
-     * 
+     *
      * @throws IllegalArgumentException Throws IllegalArgumentException if
      * <var>tid</var> does not exist.
      * @throws SecurityException Throws SecurityException if your process does
      * not have permission to modify the given thread, or to use the given
      * priority.
-     * 
+     *
      * @see #setThreadPriority(int, int)
      */
     public static final native void setThreadPriority(int priority)
             throws IllegalArgumentException, SecurityException;
-    
+
     /**
      * Return the current priority of a thread, based on Linux priorities.
-     * 
+     *
      * @param tid The identifier of the thread/process. If tid equals zero, the priority of the
      * calling process/thread will be returned.
-     * 
+     *
      * @return Returns the current priority, as a Linux priority level,
      * from -20 for highest scheduling priority to 19 for lowest scheduling
      * priority.
-     * 
+     *
      * @throws IllegalArgumentException Throws IllegalArgumentException if
      * <var>tid</var> does not exist.
      */
     public static final native int getThreadPriority(int tid)
             throws IllegalArgumentException;
-    
+
     /**
      * Return the current scheduling policy of a thread, based on Linux.
      *
@@ -1198,7 +1208,7 @@
      *
      * {@hide}
      */
-    
+
     @TestApi
     public static final native int getThreadScheduler(int tid)
             throws IllegalArgumentException;
@@ -1224,7 +1234,7 @@
 
     /**
      * Determine whether the current environment supports multiple processes.
-     * 
+     *
      * @return Returns true if the system can run in multiple processes, else
      * false if everything is running in a single process.
      *
@@ -1251,9 +1261,9 @@
     /**
      * Change this process's argv[0] parameter.  This can be useful to show
      * more descriptive information in things like the 'ps' command.
-     * 
+     *
      * @param text The new name of this process.
-     * 
+     *
      * {@hide}
      */
     @UnsupportedAppUsage(maxTargetSdk = VERSION_CODES.S, publicAlternatives = "Do not try to "
@@ -1301,12 +1311,12 @@
 
     /**
      * Send a signal to the given process.
-     * 
+     *
      * @param pid The pid of the target process.
      * @param signal The signal to send.
      */
     public static final native void sendSignal(int pid, int signal);
-    
+
     /**
      * @hide
      * Private impl for avoiding a log message...  DO NOT USE without doing
@@ -1325,24 +1335,24 @@
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     public static final native void sendSignalQuiet(int pid, int signal);
-    
+
     /** @hide */
     @UnsupportedAppUsage
     public static final native long getFreeMemory();
-    
+
     /** @hide */
     @UnsupportedAppUsage
     public static final native long getTotalMemory();
-    
+
     /** @hide */
     @UnsupportedAppUsage
     public static final native void readProcLines(String path,
             String[] reqFields, long[] outSizes);
-    
+
     /** @hide */
     @UnsupportedAppUsage
     public static final native int[] getPids(String path, int[] lastArray);
-    
+
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static final int PROC_TERM_MASK = 0xff;
@@ -1413,7 +1423,7 @@
 
     /** @hide */
     @UnsupportedAppUsage
-    public static final native boolean parseProcLine(byte[] buffer, int startIndex, 
+    public static final native boolean parseProcLine(byte[] buffer, int startIndex,
             int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
 
     /** @hide */
@@ -1422,10 +1432,10 @@
 
     /**
      * Gets the total Pss value for a given process, in bytes.
-     * 
+     *
      * @param pid the process to the Pss for
      * @return the total Pss value for the given process in bytes,
-     *  or -1 if the value cannot be determined 
+     *  or -1 if the value cannot be determined
      * @hide
      */
     @UnsupportedAppUsage
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 944b717..a3b836a 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -674,10 +674,12 @@
             }
             try {
                 if (!rs.allocateSpaceForUpdate(packageFile)) {
+                    rs.clearBcb();
                     throw new IOException("Failed to allocate space for update "
                             + packageFile.getAbsolutePath());
                 }
             } catch (RemoteException e) {
+                rs.clearBcb();
                 e.rethrowAsRuntimeException();
             }
 
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index e56f214..a715c69 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2574,6 +2574,9 @@
     /**
      * Checks if the context user is a managed profile.
      *
+     * Note that this applies specifically to <em>managed</em> profiles. For profiles in general,
+     * use {@link #isProfile()} instead.
+     *
      * @return whether the context user is a managed profile.
      */
     @UserHandleAware(
@@ -2593,6 +2596,9 @@
      * {@link android.Manifest.permission#QUERY_USERS} permission, otherwise the caller
      * must be in the same profile group of specified user.
      *
+     * Note that this applies specifically to <em>managed</em> profiles. For profiles in general,
+     * use {@link #isProfile()} instead.
+     *
      * @return whether the specified user is a managed profile.
      * @hide
      */
@@ -3322,7 +3328,7 @@
      *
      * <p>This method can be used by OEMs to "warm" up the user creation by pre-creating some users
      * at the first boot, so they when the "real" user is created (for example,
-     * by {@link #createUser(String, String, int)} or {@link #createGuest(Context, String)}), it
+     * by {@link #createUser(String, String, int)} or {@link #createGuest(Context)}), it
      * takes less time.
      *
      * <p>This method completes the majority of work necessary for user creation: it
@@ -3359,7 +3365,6 @@
     /**
      * Creates a guest user and configures it.
      * @param context an application context
-     * @param name the name to set for the user
      * @return the {@link UserInfo} object for the created user, or {@code null} if the user
      *         could not be created.
      *
@@ -3367,20 +3372,19 @@
      */
     @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
             Manifest.permission.CREATE_USERS})
-    public UserInfo createGuest(Context context, String name) {
-        UserInfo guest = null;
+    public UserInfo createGuest(Context context) {
         try {
-            guest = mService.createUserWithThrow(name, USER_TYPE_FULL_GUEST, 0);
+            final UserInfo guest = mService.createUserWithThrow(null, USER_TYPE_FULL_GUEST, 0);
             if (guest != null) {
                 Settings.Secure.putStringForUser(context.getContentResolver(),
                         Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
             }
+            return guest;
         } catch (ServiceSpecificException e) {
             return null;
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
-        return guest;
     }
 
     /**
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 722cdbc..7832dcc 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.
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index cc98339..b501730 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -273,12 +273,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 +680,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 +693,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) {
@@ -3022,9 +3026,17 @@
         }
     }
 
-    /** @hide */
-    @TestApi
+    /**
+     * Returns the authority of the current cloud media provider that was set by the
+     * {@link android.service.storage.ExternalStorageService} holding the
+     * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission via
+     * {@link #setCloudMediaProvider(String)}.
+     *
+     * @hide
+     */
     @Nullable
+    @TestApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public String getCloudMediaProvider() {
         try {
             return mStorageManager.getCloudMediaProvider();
diff --git a/core/java/android/os/vibrator/PrimitiveSegment.java b/core/java/android/os/vibrator/PrimitiveSegment.java
index 58ca978..2d287e9 100644
--- a/core/java/android/os/vibrator/PrimitiveSegment.java
+++ b/core/java/android/os/vibrator/PrimitiveSegment.java
@@ -108,7 +108,7 @@
         Preconditions.checkArgumentInRange(mPrimitiveId, VibrationEffect.Composition.PRIMITIVE_NOOP,
                 VibrationEffect.Composition.PRIMITIVE_LOW_TICK, "primitiveId");
         Preconditions.checkArgumentInRange(mScale, 0f, 1f, "scale");
-        Preconditions.checkArgumentNonnegative(mDelay, "primitive delay should be >= 0");
+        VibrationEffectSegment.checkDurationArgument(mDelay, "delay");
     }
 
     @Override
diff --git a/core/java/android/os/vibrator/RampSegment.java b/core/java/android/os/vibrator/RampSegment.java
index 9e1f636..d7d8c49 100644
--- a/core/java/android/os/vibrator/RampSegment.java
+++ b/core/java/android/os/vibrator/RampSegment.java
@@ -108,14 +108,9 @@
     /** @hide */
     @Override
     public void validate() {
-        Preconditions.checkArgumentNonNegative(mStartFrequencyHz,
-                "Frequencies must all be >= 0, got start frequency of " + mStartFrequencyHz);
-        Preconditions.checkArgumentFinite(mStartFrequencyHz, "startFrequencyHz");
-        Preconditions.checkArgumentNonNegative(mEndFrequencyHz,
-                "Frequencies must all be >= 0, got end frequency of " + mEndFrequencyHz);
-        Preconditions.checkArgumentFinite(mEndFrequencyHz, "endFrequencyHz");
-        Preconditions.checkArgumentNonnegative(mDuration,
-                "Durations must all be >= 0, got " + mDuration);
+        VibrationEffectSegment.checkFrequencyArgument(mStartFrequencyHz, "startFrequencyHz");
+        VibrationEffectSegment.checkFrequencyArgument(mEndFrequencyHz, "endFrequencyHz");
+        VibrationEffectSegment.checkDurationArgument(mDuration, "duration");
         Preconditions.checkArgumentInRange(mStartAmplitude, 0f, 1f, "startAmplitude");
         Preconditions.checkArgumentInRange(mEndAmplitude, 0f, 1f, "endAmplitude");
     }
diff --git a/core/java/android/os/vibrator/StepSegment.java b/core/java/android/os/vibrator/StepSegment.java
index c679511..5a0bbf7 100644
--- a/core/java/android/os/vibrator/StepSegment.java
+++ b/core/java/android/os/vibrator/StepSegment.java
@@ -95,11 +95,8 @@
     /** @hide */
     @Override
     public void validate() {
-        Preconditions.checkArgumentNonNegative(mFrequencyHz,
-                "Frequencies must all be >= 0, got " + mFrequencyHz);
-        Preconditions.checkArgumentFinite(mFrequencyHz, "frequencyHz");
-        Preconditions.checkArgumentNonnegative(mDuration,
-                "Durations must all be >= 0, got " + mDuration);
+        VibrationEffectSegment.checkFrequencyArgument(mFrequencyHz, "frequencyHz");
+        VibrationEffectSegment.checkDurationArgument(mDuration, "duration");
         if (Float.compare(mAmplitude, VibrationEffect.DEFAULT_AMPLITUDE) != 0) {
             Preconditions.checkArgumentInRange(mAmplitude, 0f, 1f, "amplitude");
         }
diff --git a/core/java/android/os/vibrator/VibrationEffectSegment.java b/core/java/android/os/vibrator/VibrationEffectSegment.java
index 979c447..be10553 100644
--- a/core/java/android/os/vibrator/VibrationEffectSegment.java
+++ b/core/java/android/os/vibrator/VibrationEffectSegment.java
@@ -112,6 +112,43 @@
     @NonNull
     public abstract <T extends VibrationEffectSegment> T applyEffectStrength(int effectStrength);
 
+    /**
+     * Checks the given frequency argument is valid to represent a vibration effect frequency in
+     * hertz, i.e. a finite non-negative value.
+     *
+     * @param value the frequency argument value to be checked
+     * @param name the argument name for the error message.
+     *
+     * @hide
+     */
+    public static void checkFrequencyArgument(float value, @NonNull String name) {
+        // Similar to combining Preconditions checkArgumentFinite + checkArgumentNonnegative,
+        // but this implementation doesn't create the error message unless a check fail.
+        if (Float.isNaN(value)) {
+            throw new IllegalArgumentException(name + " must not be NaN");
+        }
+        if (Float.isInfinite(value)) {
+            throw new IllegalArgumentException(name + " must not be infinite");
+        }
+        if (value < 0) {
+            throw new IllegalArgumentException(name + " must be >= 0, got " + value);
+        }
+    }
+
+    /**
+     * Checks the given duration argument is valid, i.e. a non-negative value.
+     *
+     * @param value the duration value to be checked
+     * @param name the argument name for the error message.
+     *
+     * @hide
+     */
+    public static void checkDurationArgument(long value, @NonNull String name) {
+        if (value < 0) {
+            throw new IllegalArgumentException(name + " must be >= 0, got " + value);
+        }
+    }
+
     @NonNull
     public static final Creator<VibrationEffectSegment> CREATOR =
             new Creator<VibrationEffectSegment>() {
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 87f4489..052e4d0 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -407,6 +407,13 @@
     public static final String NAMESPACE_SCHEDULER = "scheduler";
 
     /**
+     * Namespace for all SdkSandbox related features.
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_SDK_SANDBOX = "sdk_sandbox";
+
+    /**
      * Namespace for settings statistics features.
      *
      * @hide
@@ -464,11 +471,11 @@
     public static final String NAMESPACE_STORAGE_NATIVE_BOOT = "storage_native_boot";
 
     /**
-     * Namespace for all Supplemental Api related features.
+     * Namespace for all AdServices related features.
      * @hide
      */
     @SystemApi
-    public static final String NAMESPACE_SUPPLEMENTAL_API = "supplemental_api";
+    public static final String NAMESPACE_ADSERVICES = "adservices";
 
     /**
      * Namespace for all SurfaceFlinger features that are used at the native level.
@@ -586,7 +593,7 @@
     @NonNull
     private static final List<String> PUBLIC_NAMESPACES =
             Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME, NAMESPACE_STATSD_JAVA,
-                    NAMESPACE_STATSD_JAVA_BOOT, NAMESPACE_SELECTION_TOOLBAR);
+                    NAMESPACE_STATSD_JAVA_BOOT, NAMESPACE_SELECTION_TOOLBAR, NAMESPACE_AUTOFILL);
     /**
      * Privacy related properties definitions.
      *
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 23e02e9..cfef7ad 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -24,7 +24,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.StringDef;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
@@ -86,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;
@@ -241,6 +242,20 @@
             "android.settings.TETHER_PROVISIONING_UI";
 
     /**
+     * Activity Action: Show a dialog activity to notify tethering is NOT supported by carrier.
+     *
+     * When {@link android.telephony.CarrierConfigManager#KEY_CARRIER_SUPPORTS_TETHERING_BOOL}
+     * is false, and tethering is started by Settings, this dialog activity will be started to
+     * tell the user that tethering is not supported by carrier.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    @SystemApi
+    public static final String ACTION_TETHER_UNSUPPORTED_CARRIER_UI =
+            "android.settings.TETHER_UNSUPPORTED_CARRIER_UI";
+
+    /**
      * Activity Action: Show settings to allow entering/exiting airplane mode.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -2128,7 +2143,7 @@
     /**
      * Intent extra: The id of a setting restricted by supervisors.
      * <p>
-     * Type: String with a value from the SupervisorVerificationSetting annotation below.
+     * Type: Integer with a value from the SupervisorVerificationSetting annotation below.
      * <ul>
      * <li>{@link #SUPERVISOR_VERIFICATION_SETTING_UNKNOWN}
      * <li>{@link #SUPERVISOR_VERIFICATION_SETTING_BIOMETRICS}
@@ -2141,20 +2156,19 @@
     /**
      * Unknown setting.
      */
-    public static final String SUPERVISOR_VERIFICATION_SETTING_UNKNOWN = "";
+    public static final int SUPERVISOR_VERIFICATION_SETTING_UNKNOWN = 0;
 
     /**
      * Biometric settings for supervisors.
      */
-    public static final String SUPERVISOR_VERIFICATION_SETTING_BIOMETRICS =
-            "supervisor_restricted_biometrics_controller";
+    public static final int SUPERVISOR_VERIFICATION_SETTING_BIOMETRICS = 1;
 
     /**
      * Keys for {@link #EXTRA_SUPERVISOR_RESTRICTED_SETTING_KEY}.
      * @hide
      */
     @Retention(RetentionPolicy.SOURCE)
-    @StringDef(prefix = { "SUPERVISOR_VERIFICATION_SETTING_" }, value = {
+    @IntDef(prefix = { "SUPERVISOR_VERIFICATION_SETTING_" }, value = {
             SUPERVISOR_VERIFICATION_SETTING_UNKNOWN,
             SUPERVISOR_VERIFICATION_SETTING_BIOMETRICS,
     })
@@ -9950,6 +9964,14 @@
         public static final String LOCKSCREEN_SHOW_CONTROLS = "lockscreen_show_controls";
 
         /**
+         * Whether trivial home controls can be used without authentication
+         *
+         * @hide
+         */
+        public static final String LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS =
+                "lockscreen_allow_trivial_controls";
+
+        /**
          * Whether wallet should be accessible from the lockscreen
          *
          * @hide
@@ -9965,6 +9987,13 @@
                 "lockscreen_use_double_line_clock";
 
         /**
+         * Whether to show the vibrate icon in the Status Bar (default off)
+         *
+         * @hide
+         */
+        public static final String STATUS_BAR_SHOW_VIBRATE_ICON = "status_bar_show_vibrate_icon";
+
+        /**
          * Specifies whether the web action API is enabled.
          *
          * @hide
@@ -10261,6 +10290,14 @@
                 "theme_customization_overlay_packages";
 
         /**
+         * Indicates whether the nav bar is forced to always be visible, even in immersive mode.
+         * <p>Type: int (0 for false, 1 for true)
+         *
+         * @hide
+         */
+        public static final String NAV_BAR_FORCE_VISIBLE = "nav_bar_force_visible";
+
+        /**
          * Indicates whether the device is in kids nav mode.
          * <p>Type: int (0 for false, 1 for true)
          *
@@ -15483,6 +15520,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/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index cfb6909..b701e07 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -905,7 +905,7 @@
             if (field == null) {
                 setLifeTheUniverseAndEverything(id, null, null, null, null, null, null);
             } else {
-                final DatasetFieldFilter filter = field.getFilter();
+                final DatasetFieldFilter filter = field.getDatasetFieldFilter();
                 final Presentations presentations = field.getPresentations();
                 if (presentations == null) {
                     setLifeTheUniverseAndEverything(id, field.getValue(), null, null, null,
diff --git a/core/java/android/service/autofill/Field.java b/core/java/android/service/autofill/Field.java
index b7c0d82..8c905a6 100644
--- a/core/java/android/service/autofill/Field.java
+++ b/core/java/android/service/autofill/Field.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SuppressLint;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 
@@ -86,11 +85,21 @@
      * @see Dataset.DatasetFieldFilter
      * @hide
      */
-    public @Nullable Dataset.DatasetFieldFilter getFilter() {
+    public @Nullable Dataset.DatasetFieldFilter getDatasetFieldFilter() {
         return mFilter;
     }
 
     /**
+     * Regex used to determine if the dataset should be shown in the autofill UI;
+     * when {@code null}, it disables filtering on that dataset (this is the recommended
+     * approach when {@code value} is not {@code null} and field contains sensitive data
+     * such as passwords).
+     */
+    public @Nullable Pattern getFilter() {
+        return mFilter == null ? null : mFilter.pattern;
+    }
+
+    /**
      * The presentations used to visualize this field in Autofill UI.
      */
     public @Nullable Presentations getPresentations() {
@@ -127,7 +136,6 @@
          * approach when {@code value} is not {@code null} and field contains sensitive data
          * such as passwords).
          */
-        @SuppressLint("MissingGetterMatchingBuilder")
         public @NonNull Builder setFilter(@Nullable Pattern value) {
             checkNotUsed();
             mFilter = new Dataset.DatasetFieldFilter(value);
diff --git a/core/java/android/service/dreams/DreamOverlayService.java b/core/java/android/service/dreams/DreamOverlayService.java
index 163d6ed..bfc3b8b 100644
--- a/core/java/android/service/dreams/DreamOverlayService.java
+++ b/core/java/android/service/dreams/DreamOverlayService.java
@@ -36,6 +36,9 @@
     private static final String TAG = "DreamOverlayService";
     private static final boolean DEBUG = false;
     private boolean mShowComplications;
+    private boolean mIsPreviewMode;
+    @Nullable
+    private CharSequence mDreamLabel;
 
     private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() {
         @Override
@@ -56,6 +59,8 @@
     public final IBinder onBind(@NonNull Intent intent) {
         mShowComplications = intent.getBooleanExtra(DreamService.EXTRA_SHOW_COMPLICATIONS,
                 DreamService.DEFAULT_SHOW_COMPLICATIONS);
+        mIsPreviewMode = intent.getBooleanExtra(DreamService.EXTRA_IS_PREVIEW, false);
+        mDreamLabel = intent.getCharSequenceExtra(DreamService.EXTRA_DREAM_LABEL);
         return mDreamOverlay.asBinder();
     }
 
@@ -84,4 +89,19 @@
     public final boolean shouldShowComplications() {
         return mShowComplications;
     }
+
+    /**
+     * Returns whether the dream is running in preview mode.
+     */
+    public final boolean isPreviewMode() {
+        return mIsPreviewMode;
+    }
+
+    /**
+     * Returns the user-facing label of the currently running dream.
+     */
+    @Nullable
+    public final CharSequence getDreamLabel() {
+        return mDreamLabel;
+    }
 }
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 3459172..1fd75e6 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -216,6 +216,18 @@
             "android.service.dreams.SHOW_COMPLICATIONS";
 
     /**
+     * Extra containing a boolean for whether we are showing this dream in preview mode.
+     * @hide
+     */
+    public static final String EXTRA_IS_PREVIEW = "android.service.dreams.IS_PREVIEW";
+
+    /**
+     * The user-facing label of the current dream service.
+     * @hide
+     */
+    public static final String EXTRA_DREAM_LABEL = "android.service.dreams.DREAM_LABEL";
+
+    /**
      * The default value for whether to show complications on the overlay.
      * @hide
      */
@@ -258,15 +270,19 @@
         }
 
         public void bind(Context context, @Nullable ComponentName overlayService,
-                ComponentName dreamService) {
+                ComponentName dreamService, boolean isPreviewMode) {
             if (overlayService == null) {
                 return;
             }
 
+            final ServiceInfo serviceInfo = fetchServiceInfo(context, dreamService);
+
             final Intent overlayIntent = new Intent();
             overlayIntent.setComponent(overlayService);
             overlayIntent.putExtra(EXTRA_SHOW_COMPLICATIONS,
-                    fetchShouldShowComplications(context, dreamService));
+                    fetchShouldShowComplications(context, serviceInfo));
+            overlayIntent.putExtra(EXTRA_DREAM_LABEL, fetchDreamLabel(context, serviceInfo));
+            overlayIntent.putExtra(EXTRA_IS_PREVIEW, isPreviewMode);
 
             context.bindService(overlayIntent,
                     this, Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE);
@@ -988,8 +1004,11 @@
 
         // Connect to the overlay service if present.
         if (!mWindowless) {
-            mOverlayConnection.bind(this, intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT),
-                    new ComponentName(this, getClass()));
+            mOverlayConnection.bind(
+                    /* context= */ this,
+                    intent.getParcelableExtra(EXTRA_DREAM_OVERLAY_COMPONENT),
+                    new ComponentName(this, getClass()),
+                    intent.getBooleanExtra(EXTRA_IS_PREVIEW, /* defaultValue= */ false));
         }
 
         return mDreamServiceWrapper;
@@ -1111,7 +1130,10 @@
      * @hide
      */
     @Nullable
-    public static DreamMetadata getDreamMetadata(Context context, ServiceInfo serviceInfo) {
+    public static DreamMetadata getDreamMetadata(Context context,
+            @Nullable ServiceInfo serviceInfo) {
+        if (serviceInfo == null) return null;
+
         final PackageManager pm = context.getPackageManager();
 
         final TypedArray rawMetadata = readMetadata(pm, serviceInfo);
@@ -1319,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();
                         }
@@ -1350,22 +1374,33 @@
      * {@link DreamService#DEFAULT_SHOW_COMPLICATIONS}.
      */
     private static boolean fetchShouldShowComplications(Context context,
-            ComponentName componentName) {
+            @Nullable ServiceInfo serviceInfo) {
+        final DreamMetadata metadata = getDreamMetadata(context, serviceInfo);
+        if (metadata != null) {
+            return metadata.showComplications;
+        }
+        return DEFAULT_SHOW_COMPLICATIONS;
+    }
+
+    @Nullable
+    private static CharSequence fetchDreamLabel(Context context,
+            @Nullable ServiceInfo serviceInfo) {
+        if (serviceInfo == null) return null;
+        final PackageManager pm = context.getPackageManager();
+        return serviceInfo.loadLabel(pm);
+    }
+
+    @Nullable
+    private static ServiceInfo fetchServiceInfo(Context context, ComponentName componentName) {
         final PackageManager pm = context.getPackageManager();
 
         try {
-            final ServiceInfo si = pm.getServiceInfo(componentName,
+            return pm.getServiceInfo(componentName,
                     PackageManager.ComponentInfoFlags.of(PackageManager.GET_META_DATA));
-            final DreamMetadata metadata = getDreamMetadata(context, si);
-
-            if (metadata != null) {
-                return metadata.showComplications;
-            }
         } catch (PackageManager.NameNotFoundException e) {
             if (DEBUG) Log.w(TAG, "cannot find component " + componentName.flattenToShortString());
         }
-
-        return DEFAULT_SHOW_COMPLICATIONS;
+        return null;
     }
 
     @Override
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/selectiontoolbar/FloatingToolbarRoot.java b/core/java/android/service/selectiontoolbar/FloatingToolbarRoot.java
index 8fe6f71..adc9251 100644
--- a/core/java/android/service/selectiontoolbar/FloatingToolbarRoot.java
+++ b/core/java/android/service/selectiontoolbar/FloatingToolbarRoot.java
@@ -40,7 +40,7 @@
 
     private final IBinder mTargetInputToken;
     private final SelectionToolbarRenderService.TransferTouchListener mTransferTouchListener;
-    private Rect mContentRect;
+    private final Rect mContentRect = new Rect();
 
     private int mLastDownX = -1;
     private int mLastDownY = -1;
@@ -57,7 +57,7 @@
      * Sets the Rect that shows the selection toolbar content.
      */
     public void setContentRect(Rect contentRect) {
-        mContentRect = contentRect;
+        mContentRect.set(contentRect);
     }
 
     @Override
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index 542de3f..c1fcd66 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -239,8 +239,10 @@
      * @param events Events
      * @param notifyNow Whether to notify instantly
      */
-    public void listenFromListener(int subId, @NonNull String pkg, @NonNull String featureId,
-            @NonNull PhoneStateListener listener, @NonNull int events, boolean notifyNow) {
+    public void listenFromListener(int subId, @NonNull boolean renounceFineLocationAccess,
+            @NonNull boolean renounceCoarseLocationAccess, @NonNull String pkg,
+            @NonNull String featureId, @NonNull PhoneStateListener listener,
+            @NonNull int events, boolean notifyNow) {
         if (listener == null) {
             throw new IllegalStateException("telephony service is null.");
         }
@@ -257,8 +259,8 @@
             } else if (listener.mSubId != null) {
                 subId = listener.mSubId;
             }
-            sRegistry.listenWithEventList(false, false, subId, pkg, featureId,
-                    listener.callback, eventsList, notifyNow);
+            sRegistry.listenWithEventList(renounceFineLocationAccess, renounceCoarseLocationAccess,
+                    subId, pkg, featureId, listener.callback, eventsList, notifyNow);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 188bc3f..4541f3a 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -95,7 +95,7 @@
         DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true");
         DEFAULT_FLAGS.put(SETTINGS_SUPPORT_LARGE_SCREEN, "true");
-        DEFAULT_FLAGS.put("settings_search_always_expand", "false");
+        DEFAULT_FLAGS.put("settings_search_always_expand", "true");
         DEFAULT_FLAGS.put(SETTINGS_APP_LANGUAGE_SELECTION, "true");
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
         DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "false");
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 4ac3178..aebc5e8 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -33,6 +33,9 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.Objects;
 import java.util.function.Supplier;
 
@@ -81,14 +84,23 @@
 
         /** Calculates and returns the age of this result. */
         public long getAgeMillis() {
-            return SystemClock.elapsedRealtime() - mElapsedRealtimeMillis;
+            return getAgeMillis(SystemClock.elapsedRealtime());
+        }
+
+        /**
+         * Calculates and returns the age of this result relative to currentElapsedRealtimeMillis.
+         *
+         * @param currentElapsedRealtimeMillis - reference elapsed real time
+         */
+        public long getAgeMillis(long currentElapsedRealtimeMillis) {
+            return currentElapsedRealtimeMillis - mElapsedRealtimeMillis;
         }
 
         @Override
         public String toString() {
             return "TimeResult{"
-                    + "mTimeMillis=" + mTimeMillis
-                    + ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
+                    + "mTimeMillis=" + Instant.ofEpochMilli(mTimeMillis)
+                    + ", mElapsedRealtimeMillis=" + Duration.ofMillis(mElapsedRealtimeMillis)
                     + ", mCertaintyMillis=" + mCertaintyMillis
                     + '}';
         }
@@ -122,6 +134,14 @@
         }
     };
 
+    /** An in-memory config override for use during tests. */
+    @Nullable
+    private String mHostnameForTests;
+
+    /** An in-memory config override for use during tests. */
+    @Nullable
+    private Duration mTimeoutForTests;
+
     // Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during
     // forceRefresh().
     private volatile TimeResult mTimeResult;
@@ -139,12 +159,23 @@
         return sSingleton;
     }
 
+    /**
+     * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
+     * test value, i.e. so the normal value will be used next time.
+     */
+    public void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
+        synchronized (this) {
+            mHostnameForTests = hostname;
+            mTimeoutForTests = timeout;
+        }
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean forceRefresh() {
         synchronized (this) {
             NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
             if (connectionInfo == null) {
-                // missing server config, so no trusted time available
+                // missing server config, so no NTP time available
                 if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
                 return false;
             }
@@ -256,6 +287,13 @@
         return mTimeResult;
     }
 
+    /** Clears the last received NTP. Intended for use during tests. */
+    public void clearCachedTimeResult() {
+        synchronized (this) {
+            mTimeResult = null;
+        }
+    }
+
     private static class NtpConnectionInfo {
 
         @NonNull private final String mServer;
@@ -274,6 +312,14 @@
         int getTimeoutMillis() {
             return mTimeoutMillis;
         }
+
+        @Override
+        public String toString() {
+            return "NtpConnectionInfo{"
+                    + "mServer='" + mServer + '\''
+                    + ", mTimeoutMillis=" + mTimeoutMillis
+                    + '}';
+        }
     }
 
     @GuardedBy("this")
@@ -281,17 +327,41 @@
         final ContentResolver resolver = mContext.getContentResolver();
 
         final Resources res = mContext.getResources();
-        final String defaultServer = res.getString(
-                com.android.internal.R.string.config_ntpServer);
-        final int defaultTimeoutMillis = res.getInteger(
-                com.android.internal.R.integer.config_ntpTimeout);
 
-        final String secureServer = Settings.Global.getString(
-                resolver, Settings.Global.NTP_SERVER);
-        final int timeoutMillis = Settings.Global.getInt(
-                resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
+        final String hostname;
+        if (mHostnameForTests != null) {
+            hostname = mHostnameForTests;
+        } else {
+            String serverGlobalSetting =
+                    Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
+            if (serverGlobalSetting != null) {
+                hostname = serverGlobalSetting;
+            } else {
+                hostname = res.getString(com.android.internal.R.string.config_ntpServer);
+            }
+        }
 
-        final String server = secureServer != null ? secureServer : defaultServer;
-        return TextUtils.isEmpty(server) ? null : new NtpConnectionInfo(server, timeoutMillis);
+        final int timeoutMillis;
+        if (mTimeoutForTests != null) {
+            timeoutMillis = (int) mTimeoutForTests.toMillis();
+        } else {
+            int defaultTimeoutMillis =
+                    res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
+            timeoutMillis = Settings.Global.getInt(
+                    resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
+        }
+        return TextUtils.isEmpty(hostname) ? null : new NtpConnectionInfo(hostname, timeoutMillis);
+    }
+
+    /** Prints debug information. */
+    public void dump(PrintWriter pw) {
+        synchronized (this) {
+            pw.println("getNtpConnectionInfo()=" + getNtpConnectionInfo());
+            pw.println("mTimeResult=" + mTimeResult);
+            if (mTimeResult != null) {
+                pw.println("mTimeResult.getAgeMillis()="
+                        + Duration.ofMillis(mTimeResult.getAgeMillis()));
+            }
+        }
     }
 }
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 8e3cc34..c1fa079 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -154,13 +154,13 @@
     private static final int MSG_DO_SCHEDULE_VSYNC = 1;
     private static final int MSG_DO_SCHEDULE_CALLBACK = 2;
 
-    // All frame callbacks posted by applications have this token or EXTENDED_FRAME_CALLBACK_TOKEN.
+    // All frame callbacks posted by applications have this token or VSYNC_CALLBACK_TOKEN.
     private static final Object FRAME_CALLBACK_TOKEN = new Object() {
         public String toString() { return "FRAME_CALLBACK_TOKEN"; }
     };
-    private static final Object EXTENDED_FRAME_CALLBACK_TOKEN = new Object() {
+    private static final Object VSYNC_CALLBACK_TOKEN = new Object() {
         public String toString() {
-            return "EXTENDED_FRAME_CALLBACK_TOKEN";
+            return "VSYNC_CALLBACK_TOKEN";
         }
     };
 
@@ -492,12 +492,12 @@
     }
 
     /**
-     * Posts an extended frame callback to run on the next frame.
+     * Posts a vsync callback to run on the next frame.
      * <p>
      * The callback runs once then is automatically removed.
      * </p>
      *
-     * @param callback The extended frame callback to run during the next frame.
+     * @param callback The vsync callback to run during the next frame.
      *
      * @see #removeVsyncCallback
      */
@@ -506,7 +506,7 @@
             throw new IllegalArgumentException("callback must not be null");
         }
 
-        postCallbackDelayedInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN, 0);
+        postCallbackDelayedInternal(CALLBACK_ANIMATION, callback, VSYNC_CALLBACK_TOKEN, 0);
     }
 
     /**
@@ -599,9 +599,9 @@
     }
 
     /**
-     * Removes a previously posted extended frame callback.
+     * Removes a previously posted vsync callback.
      *
-     * @param callback The extended frame callback to remove.
+     * @param callback The vsync callback to remove.
      *
      * @see #postVsyncCallback
      */
@@ -610,7 +610,7 @@
             throw new IllegalArgumentException("callback must not be null");
         }
 
-        removeCallbacksInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN);
+        removeCallbacksInternal(CALLBACK_ANIMATION, callback, VSYNC_CALLBACK_TOKEN);
     }
 
     /**
@@ -1198,7 +1198,7 @@
     private static final class CallbackRecord {
         public CallbackRecord next;
         public long dueTime;
-        /** Runnable or FrameCallback or ExtendedFrameCallback object. */
+        /** Runnable or FrameCallback or VsyncCallback object. */
         public Object action;
         /** Denotes the action type. */
         public Object token;
@@ -1213,7 +1213,7 @@
         }
 
         void run(FrameData frameData) {
-            if (token == EXTENDED_FRAME_CALLBACK_TOKEN) {
+            if (token == VSYNC_CALLBACK_TOKEN) {
                 ((VsyncCallback) action).onVsync(frameData);
             } else {
                 run(frameData.getFrameTimeNanos());
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/core/java/android/view/ContentRecordingSession.aidl
similarity index 62%
copy from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
copy to core/java/android/view/ContentRecordingSession.aidl
index 2894780..ddbc175 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/core/java/android/view/ContentRecordingSession.aidl
@@ -1,11 +1,11 @@
-/*
- * 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.
  * You may obtain a copy of the License at
  *
- *      http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,13 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.systemui.dagger;
+package android.view;
 
-import dagger.Module;
-
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
-}
+parcelable ContentRecordingSession;
diff --git a/core/java/android/view/ContentRecordingSession.java b/core/java/android/view/ContentRecordingSession.java
new file mode 100644
index 0000000..db4ec11
--- /dev/null
+++ b/core/java/android/view/ContentRecordingSession.java
@@ -0,0 +1,447 @@
+/*
+ * 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.view;
+
+import static android.view.Display.INVALID_DISPLAY;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DataClass;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Description of a content recording session.
+ *
+ * @hide
+ */
+@DataClass(
+        genConstructor = false,
+        genToString = true,
+        genSetters = true,
+        genEqualsHashCode = true
+)
+public final class ContentRecordingSession implements Parcelable {
+
+    /**
+     * An entire DisplayContent is being recorded. Recording may also be paused.
+     */
+    public static final int RECORD_CONTENT_DISPLAY = 0;
+    /**
+     * A single Task is being recorded. Recording may also be paused.
+     */
+    public static final int RECORD_CONTENT_TASK = 1;
+
+    /**
+     * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
+     * recorded content rendered to its surface.
+     */
+    private int mDisplayId = INVALID_DISPLAY;
+
+    /**
+     * The content to record.
+     */
+    @RecordContent
+    private int mContentToRecord = RECORD_CONTENT_DISPLAY;
+
+    /**
+     * The window token of the layer of the hierarchy to record.
+     * The display content if {@link #getContentToRecord()} is
+     * {@link RecordContent#RECORD_CONTENT_DISPLAY}, or task if {@link #getContentToRecord()} is
+     * {@link RecordContent#RECORD_CONTENT_TASK}.
+     */
+    @VisibleForTesting
+    @Nullable
+    private IBinder mTokenToRecord = null;
+
+    /**
+     * Default instance, with recording the display.
+     */
+    private ContentRecordingSession() {
+    }
+
+    /**
+     * Returns an instance initialized for display recording.
+     */
+    public static ContentRecordingSession createDisplaySession(
+            @NonNull IBinder displayContentWindowToken) {
+        return new ContentRecordingSession().setContentToRecord(RECORD_CONTENT_DISPLAY)
+                .setTokenToRecord(displayContentWindowToken);
+    }
+
+    /**
+     * Returns an instance initialized for task recording.
+     */
+    public static ContentRecordingSession createTaskSession(
+            @NonNull IBinder taskWindowContainerToken) {
+        return new ContentRecordingSession().setContentToRecord(RECORD_CONTENT_TASK)
+                .setTokenToRecord(taskWindowContainerToken);
+    }
+
+    /**
+     * Returns {@code true} if this is a valid session.
+     */
+    public static boolean isValid(ContentRecordingSession session) {
+        return session != null && (session.getDisplayId() > INVALID_DISPLAY
+                && session.getTokenToRecord() != null);
+    }
+
+    /**
+     * Returns {@code true} when both sessions are for the same display.
+     */
+    public static boolean isSameDisplay(ContentRecordingSession session,
+            ContentRecordingSession incomingSession) {
+        return session != null && incomingSession != null
+                && session.getDisplayId() == incomingSession.getDisplayId();
+    }
+
+
+
+
+    // Code below generated by codegen v1.0.23.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/ContentRecordingSession.java
+    //
+    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+    //   Settings > Editor > Code Style > Formatter Control
+    //@formatter:off
+
+
+    @IntDef(prefix = "RECORD_CONTENT_", value = {
+        RECORD_CONTENT_DISPLAY,
+        RECORD_CONTENT_TASK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @DataClass.Generated.Member
+    public @interface RecordContent {}
+
+    @DataClass.Generated.Member
+    public static String recordContentToString(@RecordContent int value) {
+        switch (value) {
+            case RECORD_CONTENT_DISPLAY:
+                    return "RECORD_CONTENT_DISPLAY";
+            case RECORD_CONTENT_TASK:
+                    return "RECORD_CONTENT_TASK";
+            default: return Integer.toHexString(value);
+        }
+    }
+
+    @DataClass.Generated.Member
+    /* package-private */ ContentRecordingSession(
+            int displayId,
+            @RecordContent int contentToRecord,
+            @VisibleForTesting @Nullable IBinder tokenToRecord) {
+        this.mDisplayId = displayId;
+        this.mContentToRecord = contentToRecord;
+
+        if (!(mContentToRecord == RECORD_CONTENT_DISPLAY)
+                && !(mContentToRecord == RECORD_CONTENT_TASK)) {
+            throw new java.lang.IllegalArgumentException(
+                    "contentToRecord was " + mContentToRecord + " but must be one of: "
+                            + "RECORD_CONTENT_DISPLAY(" + RECORD_CONTENT_DISPLAY + "), "
+                            + "RECORD_CONTENT_TASK(" + RECORD_CONTENT_TASK + ")");
+        }
+
+        this.mTokenToRecord = tokenToRecord;
+        com.android.internal.util.AnnotationValidations.validate(
+                VisibleForTesting.class, null, mTokenToRecord);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    /**
+     * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
+     * recorded content rendered to its surface.
+     */
+    @DataClass.Generated.Member
+    public int getDisplayId() {
+        return mDisplayId;
+    }
+
+    /**
+     * The content to record.
+     */
+    @DataClass.Generated.Member
+    public @RecordContent int getContentToRecord() {
+        return mContentToRecord;
+    }
+
+    /**
+     * The window token of the layer of the hierarchy to record.
+     * The display content if {@link #getContentToRecord()} is
+     * {@link RecordContent#RECORD_CONTENT_DISPLAY}, or task if {@link #getContentToRecord()} is
+     * {@link RecordContent#RECORD_CONTENT_TASK}.
+     */
+    @DataClass.Generated.Member
+    public @VisibleForTesting @Nullable IBinder getTokenToRecord() {
+        return mTokenToRecord;
+    }
+
+    /**
+     * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
+     * recorded content rendered to its surface.
+     */
+    @DataClass.Generated.Member
+    public @NonNull ContentRecordingSession setDisplayId( int value) {
+        mDisplayId = value;
+        return this;
+    }
+
+    /**
+     * The content to record.
+     */
+    @DataClass.Generated.Member
+    public @NonNull ContentRecordingSession setContentToRecord(@RecordContent int value) {
+        mContentToRecord = value;
+
+        if (!(mContentToRecord == RECORD_CONTENT_DISPLAY)
+                && !(mContentToRecord == RECORD_CONTENT_TASK)) {
+            throw new java.lang.IllegalArgumentException(
+                    "contentToRecord was " + mContentToRecord + " but must be one of: "
+                            + "RECORD_CONTENT_DISPLAY(" + RECORD_CONTENT_DISPLAY + "), "
+                            + "RECORD_CONTENT_TASK(" + RECORD_CONTENT_TASK + ")");
+        }
+
+        return this;
+    }
+
+    /**
+     * The window token of the layer of the hierarchy to record.
+     * The display content if {@link #getContentToRecord()} is
+     * {@link RecordContent#RECORD_CONTENT_DISPLAY}, or task if {@link #getContentToRecord()} is
+     * {@link RecordContent#RECORD_CONTENT_TASK}.
+     */
+    @DataClass.Generated.Member
+    public @NonNull ContentRecordingSession setTokenToRecord(@VisibleForTesting @NonNull IBinder value) {
+        mTokenToRecord = value;
+        com.android.internal.util.AnnotationValidations.validate(
+                VisibleForTesting.class, null, mTokenToRecord);
+        return this;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public String toString() {
+        // You can override field toString logic by defining methods like:
+        // String fieldNameToString() { ... }
+
+        return "ContentRecordingSession { " +
+                "displayId = " + mDisplayId + ", " +
+                "contentToRecord = " + recordContentToString(mContentToRecord) + ", " +
+                "tokenToRecord = " + mTokenToRecord +
+        " }";
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public boolean equals(@Nullable Object o) {
+        // You can override field equality logic by defining either of the methods like:
+        // boolean fieldNameEquals(ContentRecordingSession other) { ... }
+        // boolean fieldNameEquals(FieldType otherValue) { ... }
+
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        @SuppressWarnings("unchecked")
+        ContentRecordingSession that = (ContentRecordingSession) o;
+        //noinspection PointlessBooleanExpression
+        return true
+                && mDisplayId == that.mDisplayId
+                && mContentToRecord == that.mContentToRecord
+                && java.util.Objects.equals(mTokenToRecord, that.mTokenToRecord);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int hashCode() {
+        // You can override field hashCode logic by defining methods like:
+        // int fieldNameHashCode() { ... }
+
+        int _hash = 1;
+        _hash = 31 * _hash + mDisplayId;
+        _hash = 31 * _hash + mContentToRecord;
+        _hash = 31 * _hash + java.util.Objects.hashCode(mTokenToRecord);
+        return _hash;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        byte flg = 0;
+        if (mTokenToRecord != null) flg |= 0x4;
+        dest.writeByte(flg);
+        dest.writeInt(mDisplayId);
+        dest.writeInt(mContentToRecord);
+        if (mTokenToRecord != null) dest.writeStrongBinder(mTokenToRecord);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    /* package-private */ ContentRecordingSession(@NonNull Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        byte flg = in.readByte();
+        int displayId = in.readInt();
+        int contentToRecord = in.readInt();
+        IBinder tokenToRecord = (flg & 0x4) == 0 ? null : (IBinder) in.readStrongBinder();
+
+        this.mDisplayId = displayId;
+        this.mContentToRecord = contentToRecord;
+
+        if (!(mContentToRecord == RECORD_CONTENT_DISPLAY)
+                && !(mContentToRecord == RECORD_CONTENT_TASK)) {
+            throw new java.lang.IllegalArgumentException(
+                    "contentToRecord was " + mContentToRecord + " but must be one of: "
+                            + "RECORD_CONTENT_DISPLAY(" + RECORD_CONTENT_DISPLAY + "), "
+                            + "RECORD_CONTENT_TASK(" + RECORD_CONTENT_TASK + ")");
+        }
+
+        this.mTokenToRecord = tokenToRecord;
+        com.android.internal.util.AnnotationValidations.validate(
+                VisibleForTesting.class, null, mTokenToRecord);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<ContentRecordingSession> CREATOR
+            = new Parcelable.Creator<ContentRecordingSession>() {
+        @Override
+        public ContentRecordingSession[] newArray(int size) {
+            return new ContentRecordingSession[size];
+        }
+
+        @Override
+        public ContentRecordingSession createFromParcel(@NonNull Parcel in) {
+            return new ContentRecordingSession(in);
+        }
+    };
+
+    /**
+     * A builder for {@link ContentRecordingSession}
+     */
+    @SuppressWarnings("WeakerAccess")
+    @DataClass.Generated.Member
+    public static final class Builder {
+
+        private int mDisplayId;
+        private @RecordContent int mContentToRecord;
+        private @VisibleForTesting @Nullable IBinder mTokenToRecord;
+
+        private long mBuilderFieldsSet = 0L;
+
+        public Builder() {
+        }
+
+        /**
+         * Unique logical identifier of the {@link android.hardware.display.VirtualDisplay} that has
+         * recorded content rendered to its surface.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setDisplayId(int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x1;
+            mDisplayId = value;
+            return this;
+        }
+
+        /**
+         * The content to record.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setContentToRecord(@RecordContent int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2;
+            mContentToRecord = value;
+            return this;
+        }
+
+        /**
+         * The window token of the layer of the hierarchy to record.
+         * The display content if {@link #getContentToRecord()} is
+         * {@link RecordContent#RECORD_CONTENT_DISPLAY}, or task if {@link #getContentToRecord()} is
+         * {@link RecordContent#RECORD_CONTENT_TASK}.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setTokenToRecord(@VisibleForTesting @NonNull IBinder value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4;
+            mTokenToRecord = value;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        public @NonNull ContentRecordingSession build() {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8; // Mark builder used
+
+            if ((mBuilderFieldsSet & 0x1) == 0) {
+                mDisplayId = INVALID_DISPLAY;
+            }
+            if ((mBuilderFieldsSet & 0x2) == 0) {
+                mContentToRecord = RECORD_CONTENT_DISPLAY;
+            }
+            if ((mBuilderFieldsSet & 0x4) == 0) {
+                mTokenToRecord = null;
+            }
+            ContentRecordingSession o = new ContentRecordingSession(
+                    mDisplayId,
+                    mContentToRecord,
+                    mTokenToRecord);
+            return o;
+        }
+
+        private void checkNotUsed() {
+            if ((mBuilderFieldsSet & 0x8) != 0) {
+                throw new IllegalStateException(
+                        "This Builder should not be reused. Use a new Builder instance instead");
+            }
+        }
+    }
+
+    @DataClass.Generated(
+            time = 1644843382972L,
+            codegenVersion = "1.0.23",
+            sourceFile = "frameworks/base/core/java/android/view/ContentRecordingSession.java",
+            inputSignatures = "public static final  int RECORD_CONTENT_DISPLAY\npublic static final  int RECORD_CONTENT_TASK\nprivate  int mDisplayId\nprivate @android.view.ContentRecordingSession.RecordContent int mContentToRecord\nprivate @com.android.internal.annotations.VisibleForTesting @android.annotation.Nullable android.os.IBinder mTokenToRecord\npublic static  android.view.ContentRecordingSession createDisplaySession(android.os.IBinder)\npublic static  android.view.ContentRecordingSession createTaskSession(android.os.IBinder)\npublic static  boolean isValid(android.view.ContentRecordingSession)\npublic static  boolean isSameDisplay(android.view.ContentRecordingSession,android.view.ContentRecordingSession)\nclass ContentRecordingSession extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genSetters=true, genEqualsHashCode=true)")
+    @Deprecated
+    private void __metadata() {}
+
+
+    //@formatter:on
+    // End of generated code
+
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index ce21086..a35a195 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -18,6 +18,7 @@
 
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.policy.IKeyguardLockedStateListener;
 import com.android.internal.policy.IShortcutService;
 
 import android.app.IAssistDataReceiver;
@@ -31,6 +32,7 @@
 import android.os.Bundle;
 import android.os.IRemoteCallback;
 import android.os.ParcelFileDescriptor;
+import android.view.ContentRecordingSession;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.IAppTransitionAnimationSpecsFuture;
@@ -199,6 +201,14 @@
     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
     void setSwitchingUser(boolean switching);
 
@@ -875,6 +885,17 @@
     void detachWindowContextFromWindowContainer(IBinder clientToken);
 
     /**
+     * Updates the content recording session. If a different session is already in progress, then
+     * the pre-existing session is stopped, and the new incoming session takes over.
+     *
+     * The DisplayContent for the new session will begin recording when
+     * {@link RootWindowContainer#onDisplayChanged} is invoked for the new {@link VirtualDisplay}.
+     *
+     * @param incomingSession the nullable incoming content recording session
+     */
+    void setContentRecordingSession(in ContentRecordingSession incomingSession);
+
+    /**
      * Registers a listener, which is to be called whenever cross-window blur is enabled/disabled.
      *
      * @param listener the listener to be registered
@@ -951,4 +972,10 @@
      * @hide
      */
     Bitmap snapshotTaskForRecents(int taskId);
+
+    /**
+     * Informs the system whether the recents app is currently behind the system bars. If so,
+     * means the recents app can control the SystemUI flags, and vice-versa.
+     */
+    void setRecentsAppBehindSystemBars(boolean behindSystemBars);
 }
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index a266a28..5c7c844 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -290,7 +290,8 @@
     /**
      * Called when the keep-clear areas for this window have changed.
      */
-    oneway void reportKeepClearAreasChanged(IWindow window, in List<Rect> keepClearRects);
+    oneway void reportKeepClearAreasChanged(IWindow window, in List<Rect> restricted,
+           in List<Rect> unrestricted);
 
     /**
     * Request the server to call setInputWindowInfo on a given Surface, and return
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/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index b1582cf..6aab635 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -98,6 +98,13 @@
      */
     private boolean mIsAnimationPending;
 
+    /**
+     * @param type The {@link InternalInsetsType} of the consumed insets.
+     * @param state The current {@link InsetsState} of the consumed insets.
+     * @param transactionSupplier The source of new {@link Transaction} instances. The supplier
+     *         must provide *new* instances, which will be explicitly closed by this class.
+     * @param controller The {@link InsetsController} to use for insets interaction.
+     */
     public InsetsSourceConsumer(@InternalInsetsType int type, InsetsState state,
             Supplier<Transaction> transactionSupplier, InsetsController controller) {
         mType = type;
@@ -390,16 +397,17 @@
             return;
         }
 
-        final Transaction t = mTransactionSupplier.get();
-        if (DEBUG) Log.d(TAG, "applyRequestedVisibilityToControl: " + mRequestedVisible);
-        if (mRequestedVisible) {
-            t.show(mSourceControl.getLeash());
-        } else {
-            t.hide(mSourceControl.getLeash());
+        try (Transaction t = mTransactionSupplier.get()) {
+            if (DEBUG) Log.d(TAG, "applyRequestedVisibilityToControl: " + mRequestedVisible);
+            if (mRequestedVisible) {
+                t.show(mSourceControl.getLeash());
+            } else {
+                t.hide(mSourceControl.getLeash());
+            }
+            // Ensure the alpha value is aligned with the actual requested visibility.
+            t.setAlpha(mSourceControl.getLeash(), mRequestedVisible ? 1 : 0);
+            t.apply();
         }
-        // Ensure the alpha value is aligned with the actual requested visibility.
-        t.setAlpha(mSourceControl.getLeash(), mRequestedVisible ? 1 : 0);
-        t.apply();
         onPerceptible(mRequestedVisible);
     }
 
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/OWNERS b/core/java/android/view/OWNERS
index e313388..3e28490 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -75,6 +75,8 @@
 per-file ContentInfo.java = file:/core/java/android/widget/OWNERS
 
 # WindowManager
+per-file ContentRecordingSession.aidl = file:/services/core/java/com/android/server/wm/OWNERS
+per-file ContentRecordingSession.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file DisplayCutout.aidl = file:/services/core/java/com/android/server/wm/OWNERS
 per-file DisplayCutout.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file IDisplay*.aidl = file:/services/core/java/com/android/server/wm/OWNERS
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 632af23..64f5668 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -248,6 +248,7 @@
 
     private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject,
             int transformHint);
+    private static native void nativeRemoveCurrentInputFocus(long nativeObject, int displayId);
     private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken,
             String windowName, IBinder focusedToken, String focusedWindowName, int displayId);
     private static native void nativeSetFrameTimelineVsync(long transactionObj,
@@ -264,6 +265,8 @@
     private static native void nativeAddTransactionCommittedListener(long nativeObject,
             TransactionCommittedListener listener);
     private static native void nativeSanitize(long transactionObject);
+    private static native void nativeSetDestinationFrame(long transactionObj, long nativeObject,
+            int l, int t, int r, int b);
 
     /**
      * Transforms that can be applied to buffers as they are displayed to a window.
@@ -3657,6 +3660,17 @@
         }
 
         /**
+         * Removes the input focus from the current window which is having the input focus. Should
+         * only be called when the current focused app is not responding and the current focused
+         * window is not beloged to the current focused app.
+         * @hide
+         */
+        public Transaction removeCurrentInputFocus(int displayId) {
+            nativeRemoveCurrentInputFocus(mNativeObject, displayId);
+            return this;
+        }
+
+        /**
          * Adds or removes the flag SKIP_SCREENSHOT of the surface.  Setting the flag is equivalent
          * to creating the Surface with the {@link #SKIP_SCREENSHOT} flag.
          *
@@ -3838,6 +3852,26 @@
         }
 
         /**
+         * @hide
+         */
+        public Transaction setDesintationFrame(SurfaceControl sc, @NonNull Rect destinationFrame) {
+            checkPreconditions(sc);
+            nativeSetDestinationFrame(mNativeObject, sc.mNativeObject,
+                    destinationFrame.left, destinationFrame.top, destinationFrame.right,
+                    destinationFrame.bottom);
+            return this;
+        }
+
+        /**
+         * @hide
+         */
+        public Transaction setDesintationFrame(SurfaceControl sc, int width, int height) {
+            checkPreconditions(sc);
+            nativeSetDestinationFrame(mNativeObject, sc.mNativeObject, 0, 0, width, height);
+            return this;
+        }
+
+        /**
          * Merge the other transaction into this transaction, clearing the
          * other transaction as if it had been applied.
          *
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1a458ce..4138556 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -51,6 +51,7 @@
 
 import java.util.ArrayList;
 import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
 
 /**
  * Provides a dedicated drawing surface embedded inside of a view hierarchy.
@@ -133,9 +134,8 @@
     private boolean mDisableBackgroundLayer = false;
 
     /**
-     * We use this lock to protect access to mSurfaceControl and
-     * SurfaceViewPositionUpdateListener#mPositionChangedTransaction. Both are accessed on the UI
-     * thread and the render thread.
+     * We use this lock to protect access to mSurfaceControl. Both are accessed on the UI
+     * thread and the render thread via RenderNode.PositionUpdateListener#positionLost.
      */
     final Object mSurfaceControlLock = new Object();
     final Rect mTmpRect = new Rect();
@@ -224,12 +224,6 @@
     private final SurfaceControl.Transaction mFrameCallbackTransaction =
             new SurfaceControl.Transaction();
 
-    /**
-     * A temporary transaction holder that should only be used when applying right away. There
-     * should be no assumption about thread safety for this transaction.
-     */
-    private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
-
     private int mParentSurfaceSequenceId;
 
     private RemoteAccessibilityController mRemoteAccessibilityController =
@@ -397,8 +391,10 @@
         }
     }
 
-    private void performDrawFinished(Transaction t) {
-        mSyncTransaction.merge(t);
+    private void performDrawFinished(@Nullable Transaction t) {
+        if (t != null) {
+            mSyncTransaction.merge(t);
+        }
 
         if (mPendingReportDraws > 0) {
             mDrawFinished = true;
@@ -760,7 +756,7 @@
                 mBlastBufferQueue = null;
             }
 
-            Transaction transaction = new Transaction();
+            final Transaction transaction = new Transaction();
             if (mSurfaceControl != null) {
                 transaction.remove(mSurfaceControl);
                 mSurfaceControl = null;
@@ -790,22 +786,17 @@
     // synchronously otherwise we may see flickers.
     // When the listener is updated, we will get at least a single position update call so we can
     // guarantee any changes we post will be applied.
-    private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight,
-            Transaction geometryTransaction) {
+    private void replacePositionUpdateListener(int surfaceWidth, int surfaceHeight) {
         if (mPositionListener != null) {
             mRenderNode.removePositionUpdateListener(mPositionListener);
-            synchronized (mSurfaceControlLock) {
-                geometryTransaction = mPositionListener.getTransaction().merge(geometryTransaction);
-            }
         }
-        mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight,
-                geometryTransaction);
+        mPositionListener = new SurfaceViewPositionUpdateListener(surfaceWidth, surfaceHeight);
         mRenderNode.addPositionUpdateListener(mPositionListener);
     }
 
     private boolean performSurfaceTransaction(ViewRootImpl viewRoot, Translator translator,
             boolean creating, boolean sizeChanged, boolean hintChanged,
-            Transaction geometryTransaction) {
+            Transaction surfaceUpdateTransaction) {
         boolean realSizeChanged = false;
 
         mSurfaceLock.lock();
@@ -820,56 +811,60 @@
             // SurfaceChangedCallback to update the relative z. This is needed so that
             // we do not change the relative z before the server is ready to swap the
             // parent surface.
-            if (creating || (mParentSurfaceSequenceId == viewRoot.getSurfaceSequenceId())) {
-                updateRelativeZ(mTmpTransaction);
+            if (creating) {
+                updateRelativeZ(surfaceUpdateTransaction);
+                if (mSurfacePackage != null) {
+                    reparentSurfacePackage(surfaceUpdateTransaction, mSurfacePackage);
+                }
             }
             mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
 
             if (mViewVisibility) {
-                geometryTransaction.show(mSurfaceControl);
+                surfaceUpdateTransaction.show(mSurfaceControl);
             } else {
-                geometryTransaction.hide(mSurfaceControl);
+                surfaceUpdateTransaction.hide(mSurfaceControl);
             }
 
-            if (mSurfacePackage != null) {
-                reparentSurfacePackage(mTmpTransaction, mSurfacePackage);
-            }
 
-            updateBackgroundVisibility(mTmpTransaction);
-            updateBackgroundColor(mTmpTransaction);
+
+            updateBackgroundVisibility(surfaceUpdateTransaction);
+            updateBackgroundColor(surfaceUpdateTransaction);
             if (mUseAlpha) {
                 float alpha = getFixedAlpha();
-                mTmpTransaction.setAlpha(mSurfaceControl, alpha);
+                surfaceUpdateTransaction.setAlpha(mSurfaceControl, alpha);
                 mSurfaceAlpha = alpha;
             }
 
-            geometryTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
+            surfaceUpdateTransaction.setCornerRadius(mSurfaceControl, mCornerRadius);
             if ((sizeChanged || hintChanged) && !creating) {
-                setBufferSize(geometryTransaction);
+                setBufferSize(surfaceUpdateTransaction);
             }
             if (sizeChanged || creating || !isHardwareAccelerated()) {
-                onSetSurfacePositionAndScaleRT(geometryTransaction, mSurfaceControl,
-                        mScreenRect.left, /*positionLeft*/
-                        mScreenRect.top /*positionTop*/ ,
-                        mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
-                        mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
 
                 // Set a window crop when creating the surface or changing its size to
                 // crop the buffer to the surface size since the buffer producer may
                 // use SCALING_MODE_SCALE and submit a larger size than the surface
                 // size.
                 if (mClipSurfaceToBounds && mClipBounds != null) {
-                    geometryTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
+                    surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mClipBounds);
                 } else {
-                    geometryTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
+                    surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth,
                             mSurfaceHeight);
                 }
 
+                surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth,
+                            mSurfaceHeight);
+
                 if (isHardwareAccelerated()) {
                     // This will consume the passed in transaction and the transaction will be
                     // applied on a render worker thread.
-                    replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight,
-                            geometryTransaction);
+                    replacePositionUpdateListener(mSurfaceWidth, mSurfaceHeight);
+                } else {
+                    onSetSurfacePositionAndScale(surfaceUpdateTransaction, mSurfaceControl,
+                            mScreenRect.left /*positionLeft*/,
+                            mScreenRect.top /*positionTop*/,
+                            mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
+                            mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
                 }
                 if (DEBUG_POSITION) {
                     Log.d(TAG, String.format(
@@ -881,8 +876,7 @@
                             mScreenRect.bottom, mSurfaceWidth, mSurfaceHeight));
                 }
             }
-            mTmpTransaction.merge(geometryTransaction);
-            mTmpTransaction.apply();
+            applyTransactionOnVriDraw(surfaceUpdateTransaction);
             updateEmbeddedAccessibilityMatrix();
 
             mSurfaceFrame.left = 0;
@@ -990,17 +984,17 @@
                 mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
                 // Collect all geometry changes and apply these changes on the RenderThread worker
                 // via the RenderNode.PositionUpdateListener.
-                final Transaction geometryTransaction = new Transaction();
+                final Transaction surfaceUpdateTransaction = new Transaction();
                 if (creating) {
                     updateOpaqueFlag();
                     final String name = "SurfaceView[" + viewRoot.getTitle().toString() + "]";
-                    createBlastSurfaceControls(viewRoot, name, geometryTransaction);
+                    createBlastSurfaceControls(viewRoot, name, surfaceUpdateTransaction);
                 } else if (mSurfaceControl == null) {
                     return;
                 }
 
                 final boolean realSizeChanged = performSurfaceTransaction(viewRoot,
-                        translator, creating, sizeChanged, hintChanged, geometryTransaction);
+                        translator, creating, sizeChanged, hintChanged, surfaceUpdateTransaction);
                 final boolean redrawNeeded = sizeChanged || creating || hintChanged
                         || (mVisible && !mDrawFinished);
 
@@ -1047,16 +1041,24 @@
                                 callbacks = getSurfaceCallbacks();
                             }
 
-                            final Transaction t = new Transaction();
-                            if (viewRoot.wasRelayoutRequested()) {
-                                mBlastBufferQueue.setSyncTransaction(t,
-                                        false /* acquireSingleBuffer */);
+                            final boolean wasRelayoutRequested = viewRoot.wasRelayoutRequested();
+                            if (wasRelayoutRequested && (mBlastBufferQueue != null)) {
+                                mBlastBufferQueue.syncNextTransaction(
+                                        false /* acquireSingleBuffer */,
+                                        this::onDrawFinished);
                             }
                             mPendingReportDraws++;
                             viewRoot.drawPending();
                             SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
-                                mBlastBufferQueue.setSyncTransaction(null);
-                                onDrawFinished(t);
+                                if (mBlastBufferQueue != null) {
+                                    mBlastBufferQueue.stopContinuousSyncTransaction();
+                                }
+                                // If relayout was requested, then a callback from BBQ will
+                                // be invoked with the sync transaction. onDrawFinished will be
+                                // called in there
+                                if (!wasRelayoutRequested) {
+                                    onDrawFinished(null);
+                                }
                             });
                             sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
                         }
@@ -1107,7 +1109,7 @@
         mBlastSurfaceControl.setTransformHint(mTransformHint);
         if (mBlastBufferQueue != null) {
             mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight,
-                        mFormat, transaction);
+                        mFormat);
         }
     }
 
@@ -1136,7 +1138,7 @@
      *
      */
     private void createBlastSurfaceControls(ViewRootImpl viewRoot, String name,
-            Transaction geometryTransaction) {
+            Transaction surfaceUpdateTransaction) {
         if (mSurfaceControl == null) {
             mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
                     .setName(name)
@@ -1159,11 +1161,10 @@
                     .build();
         } else {
             // update blast layer
-            mTmpTransaction
+            surfaceUpdateTransaction
                     .setOpaque(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
                     .setSecure(mBlastSurfaceControl, (mSurfaceFlags & SurfaceControl.SECURE) != 0)
-                    .show(mBlastSurfaceControl)
-                    .apply();
+                    .show(mBlastSurfaceControl);
         }
 
         if (mBackgroundControl == null) {
@@ -1184,12 +1185,11 @@
         }
         mTransformHint = viewRoot.getBufferTransformHint();
         mBlastSurfaceControl.setTransformHint(mTransformHint);
-        mBlastBufferQueue = new BLASTBufferQueue(name);
-        mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat,
-                geometryTransaction);
+        mBlastBufferQueue = new BLASTBufferQueue(name, false /* updateDestinationFrame */);
+        mBlastBufferQueue.update(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight, mFormat);
     }
 
-    private void onDrawFinished(Transaction t) {
+    private void onDrawFinished(@Nullable Transaction t) {
         if (DEBUG) {
             Log.i(TAG, System.identityHashCode(this) + " "
                     + "finishedDrawing");
@@ -1211,7 +1211,7 @@
      *
      * @hide
      */
-    protected void onSetSurfacePositionAndScaleRT(@NonNull Transaction transaction,
+    protected void onSetSurfacePositionAndScale(@NonNull Transaction transaction,
             @NonNull SurfaceControl surface, int positionLeft, int positionTop,
             float postScaleX, float postScaleY) {
         transaction.setPosition(surface, positionLeft, positionTop);
@@ -1224,12 +1224,14 @@
         if (mSurfaceControl == null) {
             return;
         }
-        onSetSurfacePositionAndScaleRT(mTmpTransaction, mSurfaceControl,
+        final Transaction transaction = new Transaction();
+        onSetSurfacePositionAndScale(transaction, mSurfaceControl,
                 mScreenRect.left, /*positionLeft*/
                 mScreenRect.top/*positionTop*/ ,
                 mScreenRect.width() / (float) mSurfaceWidth /*postScaleX*/,
                 mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/);
-        mTmpTransaction.apply();
+        applyTransactionOnVriDraw(transaction);
+        invalidate();
     }
 
     /**
@@ -1251,52 +1253,43 @@
         }
     }
 
-    private Rect mRTLastReportedPosition = new Rect();
-    private Point mRTLastReportedSurfaceSize = new Point();
+    private final Rect mRTLastReportedPosition = new Rect();
+    private final Point mRTLastReportedSurfaceSize = new Point();
 
     private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener {
-        int mRtSurfaceWidth = -1;
-        int mRtSurfaceHeight = -1;
+        private final int mRtSurfaceWidth;
+        private final int mRtSurfaceHeight;
         private final SurfaceControl.Transaction mPositionChangedTransaction =
                 new SurfaceControl.Transaction();
-        boolean mPendingTransaction = false;
 
-        SurfaceViewPositionUpdateListener(int surfaceWidth, int surfaceHeight,
-                @Nullable Transaction t) {
+        SurfaceViewPositionUpdateListener(int surfaceWidth, int surfaceHeight) {
             mRtSurfaceWidth = surfaceWidth;
             mRtSurfaceHeight = surfaceHeight;
-            if (t != null) {
-                mPositionChangedTransaction.merge(t);
-                mPendingTransaction = true;
-            }
         }
 
         @Override
         public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
-            synchronized(mSurfaceControlLock) {
-                if (mSurfaceControl == null) {
-                    return;
+            if (mRTLastReportedPosition.left == left
+                    && mRTLastReportedPosition.top == top
+                    && mRTLastReportedPosition.right == right
+                    && mRTLastReportedPosition.bottom == bottom
+                    && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth
+                    && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight) {
+                return;
+            }
+            try {
+                if (DEBUG_POSITION) {
+                    Log.d(TAG, String.format(
+                            "%d updateSurfacePosition RenderWorker, frameNr = %d, "
+                                    + "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
+                            System.identityHashCode(SurfaceView.this), frameNumber,
+                            left, top, right, bottom, mRtSurfaceWidth, mRtSurfaceHeight));
                 }
-                if (mRTLastReportedPosition.left == left
-                        && mRTLastReportedPosition.top == top
-                        && mRTLastReportedPosition.right == right
-                        && mRTLastReportedPosition.bottom == bottom
-                        && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth
-                        && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight
-                        && !mPendingTransaction) {
-                    return;
-                }
-                try {
-                    if (DEBUG_POSITION) {
-                        Log.d(TAG, String.format(
-                                "%d updateSurfacePosition RenderWorker, frameNr = %d, "
-                                        + "position = [%d, %d, %d, %d] surfaceSize = %dx%d",
-                                System.identityHashCode(SurfaceView.this), frameNumber,
-                                left, top, right, bottom, mRtSurfaceWidth, mRtSurfaceHeight));
-                    }
+                synchronized (mSurfaceControlLock) {
+                    if (mSurfaceControl == null) return;
                     mRTLastReportedPosition.set(left, top, right, bottom);
                     mRTLastReportedSurfaceSize.set(mRtSurfaceWidth, mRtSurfaceHeight);
-                    onSetSurfacePositionAndScaleRT(mPositionChangedTransaction, mSurfaceControl,
+                    onSetSurfacePositionAndScale(mPositionChangedTransaction, mSurfaceControl,
                             mRTLastReportedPosition.left /*positionLeft*/,
                             mRTLastReportedPosition.top /*positionTop*/,
                             mRTLastReportedPosition.width()
@@ -1304,13 +1297,13 @@
                             mRTLastReportedPosition.height()
                                     / (float) mRtSurfaceHeight /*postScaleY*/);
                     if (mViewVisibility) {
+                        // b/131239825
                         mPositionChangedTransaction.show(mSurfaceControl);
                     }
-                    applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
-                    mPendingTransaction = false;
-                } catch (Exception ex) {
-                    Log.e(TAG, "Exception from repositionChild", ex);
                 }
+                applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
+            } catch (Exception ex) {
+                Log.e(TAG, "Exception from repositionChild", ex);
             }
         }
 
@@ -1334,28 +1327,14 @@
             mRTLastReportedPosition.setEmpty();
             mRTLastReportedSurfaceSize.set(-1, -1);
 
-            /**
-             * positionLost can be called while UI thread is un-paused so we
-             * need to hold the lock here.
-             */
+            // positionLost can be called while UI thread is un-paused.
             synchronized (mSurfaceControlLock) {
-                if (mPendingTransaction) {
-                    Log.w(TAG, System.identityHashCode(SurfaceView.this)
-                            + "Pending transaction cleared.");
-                    mPositionChangedTransaction.clear();
-                    mPendingTransaction = false;
-                }
-                if (mSurfaceControl == null) {
-                    return;
-                }
+                if (mSurfaceControl == null) return;
+                // b/131239825
                 mRtTransaction.hide(mSurfaceControl);
                 applyOrMergeTransaction(mRtTransaction, frameNumber);
             }
         }
-
-        public Transaction getTransaction() {
-            return mPositionChangedTransaction;
-        }
     }
 
     private SurfaceViewPositionUpdateListener mPositionListener = null;
@@ -1402,8 +1381,10 @@
      * @hide
      */
     public void setResizeBackgroundColor(int bgColor) {
-        setResizeBackgroundColor(mTmpTransaction, bgColor);
-        mTmpTransaction.apply();
+        final SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+        setResizeBackgroundColor(transaction, bgColor);
+        applyTransactionOnVriDraw(transaction);
+        invalidate();
     }
 
     /**
@@ -1818,4 +1799,11 @@
             t.apply();
         }
     }
+
+    /**
+     * @hide
+     */
+    public void syncNextFrame(Consumer<Transaction> t) {
+        mBlastBufferQueue.syncNextTransaction(t);
+    }
 }
diff --git a/core/java/android/view/SyncRtSurfaceTransactionApplier.java b/core/java/android/view/SyncRtSurfaceTransactionApplier.java
index 3e21103..e9c937cc 100644
--- a/core/java/android/view/SyncRtSurfaceTransactionApplier.java
+++ b/core/java/android/view/SyncRtSurfaceTransactionApplier.java
@@ -65,10 +65,12 @@
         applyParams(t, params);
 
         mTargetViewRootImpl.registerRtFrameCallback(frame -> {
-            if (mTargetSc == null || !mTargetSc.isValid()) {
-                return;
+            if (mTargetSc != null && mTargetSc.isValid()) {
+                applyTransaction(t, frame);
             }
-            applyTransaction(t, frame);
+            // The transaction was either dropped, successfully applied, or merged with a future
+            // transaction, so we can safely release its resources.
+            t.close();
         });
 
         // Make sure a frame gets scheduled.
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 1566f9e..785735c 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -184,6 +184,7 @@
      */
     public static final String DEBUG_FORCE_DARK = "debug.hwui.force_dark";
 
+    public static int EGL_CONTEXT_PRIORITY_REALTIME_NV = 0x3357;
     public static int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101;
     public static int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102;
     public static int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 34a1386..c222991 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -46,9 +46,11 @@
 import android.annotation.LayoutRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.Size;
 import android.annotation.StyleRes;
 import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UiContext;
 import android.annotation.UiThread;
@@ -4744,6 +4746,7 @@
          */
         private List<Rect> mSystemGestureExclusionRects = null;
         private List<Rect> mKeepClearRects = null;
+        private List<Rect> mUnrestrictedKeepClearRects = null;
         private boolean mPreferKeepClear = false;
         private Rect mHandwritingArea = null;
 
@@ -4766,6 +4769,9 @@
     @UnsupportedAppUsage
     ListenerInfo mListenerInfo;
 
+    private boolean mPreferKeepClearForFocus;
+    private Runnable mMarkPreferKeepClearForFocus;
+
     private static class TooltipInfo {
         /**
          * Text to be displayed in a tooltip popup.
@@ -8168,6 +8174,7 @@
         }
 
         notifyEnterOrExitForAutoFillIfNeeded(gainFocus);
+        updatePreferKeepClearForFocus();
     }
 
     /**
@@ -8226,9 +8233,25 @@
      */
     public void setAccessibilityPaneTitle(@Nullable CharSequence accessibilityPaneTitle) {
         if (!TextUtils.equals(accessibilityPaneTitle, mAccessibilityPaneTitle)) {
+            boolean currentPaneTitleEmpty = mAccessibilityPaneTitle == null;
+            boolean newPaneTitleEmpty =  accessibilityPaneTitle == null;
             mAccessibilityPaneTitle = accessibilityPaneTitle;
-            notifyViewAccessibilityStateChangedIfNeeded(
-                    AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_TITLE);
+            // Make explicitly important as nulled titles need to be important for DISAPPEARED
+            // events.
+            if (mAccessibilityPaneTitle != null
+                    && getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+                setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+            }
+            if (currentPaneTitleEmpty) {
+                notifyViewAccessibilityStateChangedIfNeeded(
+                        AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_APPEARED);
+            } else if (newPaneTitleEmpty) {
+                notifyViewAccessibilityStateChangedIfNeeded(
+                        AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED);
+            } else {
+                notifyViewAccessibilityStateChangedIfNeeded(
+                        AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_TITLE);
+            }
         }
     }
 
@@ -11713,6 +11736,7 @@
         final ListenerInfo info = getListenerInfo();
         if (getSystemGestureExclusionRects().isEmpty()
                 && collectPreferKeepClearRects().isEmpty()
+                && collectUnrestrictedPreferKeepClearRects().isEmpty()
                 && (info.mHandwritingArea == null || !isAutoHandwritingEnabled())) {
             if (info.mPositionUpdateListener != null) {
                 mRenderNode.removePositionUpdateListener(info.mPositionUpdateListener);
@@ -11787,8 +11811,8 @@
      * <p>
      * The system will try to respect this preference, but when not possible will ignore it.
      * <p>
-     * Note: while this is set to {@code true}, the system will ignore the {@code Rect}s provided
-     * through {@link #setPreferKeepClearRects} (but not clear them).
+     * Note: This is independent from {@link #setPreferKeepClearRects}. If both are set, both will
+     * be taken into account.
      * <p>
      * @see #setPreferKeepClearRects
      * @see #isPreferKeepClear
@@ -11822,8 +11846,8 @@
      * <p>
      * The system will try to respect this preference, but when not possible will ignore it.
      * <p>
-     * Note: While {@link #isPreferKeepClear} is {@code true}, the {@code Rect}s set here are
-     * ignored.
+     * Note: This is independent from {@link #setPreferKeepClear}. If both are set, both will be
+     * taken into account.
      * <p>
      * @see #setPreferKeepClear
      * @see #getPreferKeepClearRects
@@ -11855,6 +11879,52 @@
         return Collections.emptyList();
     }
 
+    /**
+     * Set a preference to keep the provided rects clear from floating windows above this
+     * view's window. This informs the system that these rects are considered vital areas for the
+     * user and that ideally they should not be covered. Setting this is only appropriate for UI
+     * where the user would likely take action to uncover it.
+     * <p>
+     * Note: The difference with {@link #setPreferKeepClearRects} is that the system won't apply
+     * restrictions to the rects set here.
+     * <p>
+     * @see #setPreferKeepClear
+     * @see #getPreferKeepClearRects
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS)
+    public final void setUnrestrictedPreferKeepClearRects(@NonNull List<Rect> rects) {
+        final ListenerInfo info = getListenerInfo();
+        if (info.mUnrestrictedKeepClearRects != null) {
+            info.mUnrestrictedKeepClearRects.clear();
+            info.mUnrestrictedKeepClearRects.addAll(rects);
+        } else {
+            info.mUnrestrictedKeepClearRects = new ArrayList<>(rects);
+        }
+        updatePositionUpdateListener();
+        postUpdate(this::updateKeepClearRects);
+    }
+
+    /**
+     * @return the list of rects, set by {@link #setPreferKeepClearRects}.
+     *
+     * @see #setPreferKeepClearRects
+     *
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public final List<Rect> getUnrestrictedPreferKeepClearRects() {
+        final ListenerInfo info = mListenerInfo;
+        if (info != null && info.mKeepClearRects != null) {
+            return new ArrayList(info.mUnrestrictedKeepClearRects);
+        }
+
+        return Collections.emptyList();
+    }
+
     void updateKeepClearRects() {
         final AttachInfo ai = mAttachInfo;
         if (ai != null) {
@@ -11868,15 +11938,57 @@
      */
     @NonNull
     List<Rect> collectPreferKeepClearRects() {
+        ListenerInfo info = mListenerInfo;
+        final List<Rect> list = new ArrayList<>();
+
+        if ((info != null && info.mPreferKeepClear) || mPreferKeepClearForFocus) {
+            list.add(new Rect(0, 0, getWidth(), getHeight()));
+        }
+
+        if (info != null && info.mKeepClearRects != null) {
+            list.addAll(info.mKeepClearRects);
+        }
+
+        return list;
+    }
+
+    private void updatePreferKeepClearForFocus() {
+        if (mMarkPreferKeepClearForFocus != null) {
+            removeCallbacks(mMarkPreferKeepClearForFocus);
+            mMarkPreferKeepClearForFocus = null;
+        }
+
+        final ViewConfiguration configuration = ViewConfiguration.get(mContext);
+        final int delay = configuration.getPreferKeepClearForFocusDelay();
+        if (delay >= 0) {
+            mMarkPreferKeepClearForFocus = () -> {
+                mPreferKeepClearForFocus = isFocused();
+                mMarkPreferKeepClearForFocus = null;
+
+                updatePositionUpdateListener();
+                post(this::updateKeepClearRects);
+            };
+            postDelayed(mMarkPreferKeepClearForFocus, delay);
+        }
+    }
+
+    private void cancelMarkPreferKeepClearForFocus() {
+        if (mMarkPreferKeepClearForFocus != null) {
+            removeCallbacks(mMarkPreferKeepClearForFocus);
+            mMarkPreferKeepClearForFocus = null;
+        }
+        mPreferKeepClearForFocus = false;
+    }
+
+    /**
+     * Retrieve the list of unrestricted areas within this view's post-layout coordinate space
+     * which the system will try to not cover with other floating elements, like the pip window.
+     */
+    @NonNull
+    List<Rect> collectUnrestrictedPreferKeepClearRects() {
         final ListenerInfo info = mListenerInfo;
-        if (info != null) {
-            final List<Rect> list = new ArrayList();
-            if (info.mPreferKeepClear) {
-                list.add(new Rect(0, 0, getWidth(), getHeight()));
-            } else if (info.mKeepClearRects != null) {
-                list.addAll(info.mKeepClearRects);
-            }
-            return list;
+        if (info != null && info.mUnrestrictedKeepClearRects != null) {
+            return info.mUnrestrictedKeepClearRects;
         }
 
         return Collections.emptyList();
@@ -13575,6 +13687,7 @@
             }
             invalidate();
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
+            updatePreferKeepClearForFocus();
             return true;
         }
         return false;
@@ -13654,6 +13767,8 @@
                     sendAccessibilityEventUnchecked(event);
                 }
             }
+
+            updatePreferKeepClearForFocus();
         }
     }
 
@@ -14168,9 +14283,12 @@
         }
 
         // Changes to views with a pane title count as window state changes, as the pane title
-        // marks them as significant parts of the UI.
+        // marks them as significant parts of the UI. A visible view with a nulled title may send
+        // a disappeared event.
         if ((changeType != AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE)
-                && isAccessibilityPane()) {
+                && (isAccessibilityPane()
+                || (changeType == AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED)
+                && isAggregatedVisible())) {
             // If the pane isn't visible, content changed events are sufficient unless we're
             // reporting that the view just disappeared
             if ((isAggregatedVisible())
@@ -20903,6 +21021,7 @@
         removePerformClickCallback();
         clearAccessibilityThrottles();
         stopNestedScroll();
+        cancelMarkPreferKeepClearForFocus();
 
         // Anything that started animating right before detach should already
         // be in its final state when re-attached.
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index b25c025..ebc409e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -347,6 +347,7 @@
     private final long mScreenshotChordKeyTimeout;
     private final int mSmartSelectionInitializedTimeout;
     private final int mSmartSelectionInitializingTimeout;
+    private final int mPreferKeepClearForFocusDelay;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915)
     private boolean sHasPermanentMenuKey;
@@ -392,6 +393,7 @@
         mMinScalingSpan = 0;
         mSmartSelectionInitializedTimeout = SMART_SELECTION_INITIALIZED_TIMEOUT_IN_MILLISECOND;
         mSmartSelectionInitializingTimeout = SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND;
+        mPreferKeepClearForFocusDelay = -1;
     }
 
     /**
@@ -506,6 +508,8 @@
                 com.android.internal.R.integer.config_smartSelectionInitializedTimeoutMillis);
         mSmartSelectionInitializingTimeout = res.getInteger(
                 com.android.internal.R.integer.config_smartSelectionInitializingTimeoutMillis);
+        mPreferKeepClearForFocusDelay = res.getInteger(
+                com.android.internal.R.integer.config_preferKeepClearForFocusDelayMillis);
     }
 
     /**
@@ -1096,6 +1100,16 @@
     }
 
     /**
+     * @return The delay in milliseconds before focused Views set themselves as preferred to keep
+     *         clear, or -1 if Views should not set themselves as preferred to keep clear.
+     * @hide
+     */
+    @TestApi
+    public int getPreferKeepClearForFocusDelay() {
+        return mPreferKeepClearForFocusDelay;
+    }
+
+    /**
      * @return the duration in milliseconds before an end of a long press causes a tooltip to be
      * hidden
      * @hide
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 8444032..bde761e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -76,6 +76,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -195,6 +196,10 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Scroller;
 import android.window.ClientWindowFrames;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
+import android.window.OnBackInvokedDispatcherOwner;
+import android.window.SurfaceSyncer;
 import android.window.WindowOnBackInvokedDispatcher;
 
 import com.android.internal.R;
@@ -217,9 +222,10 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.lang.ref.WeakReference;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
 import java.util.Queue;
@@ -775,6 +781,8 @@
             new ViewRootRectTracker(v -> v.getSystemGestureExclusionRects());
     private final ViewRootRectTracker mKeepClearRectsTracker =
             new ViewRootRectTracker(v -> v.collectPreferKeepClearRects());
+    private final ViewRootRectTracker mUnrestrictedKeepClearRectsTracker =
+            new ViewRootRectTracker(v -> v.collectUnrestrictedPreferKeepClearRects());
 
     private IAccessibilityEmbeddedConnection mAccessibilityEmbeddedConnection;
 
@@ -796,15 +804,6 @@
     }
 
     /**
-     * This is only used on the RenderThread when handling a blast sync. Specifically, it's only
-     * used when calling {@link BLASTBufferQueue#setSyncTransaction(Transaction)} and then merged
-     * with a tmp transaction on the Render Thread. The tmp transaction is then merged into
-     * {@link #mSurfaceChangedTransaction} on the UI Thread, avoiding any threading issues.
-     */
-    private final SurfaceControl.Transaction mRtBLASTSyncTransaction =
-            new SurfaceControl.Transaction();
-
-    /**
      * Keeps track of the last frame number that was attempted to draw. Should only be accessed on
      * the RenderThread.
      */
@@ -823,6 +822,8 @@
 
     private boolean mRelayoutRequested;
 
+    private int mLastTransformHint = Integer.MIN_VALUE;
+
     private String mTag = TAG;
 
     public ViewRootImpl(Context context, Display display) {
@@ -2460,8 +2461,9 @@
             if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": baseSize=" + baseSize
                     + ", desiredWindowWidth=" + desiredWindowWidth);
             if (baseSize != 0 && desiredWindowWidth > baseSize) {
-                childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
-                childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
+                childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width, lp.privateFlags);
+                childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height,
+                        lp.privateFlags);
                 performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                 if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": measured ("
                         + host.getMeasuredWidth() + "," + host.getMeasuredHeight()
@@ -2474,7 +2476,7 @@
                     baseSize = (baseSize+desiredWindowWidth)/2;
                     if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": next baseSize="
                             + baseSize);
-                    childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width);
+                    childWidthMeasureSpec = getRootMeasureSpec(baseSize, lp.width, lp.privateFlags);
                     performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
                     if (DEBUG_DIALOG) Log.v(mTag, "Window " + mView + ": measured ("
                             + host.getMeasuredWidth() + "," + host.getMeasuredHeight() + ")");
@@ -2487,8 +2489,10 @@
         }
 
         if (!goodMeasure) {
-            childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
-            childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height);
+            childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width,
+                    lp.privateFlags);
+            childHeightMeasureSpec = getRootMeasureSpec(desiredWindowHeight, lp.height,
+                    lp.privateFlags);
             performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
             if (mWidth != host.getMeasuredWidth() || mHeight != host.getMeasuredHeight()) {
                 windowSizeMayChange = true;
@@ -2721,6 +2725,10 @@
         // Execute enqueued actions on every traversal in case a detached view enqueued an action
         getRunQueue().executeActions(mAttachInfo.mHandler);
 
+        if (mApplyInsetsRequested && !(mWillMove || mWillResize)) {
+            dispatchApplyInsets(host);
+        }
+
         boolean layoutRequested = mLayoutRequested && (!mStopped || mReportNextDraw);
         if (layoutRequested) {
 
@@ -2785,18 +2793,6 @@
             }
         }
 
-        if (mApplyInsetsRequested && !(mWillMove || mWillResize)) {
-            dispatchApplyInsets(host);
-            if (mLayoutRequested) {
-                // Short-circuit catching a new layout request here, so
-                // we don't need to go through two layout passes when things
-                // change due to fitting system windows, which can happen a lot.
-                windowSizeMayChange |= measureHierarchy(host, lp,
-                        mView.getContext().getResources(),
-                        desiredWindowWidth, desiredWindowHeight);
-            }
-        }
-
         if (layoutRequested) {
             // Clear this now, so that if anything requests a layout in the
             // rest of this function we will catch it and re-run a full
@@ -2885,16 +2881,6 @@
                             host.getMeasuredHeight() + ", params=" + params);
                 }
 
-                if (mAttachInfo.mThreadedRenderer != null) {
-                    // relayoutWindow may decide to destroy mSurface. As that decision
-                    // happens in WindowManager service, we need to be defensive here
-                    // and stop using the surface in case it gets destroyed.
-                    if (mAttachInfo.mThreadedRenderer.pause()) {
-                        // Animations were running so we need to push a frame
-                        // to resume them
-                        mDirty.set(0, 0, mWidth, mHeight);
-                    }
-                }
                 if (mFirst || viewVisibilityChanged) {
                     mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED;
                 }
@@ -3156,8 +3142,10 @@
                 if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
                         || mHeight != host.getMeasuredHeight() || dispatchApplyInsets ||
                         updatedConfiguration) {
-                    int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
-                    int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
+                    int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width,
+                            lp.privateFlags);
+                    int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height,
+                            lp.privateFlags);
 
                     if (DEBUG_LAYOUT) Log.v(mTag, "Ooops, something changed!  mWidth="
                             + mWidth + " measuredWidth=" + host.getMeasuredWidth()
@@ -3693,7 +3681,7 @@
             return current;
         }
 
-        final Queue<AccessibilityNodeInfo> fringe = new LinkedList<>();
+        final Queue<AccessibilityNodeInfo> fringe = new ArrayDeque<>();
         fringe.offer(current);
 
         while (!fringe.isEmpty()) {
@@ -3957,31 +3945,28 @@
      * Figures out the measure spec for the root view in a window based on it's
      * layout params.
      *
-     * @param windowSize
-     *            The available width or height of the window
-     *
-     * @param rootDimension
-     *            The layout params for one dimension (width or height) of the
-     *            window.
-     *
+     * @param windowSize The available width or height of the window.
+     * @param measurement The layout width or height requested in the layout params.
+     * @param privateFlags The private flags in the layout params of the window.
      * @return The measure spec to use to measure the root view.
      */
-    private static int getRootMeasureSpec(int windowSize, int rootDimension) {
+    private static int getRootMeasureSpec(int windowSize, int measurement, int privateFlags) {
         int measureSpec;
+        final int rootDimension = (privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0
+                ? MATCH_PARENT : measurement;
         switch (rootDimension) {
-
-        case ViewGroup.LayoutParams.MATCH_PARENT:
-            // Window can't resize. Force root view to be windowSize.
-            measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY);
-            break;
-        case ViewGroup.LayoutParams.WRAP_CONTENT:
-            // Window can resize. Set max size for root view.
-            measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST);
-            break;
-        default:
-            // Window wants to be an exact size. Force root view to be that size.
-            measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY);
-            break;
+            case ViewGroup.LayoutParams.MATCH_PARENT:
+                // Window can't resize. Force root view to be windowSize.
+                measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.EXACTLY);
+                break;
+            case ViewGroup.LayoutParams.WRAP_CONTENT:
+                // Window can resize. Set max size for root view.
+                measureSpec = MeasureSpec.makeMeasureSpec(windowSize, MeasureSpec.AT_MOST);
+                break;
+            default:
+                // Window wants to be an exact size. Force root view to be that size.
+                measureSpec = MeasureSpec.makeMeasureSpec(rootDimension, MeasureSpec.EXACTLY);
+                break;
         }
         return measureSpec;
     }
@@ -4181,42 +4166,49 @@
                         + " didProduceBuffer=" + didProduceBuffer);
             }
 
-            Transaction tmpTransaction = new Transaction();
-            tmpTransaction.merge(mRtBLASTSyncTransaction);
-
             // If frame wasn't drawn, clear out the next transaction so it doesn't affect the next
             // draw attempt. The next transaction and transaction complete callback were only set
             // for the current draw attempt.
+            final Transaction pendingTransactions;
             if (!didProduceBuffer) {
-                mBlastBufferQueue.setSyncTransaction(null);
+                mBlastBufferQueue.syncNextTransaction(null);
                 // Get the transactions that were sent to mergeWithNextTransaction since the
                 // frame didn't draw on this vsync. It's possible the frame will draw later, but
                 // it's better to not be sync than to block on a frame that may never come.
-                Transaction pendingTransactions = mBlastBufferQueue.gatherPendingTransactions(
+                pendingTransactions = mBlastBufferQueue.gatherPendingTransactions(
                         mRtLastAttemptedDrawFrameNum);
-                tmpTransaction.merge(pendingTransactions);
+                if (!useBlastSync && !reportNextDraw) {
+                    pendingTransactions.apply();
+                }
+            } else {
+                pendingTransactions = null;
             }
-            if (!useBlastSync && !reportNextDraw) {
-                tmpTransaction.apply();
-            }
-
             // Post at front of queue so the buffer can be processed immediately and allow RT
             // to continue processing new buffers. If RT tries to process buffers before the sync
             // buffer is applied, the new buffers will not get acquired and could result in a
             // deadlock. UI thread would wait on RT, but RT would be blocked waiting for a free
             // buffer.
             mHandler.postAtFrontOfQueue(() -> {
-                if (useBlastSync) {
-                    mSurfaceChangedTransaction.merge(tmpTransaction);
+                if (!didProduceBuffer && useBlastSync) {
+                    mSurfaceChangedTransaction.merge(pendingTransactions);
                     if (blastSyncConsumer != null) {
                         blastSyncConsumer.accept(mSurfaceChangedTransaction);
                     }
                 }
 
-                if (reportNextDraw) {
+                // This is to ensure pendingDrawFinished is only called exactly one time per draw
+                // attempt when reportNextDraw is true. Since, we sometimes create a sync
+                // transaction callback, the callback will handle calling pendingDrawFinished.
+                // However, there are cases where the transaction callback may not be called.
+                // 1. If useBlastSync is false, then we know that a sync transaction callback was
+                // not created so we won't invoke pendingDrawFinished there.
+                // 2. If the draw didn't produce a frame, didProduceBuffer == false, then we know
+                // the sync transaction callback will not be invoked even if one was set up.
+                if (reportNextDraw && (!didProduceBuffer || !useBlastSync)) {
                     pendingDrawFinished();
                 }
             });
+
         };
     }
 
@@ -4299,7 +4291,19 @@
                     // Frame callbacks will always occur after submitting draw requests and before
                     // the draw actually occurs. This will ensure that we set the next transaction
                     // for the frame that's about to get drawn and not on a previous frame.
-                    mBlastBufferQueue.setSyncTransaction(mRtBLASTSyncTransaction);
+                    mBlastBufferQueue.syncNextTransaction(
+                            t -> {
+                                mHandler.postAtFrontOfQueue(() -> {
+                                    mSurfaceChangedTransaction.merge(t);
+                                    if (blastSyncConsumer != null) {
+                                        blastSyncConsumer.accept(mSurfaceChangedTransaction);
+                                    }
+
+                                    if (reportNextDraw) {
+                                        pendingDrawFinished();
+                                    }
+                                });
+                            });
                 }
 
                 return createFrameCommitCallbackForSync(useBlastSync, reportNextDraw,
@@ -4881,14 +4885,26 @@
      */
     void updateKeepClearRectsForView(View view) {
         mKeepClearRectsTracker.updateRectsForView(view);
+        mUnrestrictedKeepClearRectsTracker.updateRectsForView(view);
         mHandler.sendEmptyMessage(MSG_KEEP_CLEAR_RECTS_CHANGED);
     }
 
     void keepClearRectsChanged() {
-        final List<Rect> rectsForWindowManager = mKeepClearRectsTracker.computeChangedRects();
-        if (rectsForWindowManager != null && mView != null) {
+        List<Rect> restrictedKeepClearRects = mKeepClearRectsTracker.computeChangedRects();
+        List<Rect> unrestrictedKeepClearRects =
+                mUnrestrictedKeepClearRectsTracker.computeChangedRects();
+        if ((restrictedKeepClearRects != null || unrestrictedKeepClearRects != null)
+                && mView != null) {
+            if (restrictedKeepClearRects == null) {
+                restrictedKeepClearRects = Collections.emptyList();
+            }
+            if (unrestrictedKeepClearRects == null) {
+                unrestrictedKeepClearRects = Collections.emptyList();
+            }
+
             try {
-                mWindowSession.reportKeepClearAreasChanged(mWindow, rectsForWindowManager);
+                mWindowSession.reportKeepClearAreasChanged(mWindow, restrictedKeepClearRects,
+                        unrestrictedKeepClearRects);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -8042,13 +8058,29 @@
 
         final int transformHint = SurfaceControl.rotationToBufferTransform(
                 (mDisplayInstallOrientation + mDisplay.getRotation()) % 4);
-        mSurfaceControl.setTransformHint(transformHint);
 
         final WindowConfiguration winConfig = getConfiguration().windowConfiguration;
         final boolean dragResizing = (relayoutResult
                 & (RELAYOUT_RES_DRAG_RESIZING_DOCKED | RELAYOUT_RES_DRAG_RESIZING_FREEFORM)) != 0;
         WindowLayout.computeSurfaceSize(mWindowAttributes, winConfig.getMaxBounds(), requestedWidth,
                 requestedHeight, mTmpFrames.frame, dragResizing, mSurfaceSize);
+      
+        final boolean transformHintChanged = transformHint != mLastTransformHint;
+        final boolean sizeChanged = !mLastSurfaceSize.equals(mSurfaceSize);
+        final boolean surfaceControlChanged =
+                (relayoutResult & RELAYOUT_RES_SURFACE_CHANGED) == RELAYOUT_RES_SURFACE_CHANGED;
+        if (mAttachInfo.mThreadedRenderer != null &&
+                (transformHintChanged || sizeChanged || surfaceControlChanged)) {
+            if (mAttachInfo.mThreadedRenderer.pause()) {
+                // Animations were running so we need to push a frame
+                // to resume them
+                mDirty.set(0, 0, mWidth, mHeight);
+            }
+        }
+
+        mLastTransformHint = transformHint;
+      
+        mSurfaceControl.setTransformHint(transformHint);
 
         if (mAttachInfo.mContentCaptureManager != null) {
             MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager
@@ -8073,6 +8105,9 @@
                 dispatchTransformHintChanged(transformHint);
             }
         } else {
+            if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.pause()) {
+                mDirty.set(0, 0, mWidth, mHeight);
+            }
             destroySurface();
         }
 
@@ -10880,4 +10915,69 @@
     IWindowSession getWindowSession() {
         return mWindowSession;
     }
+
+    private void registerCallbacksForSync(
+            final SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
+        if (!isHardwareEnabled()) {
+            // TODO: correctly handle when hardware disabled
+            syncBufferCallback.onBufferReady(null);
+            return;
+        }
+
+        mAttachInfo.mThreadedRenderer.registerRtFrameCallback(new FrameDrawingCallback() {
+            @Override
+            public void onFrameDraw(long frame) {
+            }
+
+            @Override
+            public HardwareRenderer.FrameCommitCallback onFrameDraw(int syncResult, long frame) {
+                if (DEBUG_BLAST) {
+                    Log.d(mTag,
+                            "Received frameDrawingCallback syncResult=" + syncResult + " frameNum="
+                                    + frame + ".");
+                }
+
+                // If the syncResults are SYNC_LOST_SURFACE_REWARD_IF_FOUND or
+                // SYNC_CONTEXT_IS_STOPPED it means nothing will draw. There's no need to set up
+                // any blast sync or commit callback, and the code should directly call
+                // pendingDrawFinished.
+                if ((syncResult
+                        & (SYNC_LOST_SURFACE_REWARD_IF_FOUND | SYNC_CONTEXT_IS_STOPPED)) != 0) {
+                    syncBufferCallback.onBufferReady(
+                            mBlastBufferQueue.gatherPendingTransactions(frame));
+                    return null;
+                }
+
+                if (DEBUG_BLAST) {
+                    Log.d(mTag, "Setting up sync and frameCommitCallback");
+                }
+
+                mBlastBufferQueue.syncNextTransaction(t -> syncBufferCallback.onBufferReady(t));
+
+                return didProduceBuffer -> {
+                    if (DEBUG_BLAST) {
+                        Log.d(mTag, "Received frameCommittedCallback"
+                                + " lastAttemptedDrawFrameNum=" + frame
+                                + " didProduceBuffer=" + didProduceBuffer);
+                    }
+
+                    // If frame wasn't drawn, clear out the next transaction so it doesn't affect
+                    // the next draw attempt. The next transaction and transaction complete callback
+                    // were only set for the current draw attempt.
+                    if (!didProduceBuffer) {
+                        mBlastBufferQueue.syncNextTransaction(null);
+                        // Gather the transactions that were sent to mergeWithNextTransaction
+                        // since the frame didn't draw on this vsync. It's possible the frame will
+                        // draw later, but it's better to not be sync than to block on a frame that
+                        // may never come.
+                        syncBufferCallback.onBufferReady(
+                                mBlastBufferQueue.gatherPendingTransactions(frame));
+                    }
+                };
+            }
+        });
+    }
+
+    public final SurfaceSyncer.SyncTarget mSyncTarget =
+            syncBufferCallback -> registerCallbacksForSync(syncBufferCallback);
 }
diff --git a/core/java/android/view/WindowLayout.java b/core/java/android/view/WindowLayout.java
index 27f89ec..ad9f21b 100644
--- a/core/java/android/view/WindowLayout.java
+++ b/core/java/android/view/WindowLayout.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import static android.view.Gravity.DISPLAY_CLIP_HORIZONTAL;
+import static android.view.Gravity.DISPLAY_CLIP_VERTICAL;
 import static android.view.InsetsState.ITYPE_IME;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
@@ -29,6 +31,7 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
@@ -250,11 +253,39 @@
         Gravity.apply(attrs.gravity, w, h, outParentFrame,
                 (int) (x + attrs.horizontalMargin * pw),
                 (int) (y + attrs.verticalMargin * ph), outFrame);
+
         // Now make sure the window fits in the overall display frame.
         if (fitToDisplay) {
             Gravity.applyDisplay(attrs.gravity, outDisplayFrame, outFrame);
         }
 
+        if ((attrs.privateFlags & PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT) != 0
+                && !cutout.isEmpty()) {
+            // If the actual frame covering a display cutout, and the window is requesting to extend
+            // it's requested frame, re-do the frame calculation after getting the new requested
+            // size.
+            mTempRect.set(outFrame);
+            // Do nothing if the display cutout and window don't overlap entirely. This may happen
+            // when the cutout is not on the same side with the window.
+            boolean shouldExpand = false;
+            final Rect [] cutoutBounds = cutout.getBoundingRectsAll();
+            for (Rect cutoutBound : cutoutBounds) {
+                if (cutoutBound.isEmpty()) continue;
+                if (mTempRect.contains(cutoutBound) || cutoutBound.contains(mTempRect)) {
+                    shouldExpand = true;
+                    break;
+                }
+            }
+            if (shouldExpand) {
+                // Try to fit move the bar to avoid the display cutout first. Make sure the clip
+                // flags are not set to make the window move.
+                final int clipFlags = DISPLAY_CLIP_VERTICAL | DISPLAY_CLIP_HORIZONTAL;
+                Gravity.applyDisplay(attrs.gravity & ~clipFlags, displayCutoutSafe,
+                        mTempRect);
+                outFrame.union(mTempRect);
+            }
+        }
+
         if (DEBUG) Log.d(TAG, "computeWindowFrames " + attrs.getTitle()
                 + " outFrame=" + outFrame.toShortString()
                 + " outParentFrame=" + outParentFrame.toShortString()
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 8ee3e43..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;
@@ -2385,6 +2384,16 @@
         public static final int PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR = 0x00001000;
 
         /**
+         * Flag to indicate that the window frame should be the requested frame adding the display
+         * cutout frame. This will only be applied if a specific size smaller than the parent frame
+         * is given, and the window is covering the display cutout. The extended frame will not be
+         * larger than the parent frame.
+         *
+         * {@hide}
+         */
+        public static final int PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT = 0x00002000;
+
+        /**
          * Flag that will make window ignore app visibility and instead depend purely on the decor
          * view visibility for determining window visibility. This is used by recents to keep
          * drawing after it launches an app.
@@ -3350,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
@@ -3364,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
@@ -4835,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/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 93cb0dd7..2dc5fbd 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -752,6 +752,14 @@
     public void removeWindowlessRoot(ViewRootImpl impl) {
         synchronized (mLock) {
             mWindowlessRoots.remove(impl);
+	}
+    }
+
+    public void setRecentsAppBehindSystemBars(boolean behindSystemBars) {
+        try {
+            getWindowManagerService().setRecentsAppBehindSystemBars(behindSystemBars);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 }
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index c81b8cc..a270c92 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -31,6 +31,7 @@
 import android.window.IOnBackInvokedCallback;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -473,12 +474,12 @@
 
     @Override
     public void reportSystemGestureExclusionChanged(android.view.IWindow window,
-            java.util.List<android.graphics.Rect> exclusionRects) {
+            List<Rect> exclusionRects) {
     }
 
     @Override
-    public void reportKeepClearAreasChanged(android.view.IWindow window,
-            java.util.List<android.graphics.Rect> exclusionRects) {
+    public void reportKeepClearAreasChanged(android.view.IWindow window, List<Rect> restrictedRects,
+            List<Rect> unrestrictedRects) {
     }
 
     @Override
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index cd8dd86..cd0dd1d 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -385,6 +385,25 @@
  *   <li>{@link #getText()} - The text of the announcement.</li>
  * </ul>
  * </p>
+  * <p>
+ * <b>speechStateChanged</b>
+ * <em>Type:</em> {@link #TYPE_SPEECH_STATE_CHANGE}</br>
+ * Represents a change in the speech state defined by the
+ * bit mask of the speech state change types.
+ * A change in the speech state occurs when an application wants to signal that
+ * it is either speaking or listening for human speech.
+ * This event helps avoid conflicts where two applications want to speak or one listens
+ * when another speaks.
+ * When sending this event, the sender should ensure that  the accompanying state change types
+ * make sense. For example, the sender should not send
+ * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together.
+ * <em>Properties:</em></br>
+ * <ul>
+ *   <li>{@link #getSpeechStateChangeTypes()} - The type of state changes</li>
+ *   <li>{@link #getPackageName()} - The package name of the source.</li>
+ *   <li>{@link #getEventTime()}  - The event time.</li>
+ * </ul>
+ * </p>
  *
  * @see android.view.accessibility.AccessibilityManager
  * @see android.accessibilityservice.AccessibilityService
@@ -553,14 +572,20 @@
     public static final int TYPE_ASSIST_READING_CONTEXT = 0x01000000;
 
     /**
-     * Represents a change in the speech state defined by the content-change types. A change in the
-     * speech state occurs when another service is either speaking or listening for human speech.
-     * This event helps avoid conflicts where two services want to speak or one listens
+     * Represents a change in the speech state defined by the speech state change types.
+     * A change in the speech state occurs when an application wants to signal that it is either
+     * speaking or listening for human speech.
+     * This event helps avoid conflicts where two applications want to speak or one listens
      * when another speaks.
+     * When sending this event, the sender should ensure that  the accompanying state change types
+     * make sense. For example, the sender should not send
+     * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together.
      * @see #SPEECH_STATE_SPEAKING_START
      * @see #SPEECH_STATE_SPEAKING_END
      * @see #SPEECH_STATE_LISTENING_START
      * @see #SPEECH_STATE_LISTENING_END
+     * @see #getSpeechStateChangeTypes
+     * @see #setSpeechStateChangeTypes
      */
     public static final int TYPE_SPEECH_STATE_CHANGE = 0x02000000;
 
@@ -592,6 +617,11 @@
     /**
      * Change type for {@link #TYPE_WINDOW_STATE_CHANGED} event:
      * The node's pane title changed.
+     * <p>
+     * If this makes the pane appear, {@link #CONTENT_CHANGE_TYPE_PANE_APPEARED} is sent
+     * instead. If this makes the pane disappear, {@link #CONTENT_CHANGE_TYPE_PANE_DISAPPEARED}
+     * is sent.
+     *
      */
     public static final int CONTENT_CHANGE_TYPE_PANE_TITLE = 0x00000008;
 
@@ -1062,7 +1092,7 @@
     }
 
     /**
-     * Gets the speech state signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event
+     * Gets the bit mask of the speech state signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event
      *
      * @see #SPEECH_STATE_SPEAKING_START
      * @see #SPEECH_STATE_SPEAKING_END
@@ -1073,7 +1103,7 @@
         return mSpeechStateChangeTypes;
     }
 
-    private static String speechStateChangedTypesToString(int types) {
+    private static String speechStateChangeTypesToString(int types) {
         return BitUtils.flagsToString(
                 types, AccessibilityEvent::singleSpeechStateChangeTypeToString);
     }
@@ -1094,14 +1124,18 @@
     }
 
     /**
-     * Sets the speech state type signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event
+     * Sets the bit mask of the speech state change types
+     * signaled by a {@link #TYPE_SPEECH_STATE_CHANGE} event.
+     * The sender is responsible for ensuring that  the state change types  make sense. For example,
+     * the sender should not send
+     * {@link #SPEECH_STATE_SPEAKING_START} and {@link #SPEECH_STATE_SPEAKING_END} together.
      *
      * @see #SPEECH_STATE_SPEAKING_START
      * @see #SPEECH_STATE_SPEAKING_END
      * @see #SPEECH_STATE_LISTENING_START
      * @see #SPEECH_STATE_LISTENING_END
      */
-    public void setSpeechStateChangeTypes(int state) {
+    public void setSpeechStateChangeTypes(@SpeechStateChangeTypes int state) {
         enforceNotSealed();
         mSpeechStateChangeTypes = state;
     }
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 07b7a18..6853278 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -46,11 +46,11 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Queue;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -1166,7 +1166,7 @@
                         + connectionIdWaitingForPrefetchResultCopy + ";Result: " + infos,
                         Binder.getCallingUid(),
                         Arrays.asList(Thread.currentThread().getStackTrace()),
-                        new HashSet<String>(Arrays.asList("getStackTrace")),
+                        new HashSet<>(Collections.singletonList("getStackTrace")),
                         FLAGS_ACCESSIBILITY_INTERACTION_CONNECTION_CALLBACK);
             }
         } else if (DEBUG) {
@@ -1348,7 +1348,7 @@
         }
         // Check for duplicates.
         HashSet<AccessibilityNodeInfo> seen = new HashSet<>();
-        Queue<AccessibilityNodeInfo> fringe = new LinkedList<>();
+        Queue<AccessibilityNodeInfo> fringe = new ArrayDeque<>();
         fringe.add(root);
         while (!fringe.isEmpty()) {
             AccessibilityNodeInfo current = fringe.poll();
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/accessibility/IWindowMagnificationConnection.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
index 67d9667..62d029b 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnection.aidl
@@ -32,7 +32,7 @@
     /**
      * Enables window magnification on specified display with given center and scale and animation.
      *
-     * @param displayId The logical display id.
+     * @param displayId the logical display id.
      * @param scale magnification scale.
      * @param centerX the screen-relative X coordinate around which to center,
      *                or {@link Float#NaN} to leave unchanged.
@@ -51,7 +51,7 @@
     /**
      * Sets the scale of the window magnifier on specified display.
      *
-     * @param displayId The logical display id.
+     * @param displayId the logical display id.
      * @param scale magnification scale.
      */
     void setScale(int displayId, float scale);
@@ -59,7 +59,7 @@
      /**
      * Disables window magnification on specified display with animation.
      *
-     * @param displayId The logical display id.
+     * @param displayId the logical display id.
      * @param callback The callback called when the animation is completed or interrupted.
      */
     void disableWindowMagnification(int displayId,
@@ -68,6 +68,7 @@
     /**
      * Moves the window magnifier on the specified display. It has no effect while animating.
      *
+     * @param displayId the logical display id.
      * @param offsetX the amount in pixels to offset the window magnifier in the X direction, in
      *                current screen pixels.
      * @param offsetY the amount in pixels to offset the window magnifier in the Y direction, in
@@ -76,9 +77,20 @@
     void moveWindowMagnifier(int displayId, float offsetX, float offsetY);
 
     /**
+     * Moves the window magnifier on the given display.
+     *
+     * @param displayId the logical display id.
+     * @param positionX the x-axis position of the center of the magnified source bounds.
+     * @param positionY the y-axis position of the center of the magnified source bounds.
+     * @param callback the callback called when the animation is completed or interrupted.
+     */
+    void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
+        in IRemoteMagnificationAnimationCallback callback);
+
+    /**
      * Requests System UI show magnification mode button UI on the specified display.
      *
-     * @param displayId The logical display id.
+     * @param displayId the logical display id.
      * @param magnificationMode the current magnification mode.
      */
     void showMagnificationButton(int displayId, int magnificationMode);
@@ -86,7 +98,7 @@
     /**
      * Requests System UI remove magnification mode button UI on the specified display.
      *
-     * @param displayId The logical display id.
+     * @param displayId the logical display id.
      */
     void removeMagnificationButton(int displayId);
 
diff --git a/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl b/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
index 722546e..adfeb6d 100644
--- a/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
+++ b/core/java/android/view/accessibility/IWindowMagnificationConnectionCallback.aidl
@@ -68,12 +68,10 @@
     void onAccessibilityActionPerformed(int displayId);
 
     /**
-     * Called when the user is performing dragging gesture. It is started after the offset
-     * between the down location and the move event location exceed
-     * {@link ViewConfiguration#getScaledTouchSlop()}.
+     * Called when the user is performing move action.
      *
      * @param displayId The logical display id.
      */
-    void onDrag(int displayId);
+    void onMove(int displayId);
 
 }
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b7994db..a8cc114 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -58,6 +58,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.provider.DeviceConfig;
 import android.service.autofill.AutofillService;
 import android.service.autofill.FillCallback;
 import android.service.autofill.FillEventHistory;
@@ -491,6 +492,15 @@
     public static final String DEVICE_CONFIG_AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES =
             "compat_mode_allowed_packages";
 
+    /**
+     * Sets the fill dialog feature enabled or not.
+     *
+     * @hide
+     */
+    @TestApi
+    public static final String DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED =
+            "autofill_dialog_enabled";
+
     /** @hide */
     public static final int RESULT_OK = 0;
     /** @hide */
@@ -539,7 +549,7 @@
      */
     public static final int NO_SESSION = Integer.MAX_VALUE;
 
-    private static final boolean HAS_FILL_DIALOG_UI_FEATURE = false;
+    private static final boolean HAS_FILL_DIALOG_UI_FEATURE_DEFAULT = false;
 
     private final IAutoFillManager mService;
 
@@ -655,6 +665,8 @@
 
     @Nullable private List<AutofillId> mFillDialogTriggerIds;
 
+    private final boolean mIsFillDialogEnabled;
+
     /** @hide */
     public interface AutofillClient {
         /**
@@ -795,6 +807,14 @@
         mIsFillRequested = false;
         mRequireAutofill = false;
 
+        mIsFillDialogEnabled = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_AUTOFILL,
+                DEVICE_CONFIG_AUTOFILL_DIALOG_ENABLED,
+                HAS_FILL_DIALOG_UI_FEATURE_DEFAULT);
+        if (sDebug) {
+            Log.d(TAG, "Fill dialog is enabled:" + mIsFillDialogEnabled);
+        }
+
         if (mOptions != null) {
             sDebug = (mOptions.loggingLevel & FLAG_ADD_CLIENT_DEBUG) != 0;
             sVerbose = (mOptions.loggingLevel & FLAG_ADD_CLIENT_VERBOSE) != 0;
@@ -1081,7 +1101,7 @@
     }
 
     private boolean hasFillDialogUiFeature() {
-        return HAS_FILL_DIALOG_UI_FEATURE;
+        return mIsFillDialogEnabled;
     }
 
     /**
@@ -3012,6 +3032,7 @@
         }
         pw.print(pfx); pw.print("compat mode enabled: ");
         synchronized (mLock) {
+            pw.print(pfx); pw.print("fill dialog enabled: "); pw.println(mIsFillDialogEnabled);
             if (mCompatibilityBridge != null) {
                 final String pfx2 = pfx + "  ";
                 pw.println("true");
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index 8600f55..7f07146 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -575,7 +575,9 @@
     }
 
     /**
-     * Returns {@link EditorBoundsInfo} editor related bounds.
+     * Returns {@link EditorBoundsInfo} for the current editor, or {@code null} if IME is not
+     * subscribed with {@link InputConnection#CURSOR_UPDATE_FILTER_EDITOR_BOUNDS}
+     * or {@link InputConnection#CURSOR_UPDATE_MONITOR}.
      */
     @Nullable
     public EditorBoundsInfo getEditorBoundsInfo() {
diff --git a/core/java/android/view/inputmethod/EditorBoundsInfo.java b/core/java/android/view/inputmethod/EditorBoundsInfo.java
index 081dc81..df82438 100644
--- a/core/java/android/view/inputmethod/EditorBoundsInfo.java
+++ b/core/java/android/view/inputmethod/EditorBoundsInfo.java
@@ -30,13 +30,13 @@
 public final class EditorBoundsInfo implements Parcelable {
 
     /**
-     * Container of rectangular position of Editor in the current window.
+     * The bounding box of the of currently focused text editor in local coordinates.
      */
     private final RectF mEditorBounds;
 
     /**
-     * Container of rectangular position of Editor with additional padding around for initiating
-     * Stylus Handwriting in the current window.
+     * The bounding box of the of currently focused text editor with additional padding around it
+     * for initiating Stylus Handwriting in the current window.
      */
     private final RectF mHandwritingBounds;
 
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 78509fe..dac1be6 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -1043,6 +1043,23 @@
     int CURSOR_UPDATE_FILTER_INSERTION_MARKER = 1 << 4;
 
     /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {CURSOR_UPDATE_IMMEDIATE, CURSOR_UPDATE_MONITOR}, flag = true,
+            prefix = { "CURSOR_UPDATE_" })
+    @interface CursorUpdateMode{}
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {CURSOR_UPDATE_FILTER_EDITOR_BOUNDS, CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS,
+            CURSOR_UPDATE_FILTER_INSERTION_MARKER}, flag = true,
+            prefix = { "CURSOR_UPDATE_FILTER_" })
+    @interface CursorUpdateFilter{}
+
+    /**
      * Called by the input method to ask the editor for calling back
      * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)} to
      * notify cursor/anchor locations.
@@ -1063,6 +1080,34 @@
     boolean requestCursorUpdates(int cursorUpdateMode);
 
     /**
+     * Called by the input method to ask the editor for calling back
+     * {@link InputMethodManager#updateCursorAnchorInfo(android.view.View, CursorAnchorInfo)} to
+     * notify cursor/anchor locations.
+     *
+     * @param cursorUpdateMode combination of update modes:
+     * {@link #CURSOR_UPDATE_IMMEDIATE}, {@link #CURSOR_UPDATE_MONITOR}
+     * @param cursorUpdateFilter any combination of data filters:
+     * {@link #CURSOR_UPDATE_FILTER_CHARACTER_BOUNDS}, {@link #CURSOR_UPDATE_FILTER_EDITOR_BOUNDS},
+     * {@link #CURSOR_UPDATE_FILTER_INSERTION_MARKER}.
+     *
+     * <p>Pass {@code 0} to disable them. However, if an unknown flag is provided, request will be
+     * rejected and method will return {@code false}.</p>
+     * @return {@code true} if the request is scheduled. {@code false} to indicate that when the
+     *         application will not call {@link InputMethodManager#updateCursorAnchorInfo(
+     *         android.view.View, CursorAnchorInfo)}.
+     *         Since Android {@link android.os.Build.VERSION_CODES#N} until
+     *         {@link android.os.Build.VERSION_CODES#TIRAMISU}, this API returned {@code false} when
+     *         the target application does not implement this method.
+     */
+    default boolean requestCursorUpdates(@CursorUpdateMode int cursorUpdateMode,
+            @CursorUpdateFilter int cursorUpdateFilter) {
+        if (cursorUpdateFilter == 0) {
+            return requestCursorUpdates(cursorUpdateMode);
+        }
+        return false;
+    }
+
+    /**
      * Called by the system to enable application developers to specify a dedicated thread on which
      * {@link InputConnection} methods are called back.
      *
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 2717463..da20e33 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -46,6 +46,8 @@
 import android.annotation.TestApi;
 import android.annotation.UserIdInt;
 import android.app.ActivityThread;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -356,6 +358,21 @@
     /** @hide */
     public static final int SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES = 2;
 
+    /**
+     * Clear {@link #SHOW_FORCED} flag when the next IME focused application changed.
+     *
+     * <p>
+     * Note that when this flag enabled in server side, {@link #SHOW_FORCED} will no longer
+     * affect the next focused application to keep showing IME, in case of unexpected IME visible
+     * when the next focused app isn't be the IME requester. </p>
+     *
+     * @hide
+     */
+    @TestApi
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    public static final long CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING = 214016041L; // This is a bug id.
+
     @UnsupportedAppUsage
     final IInputMethodManager mService;
     final Looper mMainLooper;
@@ -1646,7 +1663,14 @@
      * Flag for {@link #showSoftInput} to indicate that the user has forced
      * the input method open (such as by long-pressing menu) so it should
      * not be closed until they explicitly do so.
+     *
+     * @deprecated Use {@link #showSoftInput} without this flag instead. Using this flag can lead
+     * to the soft input remaining visible even when the calling application is closed. The
+     * use of this flag can make the soft input remains visible globally. Starting in
+     * {@link Build.VERSION_CODES#TIRAMISU Android T}, this flag only has an effect while the
+     * caller is currently focused.
      */
+    @Deprecated
     public static final int SHOW_FORCED = 0x0002;
 
     /**
@@ -1895,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;
@@ -1912,8 +1943,8 @@
                 // TODO (b/210039666): Pipe IME displayId from InputBindResult and use it here.
                 //  instead of mDisplayId.
                 mServedInputConnection.requestCursorUpdatesFromImm(
-                        CURSOR_UPDATE_IMMEDIATE | CURSOR_UPDATE_MONITOR
-                                | CURSOR_UPDATE_FILTER_EDITOR_BOUNDS,
+                        CURSOR_UPDATE_IMMEDIATE | CURSOR_UPDATE_MONITOR,
+                                CURSOR_UPDATE_FILTER_EDITOR_BOUNDS,
                         mDisplayId);
             }
 
@@ -3227,10 +3258,11 @@
      * @return Something that is not well-defined.
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(trackingBug = 204906124, maxTargetSdk = Build.VERSION_CODES.TIRAMISU,
+            publicAlternatives = "Use {@link android.view.WindowInsets} instead")
     public int getInputMethodWindowVisibleHeight() {
         try {
-            return mService.getInputMethodWindowVisibleHeight();
+            return mService.getInputMethodWindowVisibleHeight(mClient);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java b/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
index ef04b2c..6de0316 100644
--- a/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
+++ b/core/java/android/view/selectiontoolbar/SelectionToolbarManager.java
@@ -105,7 +105,7 @@
 
     private boolean isRemoteSelectionToolbarEnabled() {
         return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SELECTION_TOOLBAR,
-                REMOTE_SELECTION_TOOLBAR_ENABLED, true);
+                REMOTE_SELECTION_TOOLBAR_ENABLED, false);
     }
 
     /**
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 6cfb938..5d9f4f6 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -39,7 +39,7 @@
 
 import dalvik.system.CloseGuard;
 
-import java.util.LinkedList;
+import java.util.ArrayDeque;
 import java.util.Locale;
 import java.util.Queue;
 import java.util.concurrent.Executor;
@@ -245,7 +245,7 @@
             }
         }
 
-        private final Queue<SpellCheckerParams> mPendingTasks = new LinkedList<>();
+        private final Queue<SpellCheckerParams> mPendingTasks = new ArrayDeque<>();
         @GuardedBy("SpellCheckerSessionListenerImpl.this")
         private SpellCheckerSession mSpellCheckerSession;
 
diff --git a/core/java/android/view/translation/TranslationManager.java b/core/java/android/view/translation/TranslationManager.java
index 6610375..db1c606 100644
--- a/core/java/android/view/translation/TranslationManager.java
+++ b/core/java/android/view/translation/TranslationManager.java
@@ -33,9 +33,9 @@
 import android.os.SynchronousResultReceiver;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.IntArray;
 import android.util.Log;
 import android.util.Pair;
-import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.SyncResultReceiver;
@@ -102,12 +102,7 @@
 
     @NonNull
     @GuardedBy("mLock")
-    private final SparseArray<Translator> mTranslators = new SparseArray<>();
-
-    @NonNull
-    @GuardedBy("mLock")
-    private final ArrayMap<TranslationContext, Integer> mTranslatorIds =
-            new ArrayMap<>();
+    private final IntArray mTranslatorIds = new IntArray();
 
     @NonNull
     private final Handler mHandler;
@@ -127,6 +122,12 @@
     /**
      * Creates an on-device Translator for natural language translation.
      *
+     * <p>In Android 12, this method provided the same cached Translator object when given the
+     * same TranslationContext object. Do not use a Translator destroyed elsewhere as this will
+     * cause an exception on Android 12.
+     *
+     * <p>In later versions, this method never returns a cached Translator.
+     *
      * @param translationContext {@link TranslationContext} containing the specs for creating the
      *                                                     Translator.
      * @param executor Executor to run callback operations
@@ -140,45 +141,25 @@
         Objects.requireNonNull(callback, "callback cannot be null");
 
         synchronized (mLock) {
-            // TODO(b/176464808): Disallow multiple Translator now, it will throw
-            //  IllegalStateException. Need to discuss if we can allow multiple Translators.
-            if (mTranslatorIds.containsKey(translationContext)) {
-                executor.execute(() -> callback.accept(
-                        mTranslators.get(mTranslatorIds.get(translationContext))));
-                return;
-            }
-
             int translatorId;
             do {
                 translatorId = Math.abs(ID_GENERATOR.nextInt());
-            } while (translatorId == 0 || mTranslators.indexOfKey(translatorId) >= 0);
+            } while (translatorId == 0 || mTranslatorIds.indexOf(translatorId) >= 0);
             final int tId = translatorId;
 
-            new Translator(mContext, translationContext, translatorId, this, mHandler, mService,
-                    new Consumer<Translator>() {
-                        @Override
-                        public void accept(Translator translator) {
-                            if (translator == null) {
-                                final long token = Binder.clearCallingIdentity();
-                                try {
-                                    executor.execute(() -> callback.accept(null));
-                                } finally {
-                                    Binder.restoreCallingIdentity(token);
-                                }
-                                return;
-                            }
-
-                            synchronized (mLock) {
-                                mTranslators.put(tId, translator);
-                                mTranslatorIds.put(translationContext, tId);
-                            }
-                            final long token = Binder.clearCallingIdentity();
-                            try {
-                                executor.execute(() -> callback.accept(translator));
-                            } finally {
-                                Binder.restoreCallingIdentity(token);
-                            }
+            new Translator(mContext, translationContext, tId, this, mHandler, mService,
+                    translator -> {
+                        if (translator == null) {
+                            Binder.withCleanCallingIdentity(
+                                    () -> executor.execute(() -> callback.accept(null)));
+                            return;
                         }
+
+                        synchronized (mLock) {
+                            mTranslatorIds.add(tId);
+                        }
+                        Binder.withCleanCallingIdentity(
+                                () -> executor.execute(() -> callback.accept(translator)));
                     });
         }
     }
@@ -201,16 +182,10 @@
         Objects.requireNonNull(translationContext, "translationContext cannot be null");
 
         synchronized (mLock) {
-            // TODO(b/176464808): Disallow multiple Translator now, it will throw
-            //  IllegalStateException. Need to discuss if we can allow multiple Translators.
-            if (mTranslatorIds.containsKey(translationContext)) {
-                return mTranslators.get(mTranslatorIds.get(translationContext));
-            }
-
             int translatorId;
             do {
                 translatorId = Math.abs(ID_GENERATOR.nextInt());
-            } while (translatorId == 0 || mTranslators.indexOfKey(translatorId) >= 0);
+            } while (translatorId == 0 || mTranslatorIds.indexOf(translatorId) >= 0);
 
             final Translator newTranslator = new Translator(mContext, translationContext,
                     translatorId, this, mHandler, mService);
@@ -220,8 +195,7 @@
                 if (!newTranslator.isSessionCreated()) {
                     return null;
                 }
-                mTranslators.put(translatorId, newTranslator);
-                mTranslatorIds.put(translationContext, translatorId);
+                mTranslatorIds.add(translatorId);
                 return newTranslator;
             } catch (Translator.ServiceBinderReceiver.TimeoutException e) {
                 // TODO(b/176464808): maybe make SyncResultReceiver.TimeoutException constructor
@@ -460,12 +434,9 @@
 
     void removeTranslator(int id) {
         synchronized (mLock) {
-            mTranslators.remove(id);
-            for (int i = 0; i < mTranslatorIds.size(); i++) {
-                if (mTranslatorIds.valueAt(i) == id) {
-                    mTranslatorIds.removeAt(i);
-                    break;
-                }
+            int index = mTranslatorIds.indexOf(id);
+            if (index >= 0) {
+                mTranslatorIds.remove(index);
             }
         }
     }
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 280e7df..3160057 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1366,7 +1366,10 @@
      * Sets the WebView's user-agent string. If the string is {@code null} or empty,
      * the system default value will be used.
      *
-     * Note that starting from {@link android.os.Build.VERSION_CODES#KITKAT} Android
+     * <p>If the user-agent is overridden in this way, the values of the User-Agent Client Hints
+     * headers and {@code navigator.userAgentData} for this WebView will be empty.
+     *
+     * <p>Note that starting from {@link android.os.Build.VERSION_CODES#KITKAT} Android
      * version, changing the user-agent while loading a web page causes WebView
      * to initiate loading once again.
      *
@@ -1554,7 +1557,7 @@
      * @see #getForceDark
      * @deprecated The "force dark" model previously implemented by WebView was complex
      * and didn't interoperate well with current Web standards for
-     * prefers-color-scheme and color-scheme. In apps with
+     * {@code prefers-color-scheme} and {@code color-scheme}. In apps with
      * {@code targetSdkVersion} &ge; {@link android.os.Build.VERSION_CODES#TIRAMISU}
      * this API is a no-op and WebView will always use the dark style defined by web content
      * authors if the app's theme is dark. To customize the behavior, refer to
@@ -1602,6 +1605,61 @@
      * If Android is applying Force Dark to WebView then WebView will ignore the value of
      * this setting and behave as if it were set to true.
      *
+     * <p>
+     * The deprecated {@link #setForceDark} and related API are no-ops in apps with
+     * {@code targetSdkVersion} &ge; {@link android.os.Build.VERSION_CODES#TIRAMISU},
+     * but they still apply to apps with
+     * {@code targetSdkVersion} &lt; {@link android.os.Build.VERSION_CODES#TIRAMISU}.
+     *
+     * <p>
+     * The below table summarizes how APIs work with different apps.
+     *
+     * <table border="2" width="85%" align="center" cellpadding="5">
+     *     <thead>
+     *         <tr>
+     *             <th>App</th>
+     *             <th>Web content which uses {@code prefers-color-scheme}</th>
+     *             <th>Web content which does not use {@code prefers-color-scheme}</th>
+     *         </tr>
+     *     </thead>
+     *     <tbody>
+     *     <tr>
+     *         <td>App with {@code isLightTheme} True or not set</td>
+     *         <td>Renders with the light theme defined by the content author.</td>
+     *         <td>Renders with the default styling defined by the content author.</td>
+     *     </tr>
+     *     <tr>
+     *         <td>App with Android forceDark in effect</td>
+     *         <td>Renders with the dark theme defined by the content author.</td>
+     *         <td>Renders with the styling modified to dark colors by an algorithm
+     *             if allowed by the content author.</td>
+     *     </tr>
+     *     <tr>
+     *         <td>App with {@code isLightTheme} False,
+     *            {@code targetSdkVersion} &lt; {@link android.os.Build.VERSION_CODES#TIRAMISU},
+     *             and has {@code FORCE_DARK_AUTO}</td>
+     *         <td>Renders with the dark theme defined by the content author.</td>
+     *         <td>Renders with the default styling defined by the content author.</td>
+     *     </tr>
+     *     <tr>
+     *         <td>App with {@code isLightTheme} False,
+     *            {@code targetSdkVersion} &ge; {@link android.os.Build.VERSION_CODES#TIRAMISU},
+     *             and {@code setAlgorithmicDarkening(false)}</td>
+     *         <td>Renders with the dark theme defined by the content author.</td>
+     *         <td>Renders with the default styling defined by the content author.</td>
+     *     </tr>
+     *     <tr>
+     *         <td>App with {@code isLightTheme} False,
+     *            {@code targetSdkVersion} &ge; {@link android.os.Build.VERSION_CODES#TIRAMISU},
+     *             and {@code setAlgorithmicDarkening(true)}</td>
+     *         <td>Renders with the dark theme defined by the content author.</td>
+     *         <td>Renders with the styling modified to dark colors by an algorithm if allowed
+     *             by the content author.</td>
+     *     </tr>
+     *     </tbody>
+     * </table>
+     * </p>
+     *
      * @param allow allow algorithmic darkening or not.
      */
     public void setAlgorithmicDarkeningAllowed(boolean allow) {
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index 2bfbe4b..bc7a5fd 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.Zygote;
 
 /** @hide */
 public class WebViewZygote {
@@ -127,13 +128,15 @@
 
         try {
             String abi = sPackage.applicationInfo.primaryCpuAbi;
+            int runtimeFlags = Zygote.getMemorySafetyRuntimeFlagsForSecondaryZygote(
+                    sPackage.applicationInfo, null);
             sZygote = Process.ZYGOTE_PROCESS.startChildZygote(
                     "com.android.internal.os.WebViewZygoteInit",
                     "webview_zygote",
                     Process.WEBVIEW_ZYGOTE_UID,
                     Process.WEBVIEW_ZYGOTE_UID,
                     null,  // gids
-                    0,  // runtimeFlags
+                    runtimeFlags,
                     "webview_zygote",  // seInfo
                     abi,  // abi
                     TextUtils.join(",", Build.SUPPORTED_ABIS),
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1d8e9a3..231ae08 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6180,6 +6180,11 @@
         }
 
         @Override
+        public boolean requestCursorUpdates(int cursorUpdateMode, int cursorUpdateFilter) {
+            return getTarget().requestCursorUpdates(cursorUpdateMode, cursorUpdateFilter);
+        }
+
+        @Override
         public Handler getHandler() {
             return getTarget().getHandler();
         }
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..b076d39 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -12313,7 +12313,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 +12635,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/widget/inline/InlineContentView.java b/core/java/android/widget/inline/InlineContentView.java
index 9712311..e4f483a 100644
--- a/core/java/android/widget/inline/InlineContentView.java
+++ b/core/java/android/widget/inline/InlineContentView.java
@@ -230,8 +230,9 @@
             int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
         mSurfaceView = new SurfaceView(context, attrs, defStyleAttr, defStyleRes) {
+            // b/219807628
             @Override
-            protected void onSetSurfacePositionAndScaleRT(
+            protected void onSetSurfacePositionAndScale(
                     @NonNull SurfaceControl.Transaction transaction,
                     @NonNull SurfaceControl surface, int positionLeft, int positionTop,
                     float postScaleX, float postScaleY) {
@@ -248,7 +249,7 @@
                 postScaleX = InlineContentView.this.getScaleX();
                 postScaleY = InlineContentView.this.getScaleY();
 
-                super.onSetSurfacePositionAndScaleRT(transaction, surface, positionLeft,
+                super.onSetSurfacePositionAndScale(transaction, surface, positionLeft,
                         positionTop, postScaleX, postScaleY);
             }
         };
diff --git a/core/java/android/window/BackNavigationInfo.java b/core/java/android/window/BackNavigationInfo.java
index 1e922d9..6653758 100644
--- a/core/java/android/window/BackNavigationInfo.java
+++ b/core/java/android/window/BackNavigationInfo.java
@@ -61,7 +61,7 @@
     public static final int TYPE_CROSS_TASK = 3;
 
     /**
-     * A {@link android.view.OnBackInvokedCallback} is available and needs to be called.
+     * A {@link OnBackInvokedCallback} is available and needs to be called.
      * <p>
      */
     public static final int TYPE_CALLBACK = 4;
@@ -206,13 +206,13 @@
     }
 
     /**
-     * Returns the {@link android.view.OnBackInvokedCallback} of the top level window or null if
+     * Returns the {@link OnBackInvokedCallback} of the top level window or null if
      * the client didn't register a callback.
      * <p>
      * This is never null when {@link #getType} returns {@link #TYPE_CALLBACK}.
      *
-     * @see android.view.OnBackInvokedCallback
-     * @see android.view.OnBackInvokedDispatcher
+     * @see OnBackInvokedCallback
+     * @see OnBackInvokedDispatcher
      */
     @Nullable
     public IOnBackInvokedCallback getOnBackInvokedCallback() {
diff --git a/core/java/android/view/OnBackInvokedCallback.java b/core/java/android/window/OnBackInvokedCallback.java
similarity index 97%
rename from core/java/android/view/OnBackInvokedCallback.java
rename to core/java/android/window/OnBackInvokedCallback.java
index 37f858a..dcd80fd 100644
--- a/core/java/android/view/OnBackInvokedCallback.java
+++ b/core/java/android/window/OnBackInvokedCallback.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package android.view;
+package android.window;
 
 import android.app.Activity;
 import android.app.Dialog;
-import android.window.BackEvent;
+import android.view.View;
 
 /**
  * Interface for applications to register back invocation callbacks. This allows the client
diff --git a/core/java/android/view/OnBackInvokedDispatcher.java b/core/java/android/window/OnBackInvokedDispatcher.java
similarity index 95%
rename from core/java/android/view/OnBackInvokedDispatcher.java
rename to core/java/android/window/OnBackInvokedDispatcher.java
index 5c4ee89..63e6d30 100644
--- a/core/java/android/view/OnBackInvokedDispatcher.java
+++ b/core/java/android/window/OnBackInvokedDispatcher.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view;
+package android.window;
 
 import android.annotation.IntDef;
 import android.annotation.IntRange;
@@ -39,7 +39,7 @@
  */
 public interface OnBackInvokedDispatcher {
     /**
-     * Enables dispatching the "back" action via {@link android.view.OnBackInvokedDispatcher}.
+     * Enables dispatching the "back" action via {@link OnBackInvokedDispatcher}.
      *
      * When enabled, the following APIs are no longer invoked:
      * <ul>
@@ -100,7 +100,7 @@
      * @param priority The priority of the callback.
      * @throws {@link IllegalArgumentException} if the priority is negative.
      */
-    @SuppressLint("SamShouldBeLast")
+    @SuppressLint({"SamShouldBeLast", "ExecutorRegistration"})
     void registerOnBackInvokedCallback(
             @NonNull OnBackInvokedCallback callback, @Priority @IntRange(from = 0) int priority);
 
diff --git a/core/java/android/view/OnBackInvokedDispatcherOwner.java b/core/java/android/window/OnBackInvokedDispatcherOwner.java
similarity index 97%
rename from core/java/android/view/OnBackInvokedDispatcherOwner.java
rename to core/java/android/window/OnBackInvokedDispatcherOwner.java
index e69efe0..dfe06fd 100644
--- a/core/java/android/view/OnBackInvokedDispatcherOwner.java
+++ b/core/java/android/window/OnBackInvokedDispatcherOwner.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.view;
+package android.window;
 
 import android.annotation.NonNull;
 
diff --git a/core/java/android/window/ProxyOnBackInvokedDispatcher.java b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
index 4de977a..cf17a21 100644
--- a/core/java/android/window/ProxyOnBackInvokedDispatcher.java
+++ b/core/java/android/window/ProxyOnBackInvokedDispatcher.java
@@ -20,9 +20,6 @@
 import android.annotation.Nullable;
 import android.util.Log;
 import android.util.Pair;
-import android.view.OnBackInvokedCallback;
-import android.view.OnBackInvokedDispatcher;
-import android.view.OnBackInvokedDispatcherOwner;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -81,6 +78,10 @@
         }
         synchronized (mLock) {
             mCallbacks.removeIf((p) -> p.first.equals(callback));
+            if (mActualDispatcherOwner != null) {
+                mActualDispatcherOwner.getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(
+                        callback);
+            }
         }
     }
 
diff --git a/core/java/android/window/SplashScreen.java b/core/java/android/window/SplashScreen.java
index 3f65f47..fab180d 100644
--- a/core/java/android/window/SplashScreen.java
+++ b/core/java/android/window/SplashScreen.java
@@ -52,7 +52,7 @@
      * Flag to be used with {@link ActivityOptions#setSplashScreenStyle}, to avoid showing the
      * splash screen icon of the launched activity
      */
-    int SPLASH_SCREEN_STYLE_EMPTY = 0;
+    int SPLASH_SCREEN_STYLE_SOLID_COLOR = 0;
     /**
      * Flag to be used with {@link ActivityOptions#setSplashScreenStyle}, to show the splash screen
      * icon of the launched activity.
@@ -62,7 +62,7 @@
     /** @hide */
     @IntDef(prefix = { "SPLASH_SCREEN_STYLE_" }, value = {
             SPLASH_SCREEN_STYLE_UNDEFINED,
-            SPLASH_SCREEN_STYLE_EMPTY,
+            SPLASH_SCREEN_STYLE_SOLID_COLOR,
             SPLASH_SCREEN_STYLE_ICON
     })
     @interface SplashScreenStyle {}
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index 34a3418..10d7eca 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -65,6 +65,7 @@
 import java.time.Duration;
 import java.time.Instant;
 import java.util.function.Consumer;
+import java.util.function.LongConsumer;
 
 /**
  * <p>The view which allows an activity to customize its splash screen exit animation.</p>
@@ -151,7 +152,7 @@
         private Instant mIconAnimationStart;
         private Duration mIconAnimationDuration;
         private Consumer<Runnable> mUiThreadInitTask;
-        private boolean mAllowHandleEmpty = true;
+        private boolean mAllowHandleSolidColor = true;
 
         public Builder(@NonNull Context context) {
             mContext = context;
@@ -234,7 +235,7 @@
         /**
          * Set the animation duration if icon is animatable.
          */
-        public Builder setAnimationDurationMillis(int duration) {
+        public Builder setAnimationDurationMillis(long duration) {
             mIconAnimationDuration = Duration.ofMillis(duration);
             return this;
         }
@@ -262,8 +263,8 @@
          * Sets whether this view can be copied and transferred to the client if the view is
          * empty style splash screen.
          */
-        public Builder setAllowHandleEmpty(boolean allowHandleEmpty) {
-            mAllowHandleEmpty = allowHandleEmpty;
+        public Builder setAllowHandleSolidColor(boolean allowHandleSolidColor) {
+            mAllowHandleSolidColor = allowHandleSolidColor;
             return this;
         }
 
@@ -313,7 +314,7 @@
                 }
                 view.mIconView = imageView;
             }
-            if (mOverlayDrawable != null || (view.mIconView == null && !mAllowHandleEmpty)) {
+            if (mOverlayDrawable != null || (view.mIconView == null && !mAllowHandleSolidColor)) {
                 view.setNotCopyable();
             }
 
@@ -521,8 +522,11 @@
         });
     }
 
-    private void animationStartCallback() {
+    private void animationStartCallback(long animDuration) {
         mIconAnimationStart = Instant.now();
+        if (animDuration > 0) {
+            mIconAnimationDuration = Duration.ofMillis(animDuration);
+        }
     }
 
     /**
@@ -693,9 +697,8 @@
          * Prepare the animation if this drawable also be animatable.
          * @param duration The animation duration.
          * @param startListener The callback listener used to receive the start of the animation.
-         * @return true if this drawable object can also be animated and it can be played now.
          */
-        boolean prepareAnimate(long duration, Runnable startListener);
+        void prepareAnimate(long duration, LongConsumer startListener);
 
         /**
          * Stop animation.
diff --git a/core/java/android/window/StartingWindowInfo.java b/core/java/android/window/StartingWindowInfo.java
index 24899a4..5aa4501 100644
--- a/core/java/android/window/StartingWindowInfo.java
+++ b/core/java/android/window/StartingWindowInfo.java
@@ -50,10 +50,10 @@
      */
     public static final int STARTING_WINDOW_TYPE_SNAPSHOT = 2;
     /**
-     * Prefer empty splash screen starting window.
+     * Prefer solid color splash screen starting window.
      * @hide
      */
-    public static final int STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN = 3;
+    public static final int STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN = 3;
 
     /** @hide **/
     public static final int STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN = 4;
@@ -65,7 +65,7 @@
             STARTING_WINDOW_TYPE_NONE,
             STARTING_WINDOW_TYPE_SPLASH_SCREEN,
             STARTING_WINDOW_TYPE_SNAPSHOT,
-            STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN,
+            STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN,
             STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
     })
     public @interface StartingWindowType {}
@@ -115,8 +115,8 @@
             TYPE_PARAMETER_PROCESS_RUNNING,
             TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT,
             TYPE_PARAMETER_ACTIVITY_CREATED,
-            TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN,
-            TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN,
+            TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN,
+            TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN,
             TYPE_PARAMETER_LEGACY_SPLASH_SCREEN
     })
     public @interface StartingTypeParams {}
@@ -135,17 +135,17 @@
     /** @hide */
     public static final int TYPE_PARAMETER_ACTIVITY_CREATED = 0x00000010;
     /** @hide */
-    public static final int TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN = 0x00000020;
+    public static final int TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN = 0x00000020;
     /**
      * The parameter which indicates if the activity has finished drawing.
      * @hide
      */
     public static final int TYPE_PARAMETER_ACTIVITY_DRAWN = 0x00000040;
     /**
-     * Application is allowed to handle empty splash screen.
+     * Application is allowed to handle solid color splash screen.
      * @hide
      */
-    public static final int TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN = 0x00000080;
+    public static final int TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN = 0x00000080;
     /**
      * Application is allowed to use the legacy splash screen
      * @hide
@@ -192,10 +192,10 @@
     }
 
     /**
-     * Return whether the application allow to handle the empty style splash screen.
+     * Return whether the application allow to handle the solid color style splash screen.
      */
-    public boolean allowHandleEmptySplashScreen() {
-        return (startingWindowTypeParameter & TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN) != 0;
+    public boolean allowHandleSolidColorSplashScreen() {
+        return (startingWindowTypeParameter & TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN) != 0;
     }
 
     @Override
diff --git a/core/java/android/window/SurfaceSyncer.java b/core/java/android/window/SurfaceSyncer.java
new file mode 100644
index 0000000..0c32219
--- /dev/null
+++ b/core/java/android/window/SurfaceSyncer.java
@@ -0,0 +1,362 @@
+/*
+ * 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.window;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UiThread;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.SurfaceControl.Transaction;
+import android.view.SurfaceView;
+import android.view.View;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * Used to organize syncs for surfaces.
+ *
+ * The SurfaceSyncer allows callers to add desired syncs into a set and wait for them to all
+ * complete before getting a callback. The purpose of the Syncer is to be an accounting mechanism
+ * so each sync implementation doesn't need to handle it themselves. The Syncer class is used the
+ * following way.
+ *
+ * 1. {@link #setupSync(Runnable)} is called
+ * 2. {@link #addToSync(int, SyncTarget)} is called for every SyncTarget object that wants to be
+ *    included in the sync. If the addSync is called for a View or SurfaceView it needs to be called
+ *    on the UI thread. When addToSync is called, it's guaranteed that any UI updates that were
+ *    requested before addToSync but after the last frame drew, will be included in the sync.
+ * 3. {@link #markSyncReady(int)} should be called when all the {@link SyncTarget}s have been added
+ *    to the SyncSet. Now the SyncSet is closed and no more SyncTargets can be added to it.
+ * 4. The SyncSet will gather the data for each SyncTarget using the steps described below. When
+ *    all the SyncTargets have finished, the syncRequestComplete will be invoked and the transaction
+ *    will either be applied or sent to the caller. In most cases, only the SurfaceSyncer should be
+ *    handling the Transaction object directly. However, there are some cases where the framework
+ *    needs to send the Transaction elsewhere, like in ViewRootImpl, so that option is provided.
+ *
+ * The following is what happens within the {@link SyncSet}
+ *  1. Each SyncableTarget will get a {@link SyncTarget#onReadyToSync} callback that contains
+ *     a {@link SyncBufferCallback}.
+ * 2. Each {@link SyncTarget} needs to invoke {@link SyncBufferCallback#onBufferReady(Transaction)}.
+ *    This makes sure the SyncSet knows when the SyncTarget is complete, allowing the SyncSet to get
+ *    the Transaction that contains the buffer.
+ * 3. When the final SyncBufferCallback finishes for the SyncSet, the syncRequestComplete Consumer
+ *    will be invoked with the transaction that contains all information requested in the sync. This
+ *    could include buffers and geometry changes. The buffer update will include the UI changes that
+ *    were requested for the View.
+ *
+ * @hide
+ */
+public class SurfaceSyncer {
+    private static final String TAG = "SurfaceSyncer";
+    private static final boolean DEBUG = false;
+
+    private static Supplier<Transaction> sTransactionFactory = Transaction::new;
+
+    private final Object mSyncSetLock = new Object();
+    @GuardedBy("mSyncSetLock")
+    private final SparseArray<SyncSet> mSyncSets = new SparseArray<>();
+    @GuardedBy("mSyncSetLock")
+    private int mIdCounter = 0;
+
+    /**
+     * @hide
+     */
+    public static void setTransactionFactory(Supplier<Transaction> transactionFactory) {
+        sTransactionFactory = transactionFactory;
+    }
+
+    /**
+     * Starts a sync and will automatically apply the final, merged transaction.
+     *
+     * @param onComplete The runnable that is invoked when the sync has completed. This will run on
+     *                   the same thread that the sync was started on.
+     * @return The syncId for the newly created sync.
+     * @see #setupSync(Consumer)
+     */
+    public int setupSync(@Nullable Runnable onComplete) {
+        Handler handler = new Handler(Looper.myLooper());
+        return setupSync(transaction -> {
+            transaction.apply();
+            handler.post(onComplete);
+        });
+    }
+
+    /**
+     * Starts a sync.
+     *
+     * @param syncRequestComplete The complete callback that contains the syncId and transaction
+     *                            with all the sync data merged.
+     * @return The syncId for the newly created sync.
+     * @hide
+     * @see #setupSync(Runnable)
+     */
+    public int setupSync(@NonNull Consumer<Transaction> syncRequestComplete) {
+        synchronized (mSyncSetLock) {
+            mIdCounter++;
+            if (DEBUG) {
+                Log.d(TAG, "setupSync " + mIdCounter);
+            }
+            SyncSet syncSet = new SyncSet(mIdCounter, syncRequestComplete);
+            mSyncSets.put(mIdCounter, syncSet);
+            return mIdCounter;
+        }
+    }
+
+    /**
+     * Mark the sync set as ready to complete. No more data can be added to the specified syncId.
+     * Once the sync set is marked as ready, it will be able to complete once all Syncables in the
+     * set have completed their sync
+     *
+     * @param syncId The syncId to mark as ready.
+     */
+    public void markSyncReady(int syncId) {
+        SyncSet syncSet;
+        synchronized (mSyncSetLock) {
+            syncSet = mSyncSets.get(syncId);
+            mSyncSets.remove(syncId);
+        }
+        if (syncSet == null) {
+            Log.e(TAG, "Failed to find syncSet for syncId=" + syncId);
+            return;
+        }
+        syncSet.markSyncReady();
+    }
+
+    /**
+     * Add a SurfaceView to a sync set. This is different than {@link #addToSync(int, View)} because
+     * it requires the caller to notify the start and finish drawing in order to sync.
+     *
+     * @param syncId The syncId to add an entry to.
+     * @param surfaceView The SurfaceView to add to the sync.
+     * @param frameCallbackConsumer The callback that's invoked to allow the caller to notify the
+     *                              Syncer when the SurfaceView has started drawing and finished.
+     *
+     * @return true if the SurfaceView was successfully added to the SyncSet, false otherwise.
+     */
+    @UiThread
+    public boolean addToSync(int syncId, SurfaceView surfaceView,
+            Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
+        return addToSync(syncId, new SurfaceViewSyncTarget(surfaceView, frameCallbackConsumer));
+    }
+
+    /**
+     * Add a View's rootView to a sync set.
+     *
+     * @param syncId The syncId to add an entry to.
+     * @param view The view where the root will be add to the sync set
+     *
+     * @return true if the View was successfully added to the SyncSet, false otherwise.
+     */
+    @UiThread
+    public boolean addToSync(int syncId, @NonNull View view) {
+        return addToSync(syncId, view.getViewRootImpl().mSyncTarget);
+    }
+
+    /**
+     * Add a {@link SyncTarget} to a sync set. The sync set will wait for all
+     * SyncableSurfaces to complete before notifying.
+     *
+     * @param syncId                 The syncId to add an entry to.
+     * @param syncTarget A SyncableSurface that implements how to handle syncing
+     *                               buffers.
+     *
+     * @return true if the SyncTarget was successfully added to the SyncSet, false otherwise.
+     */
+    public boolean addToSync(int syncId, @NonNull SyncTarget syncTarget) {
+        SyncSet syncSet = getAndValidateSyncSet(syncId);
+        if (syncSet == null) {
+            return false;
+        }
+        if (DEBUG) {
+            Log.d(TAG, "addToSync id=" + syncId);
+        }
+        syncSet.addSyncableSurface(syncTarget);
+        return true;
+    }
+
+    /**
+     * Add a transaction to a specific sync so it can be merged along with the frames from the
+     * Syncables in the set. This is so the caller can add arbitrary transaction info that will be
+     * applied at the same time as the buffers
+     * @param syncId  The syncId where the transaction will be merged to.
+     * @param t The transaction to merge in the sync set.
+     */
+    public void addTransactionToSync(int syncId, Transaction t) {
+        SyncSet syncSet = getAndValidateSyncSet(syncId);
+        if (syncSet != null) {
+            syncSet.addTransactionToSync(t);
+        }
+    }
+
+    private SyncSet getAndValidateSyncSet(int syncId) {
+        SyncSet syncSet;
+        synchronized (mSyncSetLock) {
+            syncSet = mSyncSets.get(syncId);
+        }
+        if (syncSet == null) {
+            Log.e(TAG, "Failed to find sync for id=" + syncId);
+            return null;
+        }
+        return syncSet;
+    }
+
+    /**
+     * A SyncTarget that can be added to a sync set.
+     */
+    public interface SyncTarget {
+        /**
+         * Called when the Syncable is ready to begin handing a sync request. When invoked, the
+         * implementor is required to call {@link SyncBufferCallback#onBufferReady(Transaction)}
+         * and {@link SyncBufferCallback#onBufferReady(Transaction)} in order for this Syncable
+         * to be marked as complete.
+         *
+         * @param syncBufferCallback A SyncBufferCallback that the caller must invoke onBufferReady
+         */
+        void onReadyToSync(SyncBufferCallback syncBufferCallback);
+    }
+
+    /**
+     * Interface so the SurfaceSyncer can know when it's safe to start and when everything has been
+     * completed. The caller should invoke the calls when the rendering has started and finished a
+     * frame.
+     */
+    public interface SyncBufferCallback {
+        /**
+         * Invoked when the transaction contains the buffer and is ready to sync.
+         *
+         * @param t The transaction that contains the buffer to be synced. This can be null if
+         *          there's nothing to sync
+         */
+        void onBufferReady(@Nullable Transaction t);
+    }
+
+    /**
+     * Class that collects the {@link SyncTarget}s and notifies when all the surfaces have
+     * a frame ready.
+     */
+    private static class SyncSet {
+        private final Object mLock = new Object();
+
+        @GuardedBy("mLock")
+        private final Set<Integer> mPendingSyncs = new HashSet<>();
+        @GuardedBy("mLock")
+        private final Transaction mTransaction = sTransactionFactory.get();
+        @GuardedBy("mLock")
+        private boolean mSyncReady;
+
+        private final int mSyncId;
+        private final Consumer<Transaction> mSyncRequestCompleteCallback;
+
+        private SyncSet(int syncId, Consumer<Transaction> syncRequestComplete) {
+            mSyncId = syncId;
+            mSyncRequestCompleteCallback = syncRequestComplete;
+        }
+
+        void addSyncableSurface(SyncTarget syncTarget) {
+            SyncBufferCallback syncBufferCallback = new SyncBufferCallback() {
+                @Override
+                public void onBufferReady(Transaction t) {
+                    synchronized (mLock) {
+                        if (t != null) {
+                            mTransaction.merge(t);
+                        }
+                        mPendingSyncs.remove(hashCode());
+                        checkIfSyncIsComplete();
+                    }
+                }
+            };
+
+            synchronized (mLock) {
+                mPendingSyncs.add(syncBufferCallback.hashCode());
+            }
+            syncTarget.onReadyToSync(syncBufferCallback);
+        }
+
+        void markSyncReady() {
+            synchronized (mLock) {
+                mSyncReady = true;
+                checkIfSyncIsComplete();
+            }
+        }
+
+        @GuardedBy("mLock")
+        private void checkIfSyncIsComplete() {
+            if (!mSyncReady || !mPendingSyncs.isEmpty()) {
+                if (DEBUG) {
+                    Log.d(TAG, "Syncable is not complete. mSyncReady=" + mSyncReady
+                            + " mPendingSyncs=" + mPendingSyncs.size());
+                }
+                return;
+            }
+
+            if (DEBUG) {
+                Log.d(TAG, "Successfully finished sync id=" + mSyncId);
+            }
+            mSyncRequestCompleteCallback.accept(mTransaction);
+        }
+
+        /**
+         * Add a Transaction to this sync set. This allows the caller to provide other info that
+         * should be synced with the buffers.
+         */
+        void addTransactionToSync(Transaction t) {
+            synchronized (mLock) {
+                mTransaction.merge(t);
+            }
+        }
+    }
+
+    /**
+     * Wrapper class to help synchronize SurfaceViews
+     */
+    private static class SurfaceViewSyncTarget implements SyncTarget {
+        private final SurfaceView mSurfaceView;
+        private final Consumer<SurfaceViewFrameCallback> mFrameCallbackConsumer;
+
+        SurfaceViewSyncTarget(SurfaceView surfaceView,
+                Consumer<SurfaceViewFrameCallback> frameCallbackConsumer) {
+            mSurfaceView = surfaceView;
+            mFrameCallbackConsumer = frameCallbackConsumer;
+        }
+
+        @Override
+        public void onReadyToSync(SyncBufferCallback syncBufferCallback) {
+            mFrameCallbackConsumer.accept(
+                    () -> mSurfaceView.syncNextFrame(syncBufferCallback::onBufferReady));
+        }
+    }
+
+    /**
+     * A frame callback that is used to synchronize SurfaceViews. The owner of the SurfaceView must
+     * implement onFrameStarted when trying to sync the SurfaceView. This is to ensure the sync
+     * knows when the frame is ready to add to the sync.
+     */
+    public interface SurfaceViewFrameCallback {
+        /**
+         * Called when the SurfaceView is going to render a frame
+         */
+        void onFrameStarted();
+    }
+}
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 4745220e..35c9594 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -31,6 +31,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArrayMap;
+import android.view.InsetsState;
 import android.view.SurfaceControl;
 
 import java.util.ArrayList;
@@ -571,6 +572,74 @@
     }
 
     /**
+     * If `container` was brought to front as a transient-launch (eg. recents), this will reorder
+     * the container back to where it was prior to the transient-launch. This way if a transient
+     * launch is "aborted", the z-ordering of containers in WM should be restored to before the
+     * launch.
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction restoreTransientOrder(
+            @NonNull WindowContainerToken container) {
+        final HierarchyOp hierarchyOp =
+                new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER)
+                        .setContainer(container.asBinder())
+                        .build();
+        mHierarchyOps.add(hierarchyOp);
+        return this;
+    }
+
+    /**
+     * Adds a given {@code Rect} as a rect insets provider on the {@code receiverWindowContainer}.
+     * This will trigger a change of insets for all the children in the subtree of
+     * {@code receiverWindowContainer}.
+     *
+     * @param receiverWindowContainer the window container which the insets provider need to be
+     *                                added to
+     * @param insetsProviderFrame the frame that will be added as Insets provider
+     * @param insetsTypes types of insets the rect provides
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction addRectInsetsProvider(
+            @NonNull WindowContainerToken receiverWindowContainer,
+            @NonNull Rect insetsProviderFrame,
+            @InsetsState.InternalInsetsType int[] insetsTypes) {
+        final HierarchyOp hierarchyOp =
+                new HierarchyOp.Builder(
+                        HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER)
+                        .setContainer(receiverWindowContainer.asBinder())
+                        .setInsetsProviderFrame(insetsProviderFrame)
+                        .setInsetsTypes(insetsTypes)
+                        .build();
+        mHierarchyOps.add(hierarchyOp);
+        return this;
+    }
+
+    /**
+     * Removes the insets provider for the given types from the
+     * {@code receiverWindowContainer}. This will trigger a change of insets for all the children
+     * in the subtree of {@code receiverWindowContainer}.
+     *
+     * @param receiverWindowContainer the window container which the insets-override-provider has
+     *                                to be removed from
+     * @param insetsTypes types of insets that have to be removed
+     * @hide
+     */
+    @NonNull
+    public WindowContainerTransaction removeInsetsProvider(
+            @NonNull WindowContainerToken receiverWindowContainer,
+            @InsetsState.InternalInsetsType int[] insetsTypes) {
+        final HierarchyOp hierarchyOp =
+                new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER)
+                        .setContainer(receiverWindowContainer.asBinder())
+                        .setInsetsTypes(insetsTypes)
+                        .build();
+        mHierarchyOps.add(hierarchyOp);
+        return this;
+    }
+
+    /**
      * When this {@link WindowContainerTransaction} failed to finish on the server side, it will
      * trigger callback with this {@param errorCallbackToken}.
      * @param errorCallbackToken    client provided token that will be passed back as parameter in
@@ -974,6 +1043,9 @@
         public static final int HIERARCHY_OP_TYPE_PENDING_INTENT = 12;
         public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS = 13;
         public static final int HIERARCHY_OP_TYPE_START_SHORTCUT = 14;
+        public static final int HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER = 15;
+        public static final int HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER = 16;
+        public static final int HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER = 17;
 
         // The following key(s) are for use with mLaunchOptions:
         // When launching a task (eg. from recents), this is the taskId to be launched.
@@ -993,6 +1065,10 @@
         @Nullable
         private IBinder mReparent;
 
+        private @InsetsState.InternalInsetsType int[] mInsetsTypes;
+
+        private Rect mInsetsProviderFrame;
+
         // Moves/reparents to top of parent when {@code true}, otherwise moves/reparents to bottom.
         private boolean mToTop;
 
@@ -1111,6 +1187,8 @@
             mType = copy.mType;
             mContainer = copy.mContainer;
             mReparent = copy.mReparent;
+            mInsetsTypes = copy.mInsetsTypes;
+            mInsetsProviderFrame = copy.mInsetsProviderFrame;
             mToTop = copy.mToTop;
             mReparentTopOnly = copy.mReparentTopOnly;
             mMoveAdjacentTogether = copy.mMoveAdjacentTogether;
@@ -1127,6 +1205,12 @@
             mType = in.readInt();
             mContainer = in.readStrongBinder();
             mReparent = in.readStrongBinder();
+            mInsetsTypes = in.createIntArray();
+            if (in.readInt() != 0) {
+                mInsetsProviderFrame = Rect.CREATOR.createFromParcel(in);
+            } else {
+                mInsetsProviderFrame = null;
+            }
             mToTop = in.readBoolean();
             mReparentTopOnly = in.readBoolean();
             mMoveAdjacentTogether = in.readBoolean();
@@ -1152,6 +1236,15 @@
             return mReparent;
         }
 
+        @Nullable
+        public @InsetsState.InternalInsetsType int[] getInsetsTypes() {
+            return mInsetsTypes;
+        }
+
+        public Rect getInsetsProviderFrame() {
+            return mInsetsProviderFrame;
+        }
+
         @NonNull
         public IBinder getContainer() {
             return mContainer;
@@ -1257,6 +1350,13 @@
                 case HIERARCHY_OP_TYPE_START_SHORTCUT:
                     return "{StartShortcut: options=" + mLaunchOptions + " info=" + mShortcutInfo
                             + "}";
+                case HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER:
+                    return "{addRectInsetsProvider: container=" + mContainer
+                            + " insetsProvidingFrame=" + mInsetsProviderFrame
+                            + " insetsType=" + Arrays.toString(mInsetsTypes) + "}";
+                case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER:
+                    return "{removeLocalInsetsProvider: container=" + mContainer
+                            + " insetsType=" + Arrays.toString(mInsetsTypes) + "}";
                 default:
                     return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent
                             + " mToTop=" + mToTop
@@ -1270,6 +1370,13 @@
             dest.writeInt(mType);
             dest.writeStrongBinder(mContainer);
             dest.writeStrongBinder(mReparent);
+            dest.writeIntArray(mInsetsTypes);
+            if (mInsetsProviderFrame != null) {
+                dest.writeInt(1);
+                mInsetsProviderFrame.writeToParcel(dest, 0);
+            } else {
+                dest.writeInt(0);
+            }
             dest.writeBoolean(mToTop);
             dest.writeBoolean(mReparentTopOnly);
             dest.writeBoolean(mMoveAdjacentTogether);
@@ -1309,6 +1416,10 @@
             @Nullable
             private IBinder mReparent;
 
+            private int[] mInsetsTypes;
+
+            private Rect mInsetsProviderFrame;
+
             private boolean mToTop;
 
             private boolean mReparentTopOnly;
@@ -1350,6 +1461,16 @@
                 return this;
             }
 
+            Builder setInsetsTypes(int[] insetsTypes) {
+                mInsetsTypes = insetsTypes;
+                return this;
+            }
+
+            Builder setInsetsProviderFrame(Rect insetsProviderFrame) {
+                mInsetsProviderFrame = insetsProviderFrame;
+                return this;
+            }
+
             Builder setToTop(boolean toTop) {
                 mToTop = toTop;
                 return this;
@@ -1411,6 +1532,8 @@
                 hierarchyOp.mActivityTypes = mActivityTypes != null
                         ? Arrays.copyOf(mActivityTypes, mActivityTypes.length)
                         : null;
+                hierarchyOp.mInsetsTypes = mInsetsTypes;
+                hierarchyOp.mInsetsProviderFrame = mInsetsProviderFrame;
                 hierarchyOp.mToTop = mToTop;
                 hierarchyOp.mReparentTopOnly = mReparentTopOnly;
                 hierarchyOp.mMoveAdjacentTogether = mMoveAdjacentTogether;
diff --git a/core/java/android/window/WindowOnBackInvokedDispatcher.java b/core/java/android/window/WindowOnBackInvokedDispatcher.java
index 0503c40..5dbb551 100644
--- a/core/java/android/window/WindowOnBackInvokedDispatcher.java
+++ b/core/java/android/window/WindowOnBackInvokedDispatcher.java
@@ -27,15 +27,14 @@
 import android.util.Log;
 import android.view.IWindow;
 import android.view.IWindowSession;
-import android.view.OnBackInvokedCallback;
-import android.view.OnBackInvokedDispatcher;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.TreeMap;
 
 /**
- * Provides window based implementation of {@link android.view.OnBackInvokedDispatcher}.
+ * Provides window based implementation of {@link OnBackInvokedDispatcher}.
  *
  * Callbacks with higher priorities receive back dispatching first.
  * Within the same priority, callbacks receive back dispatching in the reverse order
@@ -43,7 +42,7 @@
  *
  * When the top priority callback is updated, the new callback is propagated to the Window Manager
  * if the window the instance is associated with has been attached. It is allowed to register /
- * unregister {@link android.view.OnBackInvokedCallback}s before the window is attached, although
+ * unregister {@link OnBackInvokedCallback}s before the window is attached, although
  * callbacks will not receive dispatches until window attachment.
  *
  * @hide
@@ -54,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, 1) > 0;
+            .getInt(BACK_PREDICTABILITY_PROP, 0) > 0;
 
     /** Convenience hashmap to quickly decide if a callback has been added. */
     private final HashMap<OnBackInvokedCallback, Integer> mAllCallbacks = new HashMap<>();
@@ -76,9 +75,9 @@
 
     /** Detaches the dispatcher instance from its window. */
     public void detachFromWindow() {
+        clear();
         mWindow = null;
         mWindowSession = null;
-        clear();
     }
 
     // TODO: Take an Executor for the callback to run on.
@@ -165,50 +164,13 @@
             } else {
                 int priority = mAllCallbacks.get(callback);
                 mWindowSession.setOnBackInvokedCallback(
-                        mWindow, new OnBackInvokedCallbackWrapper(callback, priority), priority);
+                        mWindow, new OnBackInvokedCallbackWrapper(callback), priority);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Failed to set OnBackInvokedCallback to WM. Error: " + e);
         }
     }
 
-    private class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
-        private final OnBackInvokedCallback mCallback;
-        private final @Priority int mPriority;
-
-        OnBackInvokedCallbackWrapper(
-                @NonNull OnBackInvokedCallback callback, @Priority int priority) {
-            mCallback = callback;
-            mPriority = priority;
-        }
-
-        @NonNull
-        public OnBackInvokedCallback getCallback() {
-            return mCallback;
-        }
-
-        @Override
-        public void onBackStarted() throws RemoteException {
-            Handler.getMain().post(() -> mCallback.onBackStarted());
-        }
-
-        @Override
-        public void onBackProgressed(BackEvent backEvent)
-                throws RemoteException {
-            Handler.getMain().post(() -> mCallback.onBackProgressed(backEvent));
-        }
-
-        @Override
-        public void onBackCancelled() throws RemoteException {
-            Handler.getMain().post(() -> mCallback.onBackCancelled());
-        }
-
-        @Override
-        public void onBackInvoked() throws RemoteException {
-            Handler.getMain().post(() -> mCallback.onBackInvoked());
-        }
-    }
-
     @Override
     public OnBackInvokedCallback getTopCallback() {
         if (mAllCallbacks.isEmpty()) {
@@ -223,11 +185,67 @@
         return null;
     }
 
+    private static class OnBackInvokedCallbackWrapper extends IOnBackInvokedCallback.Stub {
+        private final WeakReference<OnBackInvokedCallback> mCallback;
+
+        OnBackInvokedCallbackWrapper(@NonNull OnBackInvokedCallback callback) {
+            mCallback = new WeakReference<>(callback);
+        }
+
+        @Override
+        public void onBackStarted() {
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackStarted();
+            });
+        }
+
+        @Override
+        public void onBackProgressed(BackEvent backEvent) {
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackProgressed(backEvent);
+            });
+        }
+
+        @Override
+        public void onBackCancelled() {
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackCancelled();
+            });
+        }
+
+        @Override
+        public void onBackInvoked() throws RemoteException {
+            Handler.getMain().post(() -> {
+                final OnBackInvokedCallback callback = mCallback.get();
+                if (callback == null) {
+                    return;
+                }
+
+                callback.onBackInvoked();
+            });
+        }
+    }
+
     /**
      * Returns if the legacy back behavior should be used.
      *
      * Legacy back behavior dispatches KEYCODE_BACK instead of invoking the application registered
-     * {@link android.view.OnBackInvokedCallback}.
+     * {@link OnBackInvokedCallback}.
      */
     public static boolean isOnBackInvokedCallbackEnabled(@Nullable Context context) {
         // new back is enabled if the app targets T AND the feature flag is enabled AND the app
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 4ae6bf7..70506cc 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -771,11 +771,6 @@
             delegationIntent.setComponent(delegateActivity);
             delegationIntent.putExtra(Intent.EXTRA_INTENT, getIntent());
             delegationIntent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, permissionToken);
-
-            // Query prediction availability; mIsAppPredictorComponentAvailable isn't initialized.
-            delegationIntent.putExtra(
-                    EXTRA_IS_APP_PREDICTION_SERVICE_AVAILABLE, isAppPredictionServiceAvailable());
-
             delegationIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
 
             // Don't close until the delegate finishes, or the token will be invalidated.
@@ -972,34 +967,8 @@
     /**
      * Returns true if app prediction service is defined and the component exists on device.
      */
-    @VisibleForTesting
-    public boolean isAppPredictionServiceAvailable() {
-        if (getPackageManager().getAppPredictionServicePackageName() == null) {
-            // Default AppPredictionService is not defined.
-            return false;
-        }
-
-        final String appPredictionServiceName =
-                getString(R.string.config_defaultAppPredictionService);
-        if (appPredictionServiceName == null) {
-            return false;
-        }
-        final ComponentName appPredictionComponentName =
-                ComponentName.unflattenFromString(appPredictionServiceName);
-        if (appPredictionComponentName == null) {
-            return false;
-        }
-
-        // Check if the app prediction component actually exists on the device. The component is
-        // only visible when this is running in a system activity; otherwise this check will fail.
-        Intent intent = new Intent();
-        intent.setComponent(appPredictionComponentName);
-        if (getPackageManager().resolveService(intent, PackageManager.MATCH_ALL) == null) {
-            Log.e(TAG, "App prediction service is defined, but does not exist: "
-                    + appPredictionServiceName);
-            return false;
-        }
-        return true;
+    private boolean isAppPredictionServiceAvailable() {
+        return getPackageManager().getAppPredictionServicePackageName() != null;
     }
 
     /**
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index cdb69e5..fd5eac8 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -33,7 +33,6 @@
 import android.annotation.UiThread;
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
 import android.app.ActivityThread;
 import android.app.VoiceInteractor.PickOptionRequest;
 import android.app.VoiceInteractor.PickOptionRequest.Option;
@@ -54,13 +53,11 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Insets;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.PatternMatcher;
 import android.os.RemoteException;
 import android.os.StrictMode;
@@ -1464,36 +1461,9 @@
 
     public boolean startAsCallerImpl(Intent intent, Bundle options, boolean ignoreTargetSecurity,
             int userId) {
-        // Pass intent to delegate chooser activity with permission token.
-        // TODO: This should move to a trampoline Activity in the system when the ChooserActivity
-        // moves into systemui
-        try {
-            // TODO: Once this is a small springboard activity, it can move off the UI process
-            // and we can move the request method to ActivityManagerInternal.
-            final Intent chooserIntent = new Intent();
-            final ComponentName delegateActivity = ComponentName.unflattenFromString(
-                    Resources.getSystem().getString(R.string.config_chooserActivity));
-            IBinder permissionToken = ActivityTaskManager.getService()
-                    .requestStartActivityPermissionToken(delegateActivity);
-            chooserIntent.setClassName(delegateActivity.getPackageName(),
-                    delegateActivity.getClassName());
-            chooserIntent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, permissionToken);
-
-            // TODO: These extras will change as chooser activity moves into systemui
-            chooserIntent.putExtra(Intent.EXTRA_INTENT, intent);
-            chooserIntent.putExtra(ActivityTaskManager.EXTRA_OPTIONS, options);
-            chooserIntent.putExtra(ActivityTaskManager.EXTRA_IGNORE_TARGET_SECURITY,
-                    ignoreTargetSecurity);
-            chooserIntent.putExtra(Intent.EXTRA_USER_ID, userId);
-            chooserIntent.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
-
-            // Don't close until the delegate finishes, or the token will be invalidated.
-            mAwaitingDelegateResponse = true;
-
-            startActivityForResult(chooserIntent, REQUEST_CODE_RETURN_FROM_DELEGATE_CHOOSER);
-        } catch (RemoteException e) {
-            Log.e(TAG, e.toString());
-        }
+        // Note: this method will be overridden in the delegate implementation to use the passed-in
+        // permission token.
+        startActivityAsCaller(intent, options, null, false, userId);
         return true;
     }
 
@@ -1633,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/app/chooser/DisplayResolveInfo.java b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
index 301de2d..dc53e77 100644
--- a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
+++ b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java
@@ -30,11 +30,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
-import android.provider.DeviceConfig;
 
 import com.android.internal.app.ResolverActivity;
 import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -45,11 +43,6 @@
  * resolve it to an activity.
  */
 public class DisplayResolveInfo implements TargetInfo, Parcelable {
-    private final boolean mEnableChooserDelegate =
-            DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
-                    SystemUiDeviceConfigFlags.USE_DELEGATE_CHOOSER,
-                    false);
-
     private final ResolveInfo mResolveInfo;
     private CharSequence mDisplayLabel;
     private Drawable mDisplayIcon;
@@ -180,12 +173,9 @@
 
     @Override
     public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
-        if (mEnableChooserDelegate) {
-            return activity.startAsCallerImpl(mResolvedIntent, options, false, userId);
-        } else {
-            activity.startActivityAsCaller(mResolvedIntent, options, null, false, userId);
-            return true;
-        }
+        // TODO: if the start-as-caller API no longer requires a permission token, this can go back
+        // to inlining the real activity-start call, and we can remove startAsCallerImpl.
+        return activity.startAsCallerImpl(mResolvedIntent, options, false, userId);
     }
 
     @Override
diff --git a/core/java/com/android/internal/infra/ServiceConnector.java b/core/java/com/android/internal/infra/ServiceConnector.java
index 9ced609..9e07f97 100644
--- a/core/java/com/android/internal/infra/ServiceConnector.java
+++ b/core/java/com/android/internal/infra/ServiceConnector.java
@@ -147,6 +147,15 @@
     void unbind();
 
     /**
+     * Registers a {@link ServiceLifecycleCallbacks callbacks} to be invoked when the lifecycle
+     * of the managed service changes.
+     *
+     * @param callbacks The callbacks that will be run, or {@code null} to clear the existing
+     *                 callbacks.
+     */
+    void setServiceLifecycleCallbacks(@Nullable ServiceLifecycleCallbacks<I> callbacks);
+
+    /**
      * A request to be run when the service is
      * {@link ServiceConnection#onServiceConnected connected}.
      *
@@ -189,6 +198,32 @@
         }
     }
 
+    /**
+     * Collection of callbacks invoked when the lifecycle of the service changes.
+     *
+     * @param <II> the type of the {@link IInterface ipc interface} for the remote service
+     * @see ServiceConnector#setServiceLifecycleCallbacks(ServiceLifecycleCallbacks)
+     */
+    interface ServiceLifecycleCallbacks<II extends IInterface> {
+        /**
+         * Called when the service has just connected and before any queued jobs are run.
+         */
+        default void onConnected(@NonNull II service) {}
+
+        /**
+         * Called just before the service is disconnected and unbound.
+         */
+        default void onDisconnected(@NonNull II service) {}
+
+        /**
+         * Called when the service Binder has died.
+         *
+         * In cases where {@link #onBinderDied()} is invoked the service becomes unbound without
+         * a callback to {@link #onDisconnected(IInterface)}.
+         */
+        default void onBinderDied() {}
+    }
+
 
     /**
      * Implementation of {@link ServiceConnector}
@@ -230,6 +265,8 @@
         private final @NonNull Handler mHandler;
         protected final @NonNull Executor mExecutor;
 
+        @Nullable
+        private volatile ServiceLifecycleCallbacks<I> mServiceLifecycleCallbacks = null;
         private volatile I mService = null;
         private boolean mBinding = false;
         private boolean mUnbinding = false;
@@ -330,6 +367,19 @@
             }
         }
 
+        private void dispatchOnServiceConnectionStatusChanged(
+                @NonNull I service, boolean isConnected) {
+            ServiceLifecycleCallbacks<I> serviceLifecycleCallbacks = mServiceLifecycleCallbacks;
+            if (serviceLifecycleCallbacks != null) {
+                if (isConnected) {
+                    serviceLifecycleCallbacks.onConnected(service);
+                } else {
+                    serviceLifecycleCallbacks.onDisconnected(service);
+                }
+            }
+            onServiceConnectionStatusChanged(service, isConnected);
+        }
+
         /**
          * Called when the service just connected or is about to disconnect
          */
@@ -504,12 +554,17 @@
             mHandler.post(this::unbindJobThread);
         }
 
+        @Override
+        public void setServiceLifecycleCallbacks(@Nullable ServiceLifecycleCallbacks<I> callbacks) {
+            mServiceLifecycleCallbacks = callbacks;
+        }
+
         void unbindJobThread() {
             cancelTimeout();
             I service = mService;
             boolean wasBound = service != null;
             if (wasBound) {
-                onServiceConnectionStatusChanged(service, false);
+                dispatchOnServiceConnectionStatusChanged(service, false);
                 mContext.unbindService(mServiceConnection);
                 service.asBinder().unlinkToDeath(this, 0);
                 mService = null;
@@ -560,7 +615,7 @@
             } catch (RemoteException e) {
                 Log.e(LOG_TAG, "onServiceConnected " + name + ": ", e);
             }
-            onServiceConnectionStatusChanged(service, true);
+            dispatchOnServiceConnectionStatusChanged(service, true);
             processQueue();
         }
 
@@ -572,7 +627,7 @@
             mBinding = true;
             I service = mService;
             if (service != null) {
-                onServiceConnectionStatusChanged(service, false);
+                dispatchOnServiceConnectionStatusChanged(service, false);
                 mService = null;
             }
         }
@@ -592,6 +647,14 @@
             }
             mService = null;
             unbind();
+            dispatchOnBinderDied();
+        }
+
+        private void dispatchOnBinderDied() {
+            ServiceLifecycleCallbacks<I> serviceLifecycleCallbacks = mServiceLifecycleCallbacks;
+            if (serviceLifecycleCallbacks != null) {
+                serviceLifecycleCallbacks.onBinderDied();
+            }
         }
 
         @Override
@@ -764,5 +827,10 @@
 
         @Override
         public void unbind() {}
+
+        @Override
+        public void setServiceLifecycleCallbacks(@Nullable ServiceLifecycleCallbacks<T> callbacks) {
+            // Do nothing.
+        }
     }
 }
diff --git a/core/java/com/android/internal/inputmethod/EditableInputConnection.java b/core/java/com/android/internal/inputmethod/EditableInputConnection.java
index 630c271..f8b268f 100644
--- a/core/java/com/android/internal/inputmethod/EditableInputConnection.java
+++ b/core/java/com/android/internal/inputmethod/EditableInputConnection.java
@@ -205,6 +205,13 @@
     }
 
     @Override
+    public boolean requestCursorUpdates(
+            @CursorUpdateMode int cursorUpdateMode, @CursorUpdateFilter int cursorUpdateFilter) {
+        // TODO(b/210039666): use separate attrs for updateMode and updateFilter.
+        return requestCursorUpdates(cursorUpdateMode | cursorUpdateFilter);
+    }
+
+    @Override
     public boolean requestCursorUpdates(int cursorUpdateMode) {
         if (DEBUG) Log.v(TAG, "requestUpdateCursorAnchorInfo " + cursorUpdateMode);
 
diff --git a/core/java/com/android/internal/inputmethod/IInputContextInvoker.java b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java
index e6fafe0..e8838c8 100644
--- a/core/java/com/android/internal/inputmethod/IInputContextInvoker.java
+++ b/core/java/com/android/internal/inputmethod/IInputContextInvoker.java
@@ -603,6 +603,30 @@
     }
 
     /**
+     * Invokes {@link IInputContext#requestCursorUpdatesWithFilter(InputConnectionCommandHeader,
+     * int, int, int, AndroidFuture)}.
+     *
+     * @param cursorUpdateMode {@code cursorUpdateMode} parameter to be passed.
+     * @param cursorUpdateFilter {@code cursorUpdateFilter} parameter to be passed.
+     * @param imeDisplayId the display ID that is associated with the IME.
+     * @return {@link AndroidFuture<Boolean>} that can be used to retrieve the invocation
+     *         result. {@link RemoteException} will be treated as an error.
+     */
+    @AnyThread
+    @NonNull
+    public AndroidFuture<Boolean> requestCursorUpdates(int cursorUpdateMode, int cursorUpdateFilter,
+            int imeDisplayId) {
+        final AndroidFuture<Boolean> future = new AndroidFuture<>();
+        try {
+            mIInputContext.requestCursorUpdatesWithFilter(createHeader(), cursorUpdateMode,
+                    cursorUpdateFilter, imeDisplayId, future);
+        } catch (RemoteException e) {
+            future.completeExceptionally(e);
+        }
+        return future;
+    }
+
+    /**
      * Invokes {@link IInputContext#commitContent(InputConnectionCommandHeader, InputContentInfo,
      * int, Bundle, AndroidFuture)}.
      *
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index 30853bc..b18c98b 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -42,6 +42,6 @@
     void shouldOfferSwitchingToNextInputMethod(in AndroidFuture future /* T=Boolean */);
     void notifyUserActionAsync();
     void applyImeVisibilityAsync(IBinder showOrHideInputToken, boolean setVisible);
-    void onStylusHandwritingReady(int requestId);
+    void onStylusHandwritingReady(int requestId, int pid);
     void finishStylusHandwriting(int requestId);
 }
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/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index 2a7e1dc..e8a2d81 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -396,16 +396,16 @@
     }
 
     /**
-     * Calls {@link IInputMethodPrivilegedOperations#onStylusHandwritingReady()}
+     * Calls {@link IInputMethodPrivilegedOperations#onStylusHandwritingReady(int, int)}
      */
     @AnyThread
-    public void onStylusHandwritingReady(int requestId) {
+    public void onStylusHandwritingReady(int requestId, int pid) {
         final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
         if (ops == null) {
             return;
         }
         try {
-            ops.onStylusHandwritingReady(requestId);
+            ops.onStylusHandwritingReady(requestId, pid);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
index 780de0e..f81fd37 100644
--- a/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/com/android/internal/inputmethod/RemoteInputConnectionImpl.java
@@ -935,17 +935,20 @@
      * Dispatches {@link InputConnection#requestCursorUpdates(int)}.
      *
      * <p>This method is intended to be called only from {@link InputMethodManager}.</p>
-     * @param cursorUpdateMode the mode for {@link InputConnection#requestCursorUpdates(int)}
+     * @param cursorUpdateMode the mode for {@link InputConnection#requestCursorUpdates(int, int)}
+     * @param cursorUpdateFilter the filter for
+     *      {@link InputConnection#requestCursorUpdates(int, int)}
      * @param imeDisplayId displayId on which IME is displayed.
      */
     @Dispatching(cancellable = true)
-    public void requestCursorUpdatesFromImm(int cursorUpdateMode, int imeDisplayId) {
+    public void requestCursorUpdatesFromImm(int cursorUpdateMode, int cursorUpdateFilter,
+            int imeDisplayId) {
         final int currentSessionId = mCurrentSessionId.get();
         dispatchWithTracing("requestCursorUpdatesFromImm", () -> {
             if (currentSessionId != mCurrentSessionId.get()) {
                 return;  // cancelled
             }
-            requestCursorUpdatesInternal(cursorUpdateMode, imeDisplayId);
+            requestCursorUpdatesInternal(cursorUpdateMode, cursorUpdateFilter, imeDisplayId);
         });
     }
 
@@ -957,11 +960,28 @@
             if (header.mSessionId != mCurrentSessionId.get()) {
                 return false;  // cancelled
             }
-            return requestCursorUpdatesInternal(cursorUpdateMode, imeDisplayId);
+            return requestCursorUpdatesInternal(
+                    cursorUpdateMode, 0 /* cursorUpdateFilter */, imeDisplayId);
         });
     }
 
-    private boolean requestCursorUpdatesInternal(int cursorUpdateMode, int imeDisplayId) {
+    @Dispatching(cancellable = true)
+    @Override
+    public void requestCursorUpdatesWithFilter(InputConnectionCommandHeader header,
+            int cursorUpdateMode, int cursorUpdateFilter, int imeDisplayId,
+            AndroidFuture future /* T=Boolean */) {
+        dispatchWithTracing("requestCursorUpdates", future, () -> {
+            if (header.mSessionId != mCurrentSessionId.get()) {
+                return false;  // cancelled
+            }
+            return requestCursorUpdatesInternal(
+                    cursorUpdateMode, cursorUpdateFilter, imeDisplayId);
+        });
+    }
+
+    private boolean requestCursorUpdatesInternal(
+            @InputConnection.CursorUpdateMode int cursorUpdateMode,
+            @InputConnection.CursorUpdateFilter int cursorUpdateFilter, int imeDisplayId) {
         final InputConnection ic = getInputConnection();
         if (ic == null || !isActive()) {
             Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
@@ -972,7 +992,7 @@
             return false;
         }
         try {
-            return ic.requestCursorUpdates(cursorUpdateMode);
+            return ic.requestCursorUpdates(cursorUpdateMode, cursorUpdateFilter);
         } catch (AbstractMethodError ignored) {
             // TODO(b/199934664): See if we can remove this by providing a default impl.
             return false;
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/SystemServerClassLoaderFactory.java b/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java
index 615e4b79..a03bac4 100644
--- a/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java
+++ b/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java
@@ -29,22 +29,66 @@
     private static final ArrayMap<String, PathClassLoader> sLoadedPaths = new ArrayMap<>();
 
     /**
-     * Creates and caches a ClassLoader for the jar at the given path, or returns a cached
-     * ClassLoader if it exists.
+     * Creates and caches a ClassLoader for the jar at the given path.
+     *
+     * This method should only be called by ZygoteInit to prefetch jars. For other users, use
+     * {@link getOrCreateClassLoader} instead.
      *
      * The parent class loader should always be the system server class loader. Changing it has
      * implications that require discussion with the mainline team.
      *
      * @hide for internal use only
      */
-    public static PathClassLoader getOrCreateClassLoader(String path, ClassLoader parent) {
-        PathClassLoader pathClassLoader = sLoadedPaths.get(path);
-        if (pathClassLoader == null) {
-            pathClassLoader = (PathClassLoader) ClassLoaderFactory.createClassLoader(
-                    path, /*librarySearchPath=*/null, /*libraryPermittedPath=*/null, parent,
-                    Build.VERSION.SDK_INT, /*isNamespaceShared=*/true , /*classLoaderName=*/null);
-            sLoadedPaths.put(path, pathClassLoader);
+    /* package */ static PathClassLoader createClassLoader(String path, ClassLoader parent) {
+        if (sLoadedPaths.containsKey(path)) {
+            throw new IllegalStateException("A ClassLoader for " + path + " already exists");
         }
+        PathClassLoader pathClassLoader = (PathClassLoader) ClassLoaderFactory.createClassLoader(
+                path, /*librarySearchPath=*/null, /*libraryPermittedPath=*/null, parent,
+                Build.VERSION.SDK_INT, /*isNamespaceShared=*/true , /*classLoaderName=*/null);
+        sLoadedPaths.put(path, pathClassLoader);
         return pathClassLoader;
     }
+
+    /**
+     * Returns a cached ClassLoader to be used at runtime for the jar at the given path. Or, creates
+     * one if it is not prefetched and is allowed to be created at runtime.
+     *
+     * The parent class loader should always be the system server class loader. Changing it has
+     * implications that require discussion with the mainline team.
+     *
+     * @hide for internal use only
+     */
+    public static PathClassLoader getOrCreateClassLoader(
+            String path, ClassLoader parent, boolean isTestOnly) {
+        PathClassLoader pathClassLoader = sLoadedPaths.get(path);
+        if (pathClassLoader != null) {
+            return pathClassLoader;
+        }
+        if (!allowClassLoaderCreation(path, isTestOnly)) {
+            throw new RuntimeException("Creating a ClassLoader from " + path + " is not allowed. "
+                    + "Please make sure that the jar is listed in "
+                    + "`PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS` in the Makefile and added as a "
+                    + "`standalone_contents` of a `systemserverclasspath_fragment` in "
+                    + "`Android.bp`.");
+        }
+        return createClassLoader(path, parent);
+    }
+
+    /**
+     * Returns whether a class loader for the jar is allowed to be created at runtime.
+     */
+    private static boolean allowClassLoaderCreation(String path, boolean isTestOnly) {
+        // Currently, we only enforce prefetching for APEX jars.
+        if (!path.startsWith("/apex/")) {
+            return true;
+        }
+        // APEXes for testing only are okay to ignore.
+        if (isTestOnly) {
+            return true;
+        }
+        return false;
+    }
+
+
 }
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 6d4b8c5..b1e7d15 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -20,13 +20,21 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
+import android.compat.annotation.EnabledAfter;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ProcessInfo;
 import android.net.Credentials;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
+import android.os.Build;
 import android.os.FactoryTest;
 import android.os.IVold;
 import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.provider.DeviceConfig;
@@ -34,6 +42,7 @@
 import android.system.Os;
 import android.util.Log;
 
+import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.net.NetworkUtilsInternal;
 
 import dalvik.annotation.optimization.CriticalNative;
@@ -125,6 +134,7 @@
     public static final int MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20);
 
     public static final int MEMORY_TAG_LEVEL_NONE = 0;
+
     /**
      * Enable pointer tagging in this process.
      * Tags are checked during memory deallocation, but not on access.
@@ -170,10 +180,8 @@
      */
     public static final int GWP_ASAN_LEVEL_ALWAYS = 1 << 22;
 
-    /**
-     * Enable automatic zero-initialization of native heap memory allocations.
-     */
-    public static final int NATIVE_HEAP_ZERO_INIT = 1 << 23;
+    /** Enable automatic zero-initialization of native heap memory allocations. */
+    public static final int NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23;
 
     /**
      * Enable profiling from system services. This loads profiling related plugins in ART.
@@ -1170,4 +1178,251 @@
      * we failed to determine the level.
      */
     public static native int nativeCurrentTaggingLevel();
+
+    /**
+     * Native heap allocations will now have a non-zero tag in the most significant byte.
+     *
+     * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged
+     *     Pointers</a>
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
+    private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id.
+
+    /**
+     * Native heap allocations in AppZygote process and its descendants will now have a non-zero tag
+     * in the most significant byte.
+     *
+     * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged
+     *     Pointers</a>
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S)
+    private static final long NATIVE_HEAP_POINTER_TAGGING_SECONDARY_ZYGOTE = 207557677;
+
+    /**
+     * Enable asynchronous (ASYNC) memory tag checking in this process. This flag will only have an
+     * effect on hardware supporting the ARM Memory Tagging Extension (MTE).
+     */
+    @ChangeId @Disabled
+    private static final long NATIVE_MEMTAG_ASYNC = 135772972; // This is a bug id.
+
+    /**
+     * Enable synchronous (SYNC) memory tag checking in this process. This flag will only have an
+     * effect on hardware supporting the ARM Memory Tagging Extension (MTE). If both
+     * NATIVE_MEMTAG_ASYNC and this option is selected, this option takes preference and MTE is
+     * enabled in SYNC mode.
+     */
+    @ChangeId @Disabled
+    private static final long NATIVE_MEMTAG_SYNC = 177438394; // This is a bug id.
+
+    /** Enable automatic zero-initialization of native heap memory allocations. */
+    @ChangeId @Disabled
+    private static final long NATIVE_HEAP_ZERO_INIT = 178038272; // This is a bug id.
+
+    /**
+     * Enable sampled memory bug detection in the app.
+     *
+     * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>.
+     */
+    @ChangeId @Disabled private static final long GWP_ASAN = 135634846; // This is a bug id.
+
+    private static int memtagModeToZygoteMemtagLevel(int memtagMode) {
+        switch (memtagMode) {
+            case ApplicationInfo.MEMTAG_ASYNC:
+                return MEMORY_TAG_LEVEL_ASYNC;
+            case ApplicationInfo.MEMTAG_SYNC:
+                return MEMORY_TAG_LEVEL_SYNC;
+            default:
+                return MEMORY_TAG_LEVEL_NONE;
+        }
+    }
+
+    private static boolean isCompatChangeEnabled(
+            long change,
+            @NonNull ApplicationInfo info,
+            @Nullable IPlatformCompat platformCompat,
+            int enabledAfter) {
+        try {
+            if (platformCompat != null) return platformCompat.isChangeEnabled(change, info);
+        } catch (RemoteException ignore) {
+        }
+        return enabledAfter > 0 && info.targetSdkVersion > enabledAfter;
+    }
+
+    // Returns the requested memory tagging level.
+    private static int getRequestedMemtagLevel(
+            @NonNull ApplicationInfo info,
+            @Nullable ProcessInfo processInfo,
+            @Nullable IPlatformCompat platformCompat) {
+        // Look at the process attribute first.
+        if (processInfo != null && processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) {
+            return memtagModeToZygoteMemtagLevel(processInfo.memtagMode);
+        }
+
+        // Then at the application attribute.
+        if (info.getMemtagMode() != ApplicationInfo.MEMTAG_DEFAULT) {
+            return memtagModeToZygoteMemtagLevel(info.getMemtagMode());
+        }
+
+        if (isCompatChangeEnabled(NATIVE_MEMTAG_SYNC, info, platformCompat, 0)) {
+            return MEMORY_TAG_LEVEL_SYNC;
+        }
+
+        if (isCompatChangeEnabled(NATIVE_MEMTAG_ASYNC, info, platformCompat, 0)) {
+            return MEMORY_TAG_LEVEL_ASYNC;
+        }
+
+        // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute.
+        if (!info.allowsNativeHeapPointerTagging()) {
+            return MEMORY_TAG_LEVEL_NONE;
+        }
+
+        String defaultLevel = SystemProperties.get("persist.arm64.memtag.app_default");
+        if ("sync".equals(defaultLevel)) {
+            return MEMORY_TAG_LEVEL_SYNC;
+        } else if ("async".equals(defaultLevel)) {
+            return MEMORY_TAG_LEVEL_ASYNC;
+        }
+
+        // Check to see that the compat feature for TBI is enabled.
+        if (isCompatChangeEnabled(
+                NATIVE_HEAP_POINTER_TAGGING, info, platformCompat, Build.VERSION_CODES.Q)) {
+            return MEMORY_TAG_LEVEL_TBI;
+        }
+
+        return MEMORY_TAG_LEVEL_NONE;
+    }
+
+    private static int decideTaggingLevel(
+            @NonNull ApplicationInfo info,
+            @Nullable ProcessInfo processInfo,
+            @Nullable IPlatformCompat platformCompat) {
+        // Get the desired tagging level (app manifest + compat features).
+        int level = getRequestedMemtagLevel(info, processInfo, platformCompat);
+
+        // Take into account the hardware capabilities.
+        if (nativeSupportsMemoryTagging()) {
+            // MTE devices can not do TBI, because the Zygote process already has live MTE
+            // allocations. Downgrade TBI to NONE.
+            if (level == MEMORY_TAG_LEVEL_TBI) {
+                level = MEMORY_TAG_LEVEL_NONE;
+            }
+        } else if (nativeSupportsTaggedPointers()) {
+            // TBI-but-not-MTE devices downgrade MTE modes to TBI.
+            // The idea is that if an app opts into full hardware tagging (MTE), it must be ok with
+            // the "fake" pointer tagging (TBI).
+            if (level == MEMORY_TAG_LEVEL_ASYNC || level == MEMORY_TAG_LEVEL_SYNC) {
+                level = MEMORY_TAG_LEVEL_TBI;
+            }
+        } else {
+            // Otherwise disable all tagging.
+            level = MEMORY_TAG_LEVEL_NONE;
+        }
+
+        return level;
+    }
+
+    private static int decideGwpAsanLevel(
+            @NonNull ApplicationInfo info,
+            @Nullable ProcessInfo processInfo,
+            @Nullable IPlatformCompat platformCompat) {
+        // Look at the process attribute first.
+        if (processInfo != null && processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) {
+            return processInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_ALWAYS
+                    ? GWP_ASAN_LEVEL_ALWAYS
+                    : GWP_ASAN_LEVEL_NEVER;
+        }
+        // Then at the application attribute.
+        if (info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) {
+            return info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS
+                    ? GWP_ASAN_LEVEL_ALWAYS
+                    : GWP_ASAN_LEVEL_NEVER;
+        }
+        // If the app does not specify gwpAsanMode, the default behavior is lottery among the
+        // system apps, and disabled for user apps, unless overwritten by the compat feature.
+        if (isCompatChangeEnabled(GWP_ASAN, info, platformCompat, 0)) {
+            return GWP_ASAN_LEVEL_ALWAYS;
+        }
+        if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+            return GWP_ASAN_LEVEL_LOTTERY;
+        }
+        return GWP_ASAN_LEVEL_NEVER;
+    }
+
+    private static boolean enableNativeHeapZeroInit(
+            @NonNull ApplicationInfo info,
+            @Nullable ProcessInfo processInfo,
+            @Nullable IPlatformCompat platformCompat) {
+        // Look at the process attribute first.
+        if (processInfo != null
+                && processInfo.nativeHeapZeroInitialized != ApplicationInfo.ZEROINIT_DEFAULT) {
+            return processInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_ENABLED;
+        }
+        // Then at the application attribute.
+        if (info.getNativeHeapZeroInitialized() != ApplicationInfo.ZEROINIT_DEFAULT) {
+            return info.getNativeHeapZeroInitialized() == ApplicationInfo.ZEROINIT_ENABLED;
+        }
+        // Compat feature last.
+        if (isCompatChangeEnabled(NATIVE_HEAP_ZERO_INIT, info, platformCompat, 0)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns Zygote runtimeFlags for memory safety features (MTE, GWP-ASan, nativeHeadZeroInit)
+     * for a given app.
+     */
+    public static int getMemorySafetyRuntimeFlags(
+            @NonNull ApplicationInfo info,
+            @Nullable ProcessInfo processInfo,
+            @Nullable String instructionSet,
+            @Nullable IPlatformCompat platformCompat) {
+        int runtimeFlags = decideGwpAsanLevel(info, processInfo, platformCompat);
+        // If instructionSet is non-null, this indicates that the system_server is spawning a
+        // process with an ISA that may be different from its own. System (kernel and hardware)
+        // compatibility for these features is checked in the decideTaggingLevel in the
+        // system_server process (not the child process). As both MTE and TBI are only supported
+        // in aarch64, we can simply ensure that the new process is also aarch64. This prevents
+        // the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should
+        // enable some tagging variant. Theoretically, a 32-bit system server could exist that
+        // spawns 64-bit processes, in which case the new process won't get any tagging. This is
+        // fine as we haven't seen this configuration in practice, and we can reasonable assume
+        // that if tagging is desired, the system server will be 64-bit.
+        if (instructionSet == null || instructionSet.equals("arm64")) {
+            runtimeFlags |= decideTaggingLevel(info, processInfo, platformCompat);
+        }
+        if (enableNativeHeapZeroInit(info, processInfo, platformCompat)) {
+            runtimeFlags |= NATIVE_HEAP_ZERO_INIT_ENABLED;
+        }
+        return runtimeFlags;
+    }
+
+    /**
+     * Returns Zygote runtimeFlags for memory safety features (MTE, GWP-ASan, nativeHeadZeroInit)
+     * for a secondary zygote (AppZygote or WebViewZygote).
+     */
+    public static int getMemorySafetyRuntimeFlagsForSecondaryZygote(
+            @NonNull ApplicationInfo info, @Nullable ProcessInfo processInfo) {
+        final IPlatformCompat platformCompat =
+                IPlatformCompat.Stub.asInterface(
+                        ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+        int runtimeFlags =
+                getMemorySafetyRuntimeFlags(
+                        info, processInfo, null /*instructionSet*/, platformCompat);
+
+        // TBI ("fake" pointer tagging) in AppZygote is controlled by a separate compat feature.
+        if ((runtimeFlags & MEMORY_TAG_LEVEL_MASK) == MEMORY_TAG_LEVEL_TBI
+                && isCompatChangeEnabled(
+                        NATIVE_HEAP_POINTER_TAGGING_SECONDARY_ZYGOTE,
+                        info,
+                        platformCompat,
+                        Build.VERSION_CODES.S)) {
+            // Reset memory tag level to NONE.
+            runtimeFlags &= ~MEMORY_TAG_LEVEL_MASK;
+            runtimeFlags |= MEMORY_TAG_LEVEL_NONE;
+        }
+        return runtimeFlags;
+    }
 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 3d24aa2d..ca1ae19 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -586,7 +586,7 @@
         }
         for (String jar : envStr.split(":")) {
             try {
-                SystemServerClassLoaderFactory.getOrCreateClassLoader(
+                SystemServerClassLoaderFactory.createClassLoader(
                         jar, getOrCreateSystemServerClassLoader());
             } catch (Error e) {
                 // We don't want the process to crash for this error because prefetching is just an
diff --git a/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java b/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java
index 3e72564..75dce5a 100644
--- a/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java
+++ b/core/java/com/android/internal/policy/ForceShowNavigationBarSettingsObserver.java
@@ -26,7 +26,7 @@
 /**
  * A ContentObserver for listening force show navigation bar relative setting keys:
  *  - {@link Settings.Secure#NAVIGATION_MODE}
- *  - {@link Settings.Secure#NAV_BAR_KIDS_MODE}
+ *  - {@link Settings.Secure#NAV_BAR_FORCE_VISIBLE}
  *
  * @hide
  */
@@ -52,7 +52,7 @@
                 Settings.Secure.getUriFor(Settings.Secure.NAVIGATION_MODE),
                 false, this, UserHandle.USER_ALL);
         r.registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE),
+                Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_FORCE_VISIBLE),
                 false, this, UserHandle.USER_ALL);
     }
 
@@ -78,6 +78,6 @@
         return Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.NAVIGATION_MODE, 0, UserHandle.USER_CURRENT) == 0
                 && Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.NAV_BAR_KIDS_MODE, 0, UserHandle.USER_CURRENT) == 1;
+                Settings.Secure.NAV_BAR_FORCE_VISIBLE, 0, UserHandle.USER_CURRENT) == 1;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/core/java/com/android/internal/policy/IKeyguardLockedStateListener.aidl
similarity index 68%
copy from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
copy to core/java/com/android/internal/policy/IKeyguardLockedStateListener.aidl
index 2894780..ee50219 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/core/java/com/android/internal/policy/IKeyguardLockedStateListener.aidl
@@ -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,8 @@
  * limitations under the License.
  */
 
-package com.android.systemui.dagger;
+package com.android.internal.policy;
 
-import dagger.Module;
-
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
-}
+oneway interface IKeyguardLockedStateListener {
+    void onKeyguardLockedStateChanged(boolean isKeyguardLocked);
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 12f38a4..b4ba16f 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -91,8 +91,6 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
-import android.view.OnBackInvokedDispatcher;
-import android.view.OnBackInvokedDispatcherOwner;
 import android.view.ScrollCaptureCallback;
 import android.view.SearchEvent;
 import android.view.SurfaceHolder.Callback2;
@@ -112,6 +110,8 @@
 import android.widget.ImageView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
+import android.window.OnBackInvokedDispatcher;
+import android.window.OnBackInvokedDispatcherOwner;
 import android.window.ProxyOnBackInvokedDispatcher;
 
 import com.android.internal.R;
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/protolog/ProtoLogGroup.java b/core/java/com/android/internal/protolog/ProtoLogGroup.java
index def598c..45c6d5f 100644
--- a/core/java/com/android/internal/protolog/ProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/ProtoLogGroup.java
@@ -82,7 +82,7 @@
             Consts.TAG_WM),
     WM_DEBUG_WINDOW_INSETS(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
             Consts.TAG_WM),
-    WM_DEBUG_LAYER_MIRRORING(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
+    WM_DEBUG_CONTENT_RECORDING(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
             Consts.TAG_WM),
     WM_DEBUG_WALLPAPER(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false, Consts.TAG_WM),
     WM_DEBUG_BACK_PREVIEW(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, true,
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 099d1fc..d629d66 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -159,7 +159,7 @@
     /**
     * Used to notify the authentication dialog that a biometric has been authenticated.
     */
-    void onBiometricAuthenticated();
+    void onBiometricAuthenticated(int modality);
     /**
     * Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc.
     */
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 9e70392..1d60c50 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,
@@ -125,7 +125,7 @@
             int multiSensorConfig);
 
     // Used to notify the authentication dialog that a biometric has been authenticated
-    void onBiometricAuthenticated();
+    void onBiometricAuthenticated(int modality);
     // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
     void onBiometricHelp(int modality, String message);
     // Used to show an error - the dialog will dismiss after a certain amount of time
@@ -175,20 +175,20 @@
     void cancelRequestAddTile(in String packageName);
 
     /**
-    * Overrides the navigation bar mode.
+    * Sets the navigation bar mode.
     *
-    * @param navBarModeOverride the mode of the navigation bar override to be set.
+    * @param navBarMode the mode of the navigation bar to be set.
     *
     * @hide
     */
-    void setNavBarModeOverride(int navBarModeOverride);
+    void setNavBarMode(int navBarMode);
 
     /**
-    * Gets the navigation bar mode override.
+    * Gets the navigation bar mode.
     *
     * @hide
     */
-    int getNavBarModeOverride();
+    int getNavBarMode();
 
     /**
     * Register a listener for certain sessions. Each session may be guarded by its own permission.
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/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index 7da0f11..909a537 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -98,6 +98,10 @@
     void requestCursorUpdates(in InputConnectionCommandHeader header, int cursorUpdateMode,
             int imeDisplayId, in AndroidFuture future /* T=Boolean */);
 
+    void requestCursorUpdatesWithFilter(in InputConnectionCommandHeader header,
+                int cursorUpdateMode, int cursorUpdateFilter, int imeDisplayId,
+                 in AndroidFuture future /* T=Boolean */);
+
     void commitContent(in InputConnectionCommandHeader header, in InputContentInfo inputContentInfo,
             int flags, in Bundle opts, in AndroidFuture future /* T=Boolean */);
 
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/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 0df3e87..c5346b9 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -67,7 +67,7 @@
     void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
     // This is kept due to @UnsupportedAppUsage.
     // TODO(Bug 113914148): Consider removing this.
-    int getInputMethodWindowVisibleHeight();
+    int getInputMethodWindowVisibleHeight(in IInputMethodClient client);
 
     oneway void reportPerceptibleAsync(in IBinder windowToken, boolean perceptible);
     /** Remove the IME surface. Requires INTERNAL_SYSTEM_WINDOW permission. */
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 93864fa..b1846d2 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -671,6 +671,7 @@
             readPermissions(parser, Environment.buildPath(f, "etc", "permissions"),
                     apexPermissionFlag);
         }
+        pruneVendorApexPrivappAllowlists();
     }
 
     @VisibleForTesting
@@ -1197,7 +1198,8 @@
                                 readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
                                         mSystemExtPrivAppDenyPermissions);
                             } else if (apex) {
-                                readApexPrivAppPermissions(parser, permFile);
+                                readApexPrivAppPermissions(parser, permFile,
+                                        Environment.getApexDirectory().toPath());
                             } else {
                                 readPrivAppPermissions(parser, mPrivAppPermissions,
                                         mPrivAppDenyPermissions);
@@ -1547,6 +1549,21 @@
         }
     }
 
+    /**
+     * Prunes out any privileged permission allowlists bundled in vendor apexes.
+     */
+    @VisibleForTesting
+    public void pruneVendorApexPrivappAllowlists() {
+        for (String moduleName: mAllowedVendorApexes.keySet()) {
+            if (mApexPrivAppPermissions.containsKey(moduleName)
+                    || mApexPrivAppDenyPermissions.containsKey(moduleName)) {
+                Slog.w(TAG, moduleName + " is a vendor apex, ignore its priv-app allowlist");
+                mApexPrivAppPermissions.remove(moduleName);
+                mApexPrivAppDenyPermissions.remove(moduleName);
+            }
+        }
+    }
+
     private void readInstallInUserType(XmlPullParser parser,
             Map<String, Set<String>> doInstallMap,
             Map<String, Set<String>> nonInstallMap)
@@ -1757,8 +1774,7 @@
     /**
      * Returns the module name for a file in the apex module's partition.
      */
-    private String getApexModuleNameFromFilePath(Path path) {
-        final Path apexDirectoryPath = Environment.getApexDirectory().toPath();
+    private String getApexModuleNameFromFilePath(Path path, Path apexDirectoryPath) {
         if (!path.startsWith(apexDirectoryPath)) {
             throw new IllegalArgumentException("File " + path + " is not part of an APEX.");
         }
@@ -1770,9 +1786,14 @@
         return path.getName(apexDirectoryPath.getNameCount()).toString();
     }
 
-    private void readApexPrivAppPermissions(XmlPullParser parser, File permFile)
-            throws IOException, XmlPullParserException {
-        final String moduleName = getApexModuleNameFromFilePath(permFile.toPath());
+    /**
+     * Reads the contents of the privileged permission allowlist stored inside an APEX.
+     */
+    @VisibleForTesting
+    public void readApexPrivAppPermissions(XmlPullParser parser, File permFile,
+            Path apexDirectoryPath) throws IOException, XmlPullParserException {
+        final String moduleName =
+                getApexModuleNameFromFilePath(permFile.toPath(), apexDirectoryPath);
         final ArrayMap<String, ArraySet<String>> privAppPermissions;
         if (mApexPrivAppPermissions.containsKey(moduleName)) {
             privAppPermissions = mApexPrivAppPermissions.get(moduleName);
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index 4f13a9c..c0f7b41 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -35,9 +35,22 @@
     jmethodID ctor;
 } gTransactionClassInfo;
 
-static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName) {
+struct {
+    jmethodID accept;
+} gTransactionConsumer;
+
+static JNIEnv* getenv(JavaVM* vm) {
+    JNIEnv* env;
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", vm);
+    }
+    return env;
+}
+
+static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName,
+                          jboolean updateDestinationFrame) {
     ScopedUtfChars name(env, jName);
-    sp<BLASTBufferQueue> queue = new BLASTBufferQueue(name.c_str());
+    sp<BLASTBufferQueue> queue = new BLASTBufferQueue(name.c_str(), updateDestinationFrame);
     queue->incStrong((void*)nativeCreate);
     return reinterpret_cast<jlong>(queue.get());
 }
@@ -54,19 +67,57 @@
                                                   queue->getSurface(includeSurfaceControlHandle));
 }
 
-static void nativeSetSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr, jlong transactionPtr,
-                                     jboolean acquireSingleBuffer) {
+class JGlobalRefHolder {
+public:
+    JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
+
+    virtual ~JGlobalRefHolder() {
+        getenv(mVm)->DeleteGlobalRef(mObject);
+        mObject = nullptr;
+    }
+
+    jobject object() { return mObject; }
+    JavaVM* vm() { return mVm; }
+
+private:
+    JGlobalRefHolder(const JGlobalRefHolder&) = delete;
+    void operator=(const JGlobalRefHolder&) = delete;
+
+    JavaVM* mVm;
+    jobject mObject;
+};
+
+static void nativeSyncNextTransaction(JNIEnv* env, jclass clazz, jlong ptr, jobject callback,
+                                      jboolean acquireSingleBuffer) {
     sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
-    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionPtr);
-    queue->setSyncTransaction(transaction, acquireSingleBuffer);
+    JavaVM* vm = nullptr;
+    LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
+    if (!callback) {
+        queue->syncNextTransaction(nullptr, acquireSingleBuffer);
+    } else {
+        auto globalCallbackRef =
+                std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback));
+        queue->syncNextTransaction(
+                [globalCallbackRef](SurfaceComposerClient::Transaction* t) {
+                    JNIEnv* env = getenv(globalCallbackRef->vm());
+                    env->CallVoidMethod(globalCallbackRef->object(), gTransactionConsumer.accept,
+                                        env->NewObject(gTransactionClassInfo.clazz,
+                                                       gTransactionClassInfo.ctor,
+                                                       reinterpret_cast<jlong>(t)));
+                },
+                acquireSingleBuffer);
+    }
+}
+
+static void nativeStopContinuousSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr) {
+    sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
+    queue->stopContinuousSyncTransaction();
 }
 
 static void nativeUpdate(JNIEnv* env, jclass clazz, jlong ptr, jlong surfaceControl, jlong width,
-                         jlong height, jint format, jlong transactionPtr) {
+                         jlong height, jint format) {
     sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
-    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionPtr);
-    queue->update(reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, format,
-                  transaction);
+    queue->update(reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, format);
 }
 
 static void nativeMergeWithNextTransaction(JNIEnv*, jclass clazz, jlong ptr, jlong transactionPtr,
@@ -102,11 +153,12 @@
 static const JNINativeMethod gMethods[] = {
         /* name, signature, funcPtr */
         // clang-format off
-        {"nativeCreate", "(Ljava/lang/String;)J", (void*)nativeCreate},
+        {"nativeCreate", "(Ljava/lang/String;Z)J", (void*)nativeCreate},
         {"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface},
         {"nativeDestroy", "(J)V", (void*)nativeDestroy},
-        {"nativeSetSyncTransaction", "(JJZ)V", (void*)nativeSetSyncTransaction},
-        {"nativeUpdate", "(JJJJIJ)V", (void*)nativeUpdate},
+        {"nativeSyncNextTransaction", "(JLjava/util/function/Consumer;Z)V", (void*)nativeSyncNextTransaction},
+        {"nativeStopContinuousSyncTransaction", "(J)V", (void*)nativeStopContinuousSyncTransaction},
+        {"nativeUpdate", "(JJJJI)V", (void*)nativeUpdate},
         {"nativeMergeWithNextTransaction", "(JJJ)V", (void*)nativeMergeWithNextTransaction},
         {"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
         {"nativeApplyPendingTransactions", "(JJ)V", (void*)nativeApplyPendingTransactions},
@@ -124,6 +176,10 @@
     gTransactionClassInfo.clazz = MakeGlobalRefOrDie(env, transactionClazz);
     gTransactionClassInfo.ctor =
             GetMethodIDOrDie(env, gTransactionClassInfo.clazz, "<init>", "(J)V");
+
+    jclass consumer = FindClassOrDie(env, "java/util/function/Consumer");
+    gTransactionConsumer.accept =
+            GetMethodIDOrDie(env, consumer, "accept", "(Ljava/lang/Object;)V");
     return 0;
 }
 
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index 93ce377..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);
 
@@ -325,8 +263,8 @@
                         "Failed to create new InputWindowHandle object.");
     env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.token,
                         javaObjectForIBinder(env, windowInfo.token));
-    env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.name,
-                        env->NewStringUTF(windowInfo.name.data()));
+    ScopedLocalRef<jstring> name(env, env->NewStringUTF(windowInfo.name.data()));
+    env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.name, name.get());
     env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.layoutParamsFlags,
                      static_cast<uint32_t>(windowInfo.layoutParamsFlags.get()));
     env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.layoutParamsType,
@@ -359,25 +297,18 @@
     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);
     env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerUid, windowInfo.ownerUid);
+    ScopedLocalRef<jstring> packageName(env, env->NewStringUTF(windowInfo.packageName.data()));
     env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.packageName,
-                        env->NewStringUTF(windowInfo.packageName.data()));
-    env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputFeatures,
-                     static_cast<int32_t>(windowInfo.inputFeatures.get()));
+                        packageName.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++) {
@@ -480,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,
@@ -504,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/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index dc55c05..e781760 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -829,13 +829,6 @@
 }
 
 static jint
-android_media_AudioSystem_getDevicesForStream(JNIEnv *env, jobject thiz, jint stream)
-{
-    return (jint)deviceTypesToBitMask(
-            AudioSystem::getDevicesForStream(static_cast<audio_stream_type_t>(stream)));
-}
-
-static jint
 android_media_AudioSystem_getPrimaryOutputSamplingRate(JNIEnv *env, jobject clazz)
 {
     return (jint) AudioSystem::getPrimaryOutputSamplingRate();
@@ -2712,10 +2705,10 @@
     return AUDIO_JAVA_SUCCESS;
 }
 
-static jint
-android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz,
-        jobject jaa, jobjectArray jDeviceArray)
-{
+static jint android_media_AudioSystem_getDevicesForAttributes(JNIEnv *env, jobject thiz,
+                                                              jobject jaa,
+                                                              jobjectArray jDeviceArray,
+                                                              jboolean forVolume) {
     const jsize maxResultSize = env->GetArrayLength(jDeviceArray);
     // the JNI is always expected to provide us with an array capable of holding enough
     // devices i.e. the most we ever route a track to. This is preferred over receiving an ArrayList
@@ -2734,7 +2727,7 @@
 
     AudioDeviceTypeAddrVector devices;
     jStatus = check_AudioSystem_Command(
-            AudioSystem::getDevicesForAttributes(*(paa.get()), &devices));
+            AudioSystem::getDevicesForAttributes(*(paa.get()), &devices, forVolume));
     if (jStatus != NO_ERROR) {
         return jStatus;
     }
@@ -2959,7 +2952,6 @@
          {"getMasterMono", "()Z", (void *)android_media_AudioSystem_getMasterMono},
          {"setMasterBalance", "(F)I", (void *)android_media_AudioSystem_setMasterBalance},
          {"getMasterBalance", "()F", (void *)android_media_AudioSystem_getMasterBalance},
-         {"getDevicesForStream", "(I)I", (void *)android_media_AudioSystem_getDevicesForStream},
          {"getPrimaryOutputSamplingRate", "()I",
           (void *)android_media_AudioSystem_getPrimaryOutputSamplingRate},
          {"getPrimaryOutputFrameCount", "()I",
@@ -3045,7 +3037,7 @@
          {"getDevicesForRoleAndCapturePreset", "(IILjava/util/List;)I",
           (void *)android_media_AudioSystem_getDevicesForRoleAndCapturePreset},
          {"getDevicesForAttributes",
-          "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;)I",
+          "(Landroid/media/AudioAttributes;[Landroid/media/AudioDeviceAttributes;Z)I",
           (void *)android_media_AudioSystem_getDevicesForAttributes},
          {"setUserIdDeviceAffinities", "(I[I[Ljava/lang/String;)I",
           (void *)android_media_AudioSystem_setUserIdDeviceAffinities},
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 7c67cbc..a6fbf094 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -235,9 +235,7 @@
 void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jint grp)
 {
     ALOGV("%s pid=%d grp=%" PRId32, __func__, pid, grp);
-    DIR *d;
     char proc_path[255];
-    struct dirent *de;
 
     if (!verifyGroup(env, grp)) {
         return;
@@ -277,84 +275,8 @@
         }
     }
 
-    sprintf(proc_path, "/proc/%d/task", pid);
-    if (!(d = opendir(proc_path))) {
-        // If the process exited on us, don't generate an exception
-        if (errno != ENOENT)
-            signalExceptionForGroupError(env, errno, pid);
-        return;
-    }
-
-    while ((de = readdir(d))) {
-        int t_pid;
-        int t_pri;
-        std::string taskprofile;
-
-        if (de->d_name[0] == '.')
-            continue;
-        t_pid = atoi(de->d_name);
-
-        if (!t_pid) {
-            ALOGE("Error getting pid for '%s'\n", de->d_name);
-            continue;
-        }
-
-        t_pri = getpriority(PRIO_PROCESS, t_pid);
-
-        if (t_pri <= ANDROID_PRIORITY_AUDIO) {
-            int scheduler = sched_getscheduler(t_pid) & ~SCHED_RESET_ON_FORK;
-            if ((scheduler == SCHED_FIFO) || (scheduler == SCHED_RR)) {
-                // This task wants to stay in its current audio group so it can keep its budget
-                // don't update its cpuset or cgroup
-                continue;
-            }
-        }
-
-        errno = 0;
-        // grp == SP_BACKGROUND. Set background cpuset policy profile for all threads.
-        if (grp == SP_BACKGROUND) {
-            if (!SetTaskProfiles(t_pid, {"CPUSET_SP_BACKGROUND"}, true)) {
-                signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);
-                break;
-            }
-            continue;
-        }
-
-        // grp != SP_BACKGROUND. Only change the cpuset cgroup for low priority thread, so it could
-        // preserve it sched policy profile setting.
-        if (t_pri >= ANDROID_PRIORITY_BACKGROUND) {
-            switch (grp) {
-                case SP_SYSTEM:
-                    taskprofile = "ServiceCapacityLow";
-                    break;
-                case SP_RESTRICTED:
-                    taskprofile = "ServiceCapacityRestricted";
-                    break;
-                case SP_FOREGROUND:
-                case SP_AUDIO_APP:
-                case SP_AUDIO_SYS:
-                    taskprofile = "ProcessCapacityHigh";
-                    break;
-                case SP_TOP_APP:
-                    taskprofile = "ProcessCapacityMax";
-                    break;
-                default:
-                    taskprofile = "ProcessCapacityNormal";
-                    break;
-            }
-            if (!SetTaskProfiles(t_pid, {taskprofile}, true)) {
-                signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);
-                break;
-            }
-        // Change the cpuset policy profile for non-low priority thread according to the grp
-        } else {
-            if (!SetTaskProfiles(t_pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)}, true)) {
-                signalExceptionForGroupError(env, errno ? errno : EPERM, t_pid);
-                break;
-            }
-        }
-    }
-    closedir(d);
+    if (!SetProcessProfilesCached(0, pid, {get_cpuset_policy_profile_name((SchedPolicy)grp)}))
+        signalExceptionForGroupError(env, errno ? errno : EPERM, pid);
 }
 
 void android_os_Process_setProcessFrozen(
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index fb5b5ff..68025a8 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -62,6 +62,7 @@
 
 namespace android {
 
+using gui::CaptureArgs;
 using gui::FocusRequest;
 
 static void doThrowNPE(JNIEnv* env) {
@@ -961,6 +962,14 @@
     transaction->sanitize();
 }
 
+static void nativeSetDestinationFrame(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                      jlong nativeObject, jint l, jint t, jint r, jint b) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
+    Rect crop(l, t, r, b);
+    transaction->setDestinationFrame(ctrl, crop);
+}
+
 static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) {
     const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
     jlongArray array = env->NewLongArray(displayIds.size());
@@ -1833,6 +1842,15 @@
     return reinterpret_cast<jlong>(surfaceControl->getHandle().get());
 }
 
+static void nativeRemoveCurrentInputFocus(JNIEnv* env, jclass clazz, jlong transactionObj,
+                                          jint displayId) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    FocusRequest request;
+    request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+    request.displayId = displayId;
+    transaction->setFocusedWindow(request);
+}
+
 static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionObj,
                                    jobject toTokenObj, jstring windowNameJstr,
                                    jobject focusedTokenObj, jstring focusedWindowNameJstr,
@@ -2167,6 +2185,8 @@
             (void*)nativeSetFixedTransformHint},
     {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I)V",
             (void*)nativeSetFocusedWindow},
+    {"nativeRemoveCurrentInputFocus", "(JI)V",
+            (void*)nativeRemoveCurrentInputFocus},
     {"nativeSetFrameTimelineVsync", "(JJ)V",
             (void*)nativeSetFrameTimelineVsync },
     {"nativeAddJankDataListener", "(JJ)V",
@@ -2190,7 +2210,9 @@
     {"nativeAddTransactionCommittedListener", "(JLandroid/view/SurfaceControl$TransactionCommittedListener;)V",
             (void*) nativeAddTransactionCommittedListener },
     {"nativeSanitize", "(J)V",
-            (void*) nativeSanitize }
+            (void*) nativeSanitize },
+    {"nativeSetDestinationFrame", "(JJIIII)V",
+                (void*)nativeSetDestinationFrame },
         // clang-format on
 };
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5971670..5b7092c 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -346,7 +346,7 @@
     GWP_ASAN_LEVEL_NEVER = 0 << 21,
     GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
     GWP_ASAN_LEVEL_ALWAYS = 2 << 21,
-    NATIVE_HEAP_ZERO_INIT = 1 << 23,
+    NATIVE_HEAP_ZERO_INIT_ENABLED = 1 << 23,
     PROFILEABLE = 1 << 24,
 };
 
@@ -1709,13 +1709,13 @@
     // would be nice to have them for apps, we will have to wait until they are
     // proven out, have more efficient hardware, and/or apply them only to new
     // applications.
-    if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT)) {
+    if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED)) {
         mallopt(M_BIONIC_ZERO_INIT, 0);
     }
 
     // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART
     // runtime.
-    runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT;
+    runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT_ENABLED;
 
     bool forceEnableGwpAsan = false;
     switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
index 248db76..0c05da5 100644
--- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -45,7 +45,7 @@
 // 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 MAX_COMMAND_BYTES = 32768;
 constexpr size_t NICE_NAME_BYTES = 50;
 
 // A buffer optionally bundled with a file descriptor from which we can fill it.
@@ -273,8 +273,6 @@
   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,
diff --git a/core/proto/android/hardware/sensorprivacy.proto b/core/proto/android/hardware/sensorprivacy.proto
index 97870a1..9359528 100644
--- a/core/proto/android/hardware/sensorprivacy.proto
+++ b/core/proto/android/hardware/sensorprivacy.proto
@@ -128,7 +128,7 @@
         DIALOG = 3;
         SHELL = 4;
         OTHER = 5;
-        SAFETY_HUB = 6;
+        SAFETY_CENTER = 6;
     }
 
     // Source for which sensor privacy was toggled.
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/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 4c0ba8c..6a421f0 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -385,7 +385,18 @@
 
     optional SettingProto multi_press_timeout = 38 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
-    optional SettingProto nav_bar_kids_mode = 91 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    message NavBar {
+        option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+        // Nav bar is forced to always be visible, even in immersive mode.
+        optional SettingProto nav_bar_force_visible = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        // Indicates whether the device is in kids nav mode.
+        optional SettingProto nav_bar_kids_mode = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional NavBar nav_bar = 92;
+    reserved 91; // Formerly nav_bar_kids_mode
+    reserved "nav_bar_kids_mode"; // Moved to message NavBar
+
     optional SettingProto navigation_mode = 76 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
     message NfcPayment {
@@ -668,5 +679,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 92;
+    // Next tag = 93;
 }
diff --git a/core/proto/android/server/biometrics.proto b/core/proto/android/server/biometrics.proto
index fc9da90..ac9e3e0 100644
--- a/core/proto/android/server/biometrics.proto
+++ b/core/proto/android/server/biometrics.proto
@@ -91,23 +91,9 @@
         STATE_CLIENT_DIED_CANCELLING = 10;
     }
 
-    enum MultiSensorState {
-        // Initializing or not yet started.
-        MULTI_SENSOR_STATE_UNKNOWN = 0;
-        // Sensors are in the process of being transitioned and there is no active sensor.
-        MULTI_SENSOR_STATE_SWITCHING = 1;
-        // Face sensor is being used as the primary input.
-        MULTI_SENSOR_STATE_FACE_SCANNING = 2;
-        // Fingerprint sensor is being used as the primary input.
-        MULTI_SENSOR_STATE_FP_SCANNING = 3;
-    }
-
     repeated SensorServiceStateProto sensor_service_states = 1;
 
     optional AuthSessionState auth_session_state = 2;
-
-    // Additional session state information, when the device has multiple sensors.
-    optional MultiSensorState auth_session_multi_sensor_state = 3;
 }
 
 // Overall state for an instance of a <Biometric>Service, for example FingerprintService or
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index c33b7c9..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 */
@@ -382,6 +383,7 @@
     optional bool in_size_compat_mode = 32;
     optional float min_aspect_ratio = 33;
     optional bool provides_max_bounds = 34;
+    optional bool enable_recents_screenshot = 35;
 }
 
 /* represents WindowToken */
@@ -445,6 +447,7 @@
     optional bool has_compat_scale = 43;
     optional float global_scale = 44;
     repeated .android.graphics.RectProto keep_clear_areas = 45;
+    repeated .android.graphics.RectProto unrestricted_keep_clear_areas = 46;
 }
 
 message IdentifierProto {
diff --git a/core/proto/android/service/diskstats.proto b/core/proto/android/service/diskstats.proto
index f79de39..ad3d673 100644
--- a/core/proto/android/service/diskstats.proto
+++ b/core/proto/android/service/diskstats.proto
@@ -99,6 +99,8 @@
         FOLDER_CACHE = 1;
         // System folder
         FOLDER_SYSTEM = 2;
+        // Metadata folder
+        FOLDER_METADATA = 3;
     }
     // Which folder?
     optional Folder folder = 1;
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 80317b8..21baa0b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1903,14 +1903,16 @@
          to improve wifi performance.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MANAGE_WIFI_AUTO_JOIN"
-                android:protectionLevel="signature|privileged" />
+                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.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MANAGE_WIFI_INTERFACES"
-                android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged|knownSigner"
+                android:knownCerts="@array/wifi_known_signers" />
 
     <!-- @SystemApi @hide Allows apps to create and manage IPsec tunnels.
          <p>Only granted to applications that are currently bound by the
@@ -1948,7 +1950,8 @@
      modifications.
      <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.OVERRIDE_WIFI_CONFIG"
-        android:protectionLevel="signature|privileged" />
+                android:protectionLevel="signature|privileged|knownSigner"
+                android:knownCerts="@array/wifi_known_signers" />
 
     <!-- @deprecated Allows applications to act as network scorers. @hide @SystemApi-->
     <permission android:name="android.permission.SCORE_NETWORKS"
@@ -2934,7 +2937,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" />
 
@@ -2943,6 +2946,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"
@@ -3711,15 +3718,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" />
 
     <!-- ==================================== -->
@@ -4119,6 +4137,13 @@
     <permission android:name="android.permission.MANAGE_HOTWORD_DETECTION"
                 android:protectionLevel="internal|preinstalled" />
 
+    <!-- Allows an application to subscribe to keyguard locked (i.e., showing) state.
+         <p>Protection level: internal|role
+         <p>Intended for use by ROLE_ASSISTANT only.
+    -->
+    <permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE"
+                android:protectionLevel="internal|role"/>
+
     <!-- Must be required by a {@link android.service.autofill.AutofillService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature
@@ -6643,10 +6668,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>
@@ -6900,10 +6924,6 @@
                     android:resource="@xml/autofill_compat_accessibility_service" />
         </service>
 
-        <service android:name="com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-
         <service android:name="com.android.server.blob.BlobStoreIdleJobService"
                  android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
@@ -6916,6 +6936,10 @@
                  android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
 
+        <service android:name="com.android.server.BinaryTransparencyService$UpdateMeasurementsJobService"
+                 android:permission="android.permission.BIND_JOB_SERVICE">
+        </service>
+
         <service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader"
             android:exported="false">
             <intent-filter>
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/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/drawable/ic_swap_horiz.xml b/core/res/res/drawable/ic_swap_horiz.xml
new file mode 100644
index 0000000..e7517f9
--- /dev/null
+++ b/core/res/res/drawable/ic_swap_horiz.xml
@@ -0,0 +1,28 @@
+<?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.
+ */
+-->
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M17,14L15.6,12.575L18.175,10H11V8H18.175L15.6,5.425L17,4L22,9ZM7,20L2,15L7,10L8.4,11.425L5.825,14H13V16H5.825L8.4,18.575Z" />
+</vector>
diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml
index cce9593..252f59e 100644
--- a/core/res/res/layout/autofill_fill_dialog.xml
+++ b/core/res/res/layout/autofill_fill_dialog.xml
@@ -22,8 +22,7 @@
     android:layout_height="wrap_content"
     android:layout_marginTop="@dimen/autofill_save_outer_top_margin"
     android:padding="@dimen/autofill_save_outer_top_padding"
-    android:elevation="@dimen/autofill_elevation"
-    android:background="?android:attr/colorBackground"
+    android:background="@drawable/bottomsheet_background"
     android:orientation="vertical">
 
     <LinearLayout
@@ -48,9 +47,7 @@
             android:gravity="center_horizontal"
             android:paddingStart="@dimen/autofill_save_inner_padding"
             android:paddingEnd="@dimen/autofill_save_inner_padding"
-            android:visibility="gone"
-            android:foreground="?attr/listChoiceBackgroundIndicator"
-            style="@style/AutofillDatasetPicker" />
+            android:visibility="gone" />
     </LinearLayout>
 
     <LinearLayout
@@ -61,7 +58,6 @@
         android:paddingStart="@dimen/autofill_save_inner_padding"
         android:paddingEnd="@dimen/autofill_save_inner_padding"
         android:visibility="gone"
-        android:foreground="?attr/listChoiceBackgroundIndicator"
         style="@style/AutofillDatasetPicker" />
 
     <ListView
@@ -71,15 +67,12 @@
         android:layout_height="0dp"
         android:drawSelectorOnTop="true"
         android:clickable="true"
-        android:divider="@null"
+        android:divider="?android:attr/listDivider"
         android:visibility="gone"
-        android:paddingStart="@dimen/autofill_save_inner_padding"
-        android:paddingEnd="@dimen/autofill_save_inner_padding"
-        android:foreground="?attr/listChoiceBackgroundIndicator"
         style="@style/AutofillDatasetPicker" />
 
     <com.android.internal.widget.ButtonBarLayout
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="end"
         android:padding="@dimen/autofill_save_button_bar_padding"
@@ -91,7 +84,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             style="?android:attr/buttonBarButtonStyle"
-            android:text="@string/dismiss_action">
+            android:text="@string/autofill_save_no">
         </Button>
 
         <Space
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index d4c3565..eb5fd56 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -72,7 +72,7 @@
         </LinearLayout>
 
         <com.android.internal.widget.ButtonBarLayout
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="end"
             android:padding="@dimen/autofill_save_button_bar_padding"
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/user_switching_dialog.xml b/core/res/res/layout/user_switching_dialog.xml
index c806210..2e041f5 100644
--- a/core/res/res/layout/user_switching_dialog.xml
+++ b/core/res/res/layout/user_switching_dialog.xml
@@ -18,10 +18,13 @@
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/message"
         style="?attr/textAppearanceListItem"
-        android:layout_width="match_parent"
+        android:background="?attr/colorSurface"
+        android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:gravity="center"
+        android:drawablePadding="12dp"
+        android:drawableTint="?attr/textColorPrimary"
         android:paddingStart="?attr/dialogPreferredPadding"
         android:paddingEnd="?attr/dialogPreferredPadding"
         android:paddingTop="24dp"
-        android:paddingBottom="24dp" />
\ No newline at end of file
+        android:paddingBottom="24dp" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 50f6a42c..8c01f4f 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Drierigtingbel"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Verwerping van ongewenste, irriterende oproepe"</string>
     <string name="CndMmi" msgid="185136449405618437">"Oproepnommer-lewering"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Moenie Steur Nie"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Beller-ID se verstek is beperk. Volgende oproep: beperk"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Beller-ID se verstek is beperk. Volgende oproep: nie beperk nie"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Beller-ID se verstek is nie beperk nie. Volgende oproep: beperk"</string>
@@ -545,7 +546,7 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Laat die program toe om op Bluetooth-toestelle in die omtrek te adverteer"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"bepaal relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Laat die program toe om relatiewe posisie tussen ultrabreëbandtoestelle in die omtrek te bepaal"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interaksie met wi‑fi-toestelle in die omtrek te hê"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"om interaksie met wi‑fi-toestelle in die omtrek te hê"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Laat die program toe om op toestelle in die omtrek te adverteer, aan hulle te koppel en hul relatiewe posisie te bepaal"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Voorkeur-NFC-betalingdiensinligting"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Laat die program toe om voorkeur-NFC-betalingdiensinligting soos geregistreerde hulpmiddels en roetebestemming te kry."</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dit laat die houer toe om aan die top-koppelvlak van \'n diensverskaffer-boodskapdiens te bind. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"verbind aan diensverskafferdienste"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Laat die houer toe om aan diensverskafferdienste te verbind. Behoort nooit vir normale programme nodig te wees nie."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"verkry toegang tot Moenie Steur Nie"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Laat die program toe om Moenie Steur Nie-opstelling te lees en skryf."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"begin kyk van toestemminggebruik"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Laat die houer toe om die toestemminggebruik vir \'n program te begin. Behoort nooit vir normale programme nodig te wees nie."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"begin Bekyk Toestemmingbesluite"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Slaan oor"</string>
     <string name="no_matches" msgid="6472699895759164599">"Geen passings nie"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Vind op bladsy"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# passing}other{# van {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Klaar"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Vee tans gedeelde berging uit …"</string>
     <string name="share" msgid="4157615043345227321">"Deel"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (volgende wekker)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Totdat jy dit afskakel"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Totdat jy Moenie Steur Nie afskakel"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Vou in"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Moenie Steur Nie"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Staantyd"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Weeksaand"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Naweek"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Oproepe en kennisgewings sal vibreer"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Oproepe en kennisgewings sal gedemp wees"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Stelselveranderinge"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Moenie Steur Nie"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nuut: Moenie Steur Nie versteek tans kennisgewings"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tik om meer te wete te kom en te verander."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Moenie Steur Nie het verander"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tik om te kyk wat geblokkeer word."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Stelsel"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Instellings"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Skakel af"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Kom meer te wete"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Verbeterde kennisgewings het Android se aanpasbare kennisgewings in Android 12 vervang. Hierdie kenmerk wys voorgestelde handelinge en antwoorde en organiseer jou kennisgewings.\n\nVerbeterde kennisgewings het toegang tot kennisgewinginhoud, insluitend persoonlike inligting soos kontakname en boodskappe. Hierdie kenmerk kan ook kennisgewings toemaak of daarop antwoord, soos om foonoproepe te beantwoord en Moenie Steur Nie te beheer."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Roetinemodus-inligtingkennisgewing"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery kan afloop voordat dit normaalweg gelaai word"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterybespaarder is geaktiveer om batterylewe te verleng"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> werk tans op die agtergrond en gebruik batterykrag. Tik om na te gaan."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> werk al vir \'n lang tyd op die agtergrond. Tik om na te gaan."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Gaan aktiewe programme na"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kan nie toegang tot kamera van hierdie toestel af kry nie"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 2e6f3e0..7197216 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"የሦስትዮሽ ጥሪ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"የሚያበሳጭ የማይፈለጉ ጥሪዎች አለመቀበል።"</string>
     <string name="CndMmi" msgid="185136449405618437">"መደወያ ቁጥር አስረከበ"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"አትረብሽ"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"የደዋይID  ወደ ተከልክሏል ነባሪዎች።ጥሪ ቀጥሎ ተከልክሏል፡"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"የደዋይ  ID  ወደ ተከልክሏል ነባሪዎች።ቀጥሎ ጥሪ፡ አልተከለከለም"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"የደዋይ  ID  ወደ አልተከለከለም ነባሪዎች።ቀጥሎ ጥሪ፡ ተከልክሏል"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ያዢው በሞባይል አገልግሎት ሰጪ የመልዕክት አላላክ አገልግሎት ላይ ከፍተኛውን ደረጃ በይነ ገጽ እንዲይዝ ይፈቅድለታል። ለመደበኛ መተግበሪያ በጭራሽ አያስፈልግም።"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"ከአገልግሎት አቅራቢ አገልግሎቶች ጋር እሰር"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"ያዢው የአገልግሎት አቅራቢ አገልግሎቶችን እንዲያስር ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"አትረብሽን ድረስበት"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"መተግበሪያው የአትረብሽ ውቅረትን እንዲያነብብ እና እንዲጸፍ ይፈቅዳል።"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"የእይታ ፈቃድ መጠቀምን መጀመር"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ያዢው ለአንድ መተግበሪያ የፈቃድ አጠቃቀሙን እንዲያስጀምር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"የእይታ ፈቃድ ውሳኔዎችን ይጀምሩ"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ዝለል"</string>
     <string name="no_matches" msgid="6472699895759164599">"ምንም ተመሳሳይ የለም።"</string>
     <string name="find_on_page" msgid="5400537367077438198">"በገፅ ላይ አግኝ"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# ተዛማጅ}one{# ከ{total}}other{# ከ{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"ተከናውኗል"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"የተጋራ ማከማቻን በመደምሰስ ላይ…"</string>
     <string name="share" msgid="4157615043345227321">"አጋራ"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"እስከ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ድረስ"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"እስከ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ቀጣይ ማንቂያ)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"እስኪያጠፉት ድረስ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"አትረብሽን እስኪያጠፉ ድረስ"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ሰብስብ"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"አትረብሽ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"የማይገኝበት ጊዜ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"የሳምንት ለሊት"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"የሳምንት እረፍት ቀናት"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ጥሪዎች እና ማሳወቂያዎች ይነዝራሉ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ጥሪዎች እና ማሳወቂያዎች ድምፀ-ከል ይሆናሉ"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"የሥርዓት ለውጦች"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"አትረብሽ"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"አዲስ፦ አትረብሽ ማሳወቂያዎችን እየደበቀ ነው"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"የበለጠ ለመረዳት እና ለመለወጥ መታ ያድርጉ።"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"አትረብሽ ተቀይሯል"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ምን እንደታገደ ለመፈተሽ መታ ያድርጉ።"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ሥርዓት"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ቅንብሮች"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"እሺ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"አጥፋ"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"የበለጠ ለመረዳት"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"የተሻሻሉ ማሳወቂያዎች በAndroid 12 ውስጥ Android ራስ-አስማሚ ማሳወቂያዎችን ተክተዋል። ይህ ባህሪ የተጠቆሙ እርምጃዎችን እና ምላሾችን ያሳያል እንዲሁም ማሳወቂያዎችዎን ያደራጃል።\n\nየተሻሻሉ ማሳወቂያዎች እንደ የእውቂያ ስሞች እና መልዕክቶች ያሉ የግል መረጃዎችን ጨምሮ የማሳወቂያ ይዘቶችን መድረስ ይችላሉ። ይህ ባህሪ እንደ የስልክ ጥሪዎችን መመለስ እና አትረብሽን መቆጣጠርን ያሉ ማሳወቂያዎችን ማሰናበት ወይም ምላሽ መስጠት ይችላል።"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"የዕለት ተዕለት ሁነታ መረጃ ማሳወቂያዎች"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ባትሪ ከተለመደው ኃይል መሙላት በፊት ሊያልቅ ይችላል"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"የባትሪ ቆጣቢ የባትሪ ዕድሜን ለማራዘም ገብሯል።"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ከበስተጀርባ በማሄድ ላይ ነው እና ባትሪ እየጨረሰ ነው። ለመገምገም መታ ያድርጉ።"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ከበስተጀርባ ለረጅም ጊዜ በማሄድ ላይ ነው። ለመገምገም መታ ያድርጉ።"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ንቁ መተግበሪያዎችን ይፈትሹ"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ከዚህ መሣሪያ ሆኖ ካሜራን መድረስ አይቻልም"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index e2234e4..850c2f0 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -74,6 +74,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"اتصال ثلاثي"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"رفض المكالمات المزعجة غير المرغوب فيها"</string>
     <string name="CndMmi" msgid="185136449405618437">"تسليم رقم الاتصال"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"عدم الإزعاج"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"الإعداد التلقائي لمعرف المتصل هو محظور  . الاتصال التالي: محظور"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"الإعداد التلقائي لمعرف المتصل هو محظور  . الاتصال التالي: غير محظور"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"الإعداد التلقائي لمعرف المتصل هو غير محظور  . الاتصال التالي: محظور"</string>
@@ -308,10 +309,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"الوصول إلى تقويمك"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏إرسال رسائل قصيرة SMS وعرضها"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"الملفات والمستندات"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"الوصول إلى الملفات والمستندات على جهازك"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"الموسيقى والملفات الصوتية الأخرى"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"الوصول إلى الملفات الصوتية على جهازك"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"الصور والفيديوهات"</string>
@@ -343,7 +342,7 @@
     <string name="capability_title_canPerformGestures" msgid="9106545062106728987">"تنفيذ إيماءات"</string>
     <string name="capability_desc_canPerformGestures" msgid="6619457251067929726">"يمكن النقر والتمرير بسرعة والتصغير أو التكبير بإصبعين وتنفيذ إيماءات أخرى."</string>
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"إيماءات بصمات الإصبع:"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"يمكن أن تلتقط الإيماءات التي تم تنفيذها على جهاز استشعار بصمة الإصبع في الجهاز."</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"يمكن أن تلتقط الإيماءات من أداة استشعار بصمة الإصبع في الجهاز."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"أخذ لقطة شاشة"</string>
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"يمكن أخذ لقطة شاشة."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"إيقاف شريط الحالة أو تعديله"</string>
@@ -552,7 +551,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"تحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"يسمح هذا الإذن للتطبيق بتحديد الموضع النسبي بين الأجهزة المجاورة التي تستخدم النطاق الواسع جدًا."</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"‏التفاعل مع أجهزة Wi‑Fi المجاورة"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏للسماح للتطبيق بالإعلان والربط وتحديد الموقع النسبي لأجهزة Wi-Fi المجاورة."</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"‏للسماح للتطبيق بعرض الإعلانات والاتصال بالأجهزة الأخرى وتحديد الموقع النسبي لأجهزة Wi-Fi المجاورة."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"‏معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"‏يسمح هذا الإذن للتطبيق بالحصول على معلومات الخدمات المدفوعة باستخدام الاتصال قصير المدى NFC المفضّل، مثلاً المساعدات المسجّلة ووجهة المسار."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"التحكم في اتصال الحقل القريب"</string>
@@ -592,12 +591,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"أدخِل قفل الشاشة للمتابعة"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"تم اكتشاف بصمة إصبع جزئية."</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"تعذرت معالجة بصمة الإصبع. يُرجى إعادة المحاولة."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"يُرجى تنظيف مستشعر بصمات الإصبع ثم إعادة المحاولة."</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"تنظيف المستشعر ثم إعادة المحاولة"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"اضغط بقوة على المستشعر."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"تم تحريك الإصبع ببطء شديد. يُرجى إعادة المحاولة."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"يمكنك تجربة بصمة إصبع أخرى."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"الصورة ساطعة للغاية."</string>
@@ -605,10 +601,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"غيِّر موضع إصبعك قليلاً في كل مرة."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"لم يتمّ التعرّف على البصمة."</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"اضغط بقوة على المستشعر."</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"تم مصادقة بصمة الإصبع"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"تمّت مصادقة الوجه"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"تمّت مصادقة الوجه، يُرجى الضغط على \"تأكيد\"."</string>
@@ -747,6 +741,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"يسمح لحامله بالالتزام بواجهة المستوى العالي لخدمة المراسلة التابعة لمشغل شبكة الجوَّال. ومن المفترض عدم الحاجة إليه مع التطبيقات العادية."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"الالتزام بخدمات مشغل شبكة الجوال"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"للسماح للمالك بالالتزام بخدمات مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"الوصول إلى إعداد \"عدم الإزعاج\""</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"للسماح للتطبيق بقراءة إعداد \"عدم الإزعاج\" وكتابتها."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"بدء استخدام إذن العرض"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"للسماح للمالك ببدء استخدام الإذن لأحد التطبيقات. ولن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"بدء اتخاذ القرارات المتعلقة بالإذن بعرض البيانات"</string>
@@ -1458,7 +1454,7 @@
     <string name="permdesc_requestDeletePackages" msgid="6133633516423860381">"للسماح لتطبيق ما بطلب حذف الحِزم."</string>
     <string name="permlab_requestIgnoreBatteryOptimizations" msgid="7646611326036631439">"طلب تجاهل تحسينات البطارية"</string>
     <string name="permdesc_requestIgnoreBatteryOptimizations" msgid="634260656917874356">"للسماح للتطبيق بطلب الإذن لتجاهل تحسينات البطارية في هذا التطبيق."</string>
-    <string name="permlab_queryAllPackages" msgid="2928450604653281650">"طلب البحث في كل الحِزم"</string>
+    <string name="permlab_queryAllPackages" msgid="2928450604653281650">"البحث في كل الحِزم"</string>
     <string name="permdesc_queryAllPackages" msgid="5339069855520996010">"يسمح هذا الإذن للتطبيق بعرض كل الحِزم المثبّتة."</string>
     <string name="permlab_accessSupplementalApi" msgid="3544659160536960275">"‏الوصول إلى SupplementalApis"</string>
     <string name="permdesc_accessSupplementalApi" msgid="8974758769370951074">"‏السماح لأحد التطبيقات بالوصول إلى SupplementalApis"</string>
@@ -1512,8 +1508,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"التخطي"</string>
     <string name="no_matches" msgid="6472699895759164599">"ليس هناك أي مطابقات"</string>
     <string name="find_on_page" msgid="5400537367077438198">"بحث في الصفحة"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{مطابقة واحدة}zero{# من إجمالي {total}}two{# من إجمالي {total}}few{# من إجمالي {total}}many{# من إجمالي {total}}other{# من إجمالي {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"تم"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"جارٍ محو بيانات مساحة التخزين المشتركة…"</string>
     <string name="share" msgid="4157615043345227321">"مشاركة"</string>
@@ -1878,8 +1873,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"حتى <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"حتى <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (التنبيه التالي)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"إلى أن يتم إيقاف الوضع"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"حتى يتم إيقاف \"عدم الإزعاج\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"تصغير"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"عدم الإزعاج"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"التعطل"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ليلة يوم من أيام الأسبوع"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"نهاية الأسبوع"</string>
@@ -2044,7 +2041,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"سيهتز الهاتف عند تلقّي المكالمات والإشعارات."</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"سيتم كتم صوت الهاتف عند تلقي المكالمات والإشعارات."</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"تغييرات النظام"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"عدم الإزعاج"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"جديد: يؤدي تفعيل ميزة \"عدم الإزعاج\" إلى إخفاء الإشعارات."</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"انقر لمعرفة مزيد من المعلومات وإجراء التغيير."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"تم تغيير ميزة \"عدم الإزعاج\""</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"انقر للاطّلاع على ما تم حظره."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"النظام"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"الإعدادات"</string>
@@ -2061,6 +2061,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"حسنًا"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"إيقاف"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزيد من المعلومات"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏تم إبدال الإشعارات التكيُّفية لنظام التشغيل Android في الإصدار 12 منه بالإشعارات المحسّنة. تعرض هذه الميزة إجراءات وردودًا مقترحة وتنظِّم الإشعارات.\n\nيمكن للإشعارات المحسّنة الوصول إلى محتوى الإشعارات، بما في ذلك المعلومات الشخصية، مثلاً أسماء جهات الاتصال والرسائل. يمكن لهذه الميزة أيضًا إغلاق الإشعارات أو الاستجابة لها، مثلاً الردّ على مكالمات الهاتف والتحكّم في ميزة \"عدم الإزعاج\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"إشعار معلومات \"وضع سلسلة الإجراءات\""</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"قد تنفد طاقة البطارية قبل الشحن المعتاد"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"تم تفعيل \"توفير شحن البطارية\" لإطالة عمرها."</string>
@@ -2267,6 +2268,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"يعمل تطبيق <xliff:g id="APP">%1$s</xliff:g> في الخلفية ويستنفد شحن البطارية. انقر لمراجعة الإعدادات."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"يعمل تطبيق <xliff:g id="APP">%1$s</xliff:g> في الخلفية لفترة طويلة. انقر لمراجعة الإعدادات."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"التحقّق من التطبيقات النشطة"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"لا يمكن الوصول إلى الكاميرا من هذا الجهاز."</string>
 </resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 90f6fca..4e6a317 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"ত্ৰিপক্ষীয় কলিং"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"আমনিদায়ক কল প্ৰত্যাখ্যান"</string>
     <string name="CndMmi" msgid="185136449405618437">"কল কৰা নম্বৰত ডেলিভাৰী"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"অসুবিধা নিদিব"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"কলাৰ আইডি সীমিত কৰিবলৈ পূর্বনির্ধাৰণ কৰা হৈছে। পৰৱৰ্তী কল: সীমিত কৰা হৈছে"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"কলাৰ আইডি সীমিত কৰিবলৈ পূর্বনির্ধাৰণ কৰা হৈছে। পৰৱৰ্তী কল: সীমিত কৰা হৈছে"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"কলাৰ আইডি সীমিত নকৰিবলৈ পূর্বনির্ধাৰণ কৰা হৈছে। পৰৱৰ্তী কল: সীমিত কৰা হোৱা নাই"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"বাহক মেছেজিং সেৱাৰ উচ্চ স্তৰৰ ইণ্টাৰফেইচত সংযোগ কৰিবলৈ ধাৰকক অনুমতি দিয়ে। এয়া সাধাৰণ এপবোৰৰ বাবে কেতিয়াও প্ৰয়োজন নহয়।"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"বাহক সেৱাসমূহৰ সৈতে সংযুক্ত হ\'ব পাৰে"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"বাহক সেৱাৰ সৈতে সংযুক্ত হ\'বলৈ ধাৰকক অনুমতি দিয়ে। সাধাৰণ এপসমূহৰ বাবে সাধাৰণতে প্ৰয়োজন হ\'ব নালাগে।"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"অসুবিধা নিদিব চাব পাৰে"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"অসুবিধা নিদিবৰ কনফিগাৰেশ্বনক পঢ়িবলৈ আৰু সালসলনি কৰিবলৈ এপটোক অনুমতি দিয়ে।"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"চোৱাৰ অনুমতিৰ ব্যৱহাৰ আৰম্ভ কৰক"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ধাৰকক কোনো এপৰ বাবে অনুমতিৰ ব্যৱহাৰ আৰম্ভ কৰিবলৈ দিয়ে। সাধাৰণ এপ্‌সমূহৰ বাবে কেতিয়াও প্ৰয়োজন হ’ব নালাগে।"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"অনুমতিৰ সিদ্ধান্তসমূহ চোৱা আৰম্ভ কৰক"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"এৰি যাওক"</string>
     <string name="no_matches" msgid="6472699895759164599">"কোনো মিল নাই"</string>
     <string name="find_on_page" msgid="5400537367077438198">"পৃষ্ঠাত বিচাৰক"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# টা মিল}one{{total}ৰ #}other{{total}ৰ #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"সম্পন্ন হ’ল"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"শ্বেয়াৰ কৰি থোৱা ষ্ট’ৰেজ মচি থকা হৈছে…"</string>
     <string name="share" msgid="4157615043345227321">"শ্বেয়াৰ কৰক"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পৰ্যন্ত"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (পৰৱৰ্তী এলার্ম) পর্যন্ত"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"আপুনি অফ নকৰা পর্যন্ত"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"আপুনি যেতিয়ালৈকে অসুবিধা নিদিব অফ নকৰে"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"সংকুচিত কৰক"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"অসুবিধা নিদিব"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ডাউনটাইম"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"কাৰ্য-দিনৰ নিশা"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"সপ্তাহ অন্ত"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"কল আৰু জাননীসমূহে কম্পন কৰিব"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"কল আৰু জাননীসমূহ মিউট কৰা হ\'ব"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"ছিষ্টেমৰ সালসলনি"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"অসুবিধা নিদিব"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"নতুন: অসুবিধা নিদিব ম\'ডে জাননীসমূহ লুকাই ৰাখিছে"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"অধিক জানিবলৈ আৰু সলনি কৰিবলৈ টিপক।"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"অসুবিধা নিদিব সলনি হৈছে"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"কি কি অৱৰোধ কৰা হৈছে জানিবলৈ টিপক।"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ছিষ্টেম"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ছেটিং"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ঠিক আছে"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"অফ কৰক"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"অধিক জানক"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12ত Androidৰ অভিযোজিত জাননীক উন্নত জাননীৰ দ্বাৰা সলনি কৰা হৈছে। এই সুবিধাটোৱে পৰামৰ্শ দিয়া কাৰ্য আৰু প্ৰত্যুত্তৰ দেখুৱায় আৰু আপোনাৰ জাননীসমূহ শৃংখলাবদ্ধ কৰে।\n\nউন্নত জাননীয়ে সম্পৰ্কৰ নাম আৰু বাৰ্তাৰ দৰে ব্যক্তিগত তথ্যকে ধৰি জাননীৰ সমল এক্সেছ কৰিব পাৰে। এই সুবিধাটোৱে জাননী অগ্ৰাহ্য কৰিব অথবা জাননীৰ প্ৰতি সঁহাৰি জনাবও পাৰে, যেনে ফ’ন কলৰ উত্তৰ দিয়া আৰু অসুবিধা নিদিব সুবিধাটো নিয়ন্ত্ৰণ কৰা আদি।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ৰুটিন ম’ডৰ তথ্য জাননী"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"চাৰ্জ কৰাৰ সচৰাচৰ সময়ৰ আগতেই বেটাৰী শেষ হ’ব পাৰে"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"বেটাৰীৰ খৰচ কমাবলৈ বেটাৰী সঞ্চয়কাৰী অন কৰা হৈছে"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> নেপথ্যত চলি আছে আৰু অত্যধিক বেটাৰী খৰচ কৰিছে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> নেপথ্যত দীৰ্ঘ সময় ধৰি চলি আছে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"সক্ৰিয় এপ্‌সমূহ পৰীক্ষা কৰক"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"এইটো ডিভাইচৰ পৰা কেমেৰা এক্সেছ কৰিব নোৱাৰি"</string>
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 8c4f0b6..c8089dc 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Üç yollu zəng"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Xoşagəlməz zənglərdən imtina"</string>
     <string name="CndMmi" msgid="185136449405618437">"Çatdırılma zəngi"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Narahat etməyin"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Zəng edənin kimliyi defolt olaraq qadağandır. Növbəti zəng: Qadağandır"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Zəng edənin kimliyi defolt olaraq qadağan deyil. Növbəti zəng: Qadağan deyil"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Zəng edənin kimliyi defolt olaraq qadağan deyil. Növbəti zəng: Qadağandır"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"təqvimə daxil olun"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"göndərin və SMS mesajlarına baxın"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fayllar &amp; sənədlər"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"cihazınızda fayllara və sənədlərə giriş"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiqi və digər audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"cihazınızdakı audio fayllarına giriş"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto və videolar"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Davam etmək üçün ekran kilidinizi daxil edin"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Barmaq izinin bir hissəsi aşkarlanıb"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmaq izi tanınmadı. Lütfən, yenidən cəhd edin."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Barmaq izi sensorunu silib yenidən cəhd edin"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensoru silib yenidən cəhd edin"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sensora basıb saxlayın"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Barmağınızı çox yavaş hərəkət etdirdiniz. Lütfən, yenidən cəhd edin."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başqa bir barmaq izini sınayın"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çox işıqlıdır"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Hər dəfə barmağınızın yerini bir az dəyişdirin"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Barmaq izi tanınmır"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sensora basıb saxlayın"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmaq izi doğrulandı"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Üz doğrulandı"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Üz təsdiq edildi, təsdiq düyməsinə basın"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Sahibə operatorun mesajlaşma xidmətinin yüksək səviyyəli interfeysini əlaqələndirmək imkanı verir. Adi proqramlar üçün heç vaxt lazım olmur."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"operator xidmətləri ilə əlaqələndirin"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Sahibinə operator xidmətləri ilə əlaqələndirməyə icazə verir. Normal tətbiqlər üçün heç vaxt lazım olmamalıdır."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"\"Narahat Etməyin\" funksiyasına daxil olun"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Tətbiqə \"Narahat Etməyin\" konfiqurasiyasını oxumağa və yazmağa icazə verin."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Baxış icazəsinin istifadəsinə başlayın"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Sahibinə tətbiqin icazədən istifadəsinə başlamağa imkan verir. Adi tətbiqlər üçün heç vaxt tələb edilmir."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"icazə qərarlarına baxışı başladın"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Keç"</string>
     <string name="no_matches" msgid="6472699895759164599">"Uyğunluq yoxdur"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Səhifədə tap"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# uyğunluq}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Hazırdır"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Paylaşılan yaddaş silinir…"</string>
     <string name="share" msgid="4157615043345227321">"Paylaşın"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Saat <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> qədər"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> radəsinə qədər (növbəti siqnal)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Deaktiv edilənə qədər"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"\"Narahat etməyin\" seçiminini deaktiv edənə kimi"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Dağıt"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Narahat etməyin"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Gözləmə müddəti"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Həftəiçi gecəsi"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Həftə sonu"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Zəng və bildirişlər vibrasiya verəcək"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Zəng və bildirişlər səssiz ediləcək"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistem dəyişiklikləri"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Narahat Etməyin"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Yenilik: \"Narahat etməyin\" rejimi bildirişləri gizlədir"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Ətraflı məıumat əldə edərək dəyişmək üçün klikləyin."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Narahat Etməyin\" rejimi dəyişdirildi"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nəyin blok edildiyini yoxlamaq üçün klikləyin."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Ayarlar"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Deaktiv edin"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ətraflı məlumat"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-də qabaqcıl bildirişlər var. Bu funksiya bütün bildirişləri qaydaya salır, cavab və əməliyyatlara dair tövsiyə verir.\n\nFunksiyanın kontaktlar, mesajlar və şəxsi məlumatlar daxil olmaqla bütün bildirişlərə girişi var. Zənglərə cavab verə, \"Narahat etməyin\" rejimini idarə edə, bildirişləri qapada və cavablaya bilər."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rejim üçün məlumat bildirişi"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batareya həmişəki vaxtdan əvvəl bitə bilər"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Enerjiyə Qənaət rejimi batareya istifadəsinin müddətini artırmaq üçün aktiv edilir"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> arxa fonda işləyir və enerjini tükədir. Nəzərdən keçirmək üçün toxunun."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzun müddət arxa fonda işləyir. Nəzərdən keçirmək üçün toxunun."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktiv tətbiqləri yoxlayın"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Bu cihazdan kameraya giriş mümkün deyil"</string>
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 0c3b88c..1741287 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -71,6 +71,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Trosmerno pozivanje"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Odbijanje nepoželjnih poziva"</string>
     <string name="CndMmi" msgid="185136449405618437">"Isporuka broja za pozivanje"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne uznemiravaj"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID pozivaoca je podrazumevano ograničen. Sledeći poziv: ograničen."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID pozivaoca je podrazumevano ograničen. Sledeći poziv: Nije ograničen."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID pozivaoca podrazumevano nije ograničen. Sledeći poziv: ograničen."</string>
@@ -305,10 +306,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupi kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"šalje i pregleda SMS poruke"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fajlovi i dokumenti"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"pristupanje fajlovima i dokumentima na uređaju"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzika i drugi audio sadržaj"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audio fajlovima na uređaju"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Slike i video snimci"</string>
@@ -589,12 +588,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrebite zaključavanje ekrana da biste nastavili"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Otkriven je delimičan otisak prsta"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nije uspela obrada otiska prsta. Probajte ponovo."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Obrišite senzor za otisak prsta i probajte ponovo"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Obrišite senzor i probajte ponovo"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Jako pritisnite senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Previše sporo ste pomerili prst. Probajte ponovo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probajte sa drugim otiskom prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Previše je svetlo"</string>
@@ -602,10 +598,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Jako pritisnite senzor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisak prsta je potvrđen"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je potvrđeno"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je potvrđeno. Pritisnite Potvrdi"</string>
@@ -744,6 +738,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dozvoljava vlasniku da se poveže sa interfejsom najvišeg nivoa za uslugu za razmenu poruka mobilnog operatera. Nikada ne bi trebalo da bude potrebno za standardne aplikacije."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"povezivanje sa uslugama operatera"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Dozvoljava vlasniku da se poveže sa uslugama operatera. Nikada ne bi trebalo da bude potrebno za obične aplikacije."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"pristupaj podešavanju Ne uznemiravaj"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Dozvoljava aplikaciji da čita i upisuje konfiguraciju podešavanja Ne uznemiravaj."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"početak korišćenja dozvole za pregled"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dozvoljava vlasniku da započne korišćenje dozvole za aplikaciju. Nikada ne bi trebalo da bude potrebna za uobičajene aplikacije."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"pokretanje pregleda odluka o dozvolama"</string>
@@ -1509,8 +1505,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Preskoči"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nema podudaranja"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Pronađi na stranici"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# podudaranje}one{# od {total}}few{# od {total}}other{# od {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Gotovo"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Briše se deljeni memorijski prostor…"</string>
     <string name="share" msgid="4157615043345227321">"Deli"</string>
@@ -1875,8 +1870,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sledeći alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Dok ne isključite"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dok ne isključite režim Ne uznemiravaj"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Skupi"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne uznemiravaj"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Odmor"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Radni dan uveče"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
@@ -2041,7 +2038,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibracija za pozive i obaveštenja je uključena"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Melodija zvona za pozive i obaveštenje je isključena"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistemske promene"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne uznemiravaj"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: Režim Ne uznemiravaj krije obaveštenja"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da biste saznali više i promenili podešavanje."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim Ne uznemiravaj je promenjen"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste proverili šta je blokirano."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Podešavanja"</string>
@@ -2058,6 +2058,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Potvrdi"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Isključi"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Poboljšana obaveštenja su zamenila Android prilagodljiva obaveštenja u Android-u 12. Ova funkcija pokazuje predložene radnje i odgovore, i organizuje obaveštenja.\n\nPoboljšana obaveštenja mogu da pristupaju sadržaju obaveštenja, uključujući lične podatke poput imena kontakata i poruka. Ova funkcija može i da odbacuje obaveštenja ili da odgovara na njih, na primer, da se javlja na telefonske pozive i kontroliše režim Ne uznemiravaj."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obaveštenje o informacijama Rutinskog režima"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija će se možda isprazniti pre uobičajenog punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžilo trajanje baterije"</string>
@@ -2096,7 +2097,7 @@
     <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Obaveštenja"</string>
     <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Brza podešavanja"</string>
     <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Dijalog napajanja"</string>
-    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključani ekran"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Zaključavanje ekrana"</string>
     <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Snimak ekrana"</string>
     <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Kuka za slušalice"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Prečica za pristupačnost na ekranu"</string>
@@ -2261,9 +2262,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Poruka je prevedena sa jezika <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivnost u pozadini"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktivnost u pozadini"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta u pozadini i troši bateriju. Dodirnite da biste pregledali."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> troši bateriju u pozadini. Dodirnite da biste pregledali."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je predugo pokrenuta u pozadini. Dodirnite da biste pregledali."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Proverite aktivne aplikacije"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ne možete da pristupite kameri sa ovog uređaja"</string>
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index cf8c2dd..85ddf07 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Трохбаковы выклік"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Адмова ад непажаданых раздражняючых выклікаў"</string>
     <string name="CndMmi" msgid="185136449405618437">"Дастаўка нумару выкліку"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Не турбаваць"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Налады ідэнтыфікатару АВН па змаўчанні абмежаваныя. Наступны выклік: абмежавана"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Ідэнтыфікатар АВН па змаўчанні абмежаваны. Наступны выклік: не абмежавана"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Па змаўчанні ідэнтыфікатар АВН не абмежаваны. Наступны выклік: абмежаваны"</string>
@@ -306,10 +307,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"атрымліваць доступ да вашага календара"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"адпраўляць і праглядаць SMS-паведамленні"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлы і дакументы"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"доступ да файлаў і дакументаў на вашай прыладзе"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка і іншае аўдыя"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"доступ да аўдыяфайлаў на вашай прыладзе"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фота і відэа"</string>
@@ -549,7 +548,7 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Дазволіць праграме адпраўляць рэкламу на прылады з Bluetooth, якія знаходзяцца паблізу"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"вызначаць адлегласць паміж прыладамі з звышшырокапалоснай сувяззю"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дазволіць праграме вызначаць адлегласць паміж прыладамі паблізу, якія выкарыстоўваюць звышшырокапалосную сувязь"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Узаемадзеянне з прыладамі з Wi‑Fi паблізу"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"узаемадзейнічаць з прыладамі з Wi‑Fi паблізу"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Праграма зможа адпраўляць даныя на прылады Wi-Fi паблізу, падключацца да іх і вызначаць іх месцазнаходжанне"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Інфармацыя пра прыярытэтны сэрвіс аплаты NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дазваляе праграме атрымаць доступ да інфармацыі пра прыярытэтны сэрвіс аплаты NFC, напрыклад зарэгістраваныя ідэнтыфікатары праграм і маршруты адпраўкі даных."</string>
@@ -590,12 +589,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Каб працягнуць, скарыстайце свой сродак блакіроўкі экрана"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Адбітак пальца адсканіраваны не цалкам"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не атрымалася апрацаваць адбітак пальца. Паспрабуйце яшчэ раз."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Ачысціце сканер адбіткаў пальцаў і паўтарыце спробу"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Ачысціце сканер і паўтарыце спробу"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Моцна націсніце на сканер"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Палец рухаўся занадта павольна. Паспрабуйце яшчэ раз."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Паспрабуйце іншы адбітак пальца"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Занадта светла"</string>
@@ -603,10 +599,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Кожны раз крыху мяняйце пазіцыю пальца"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Адбітак пальца не распазнаны"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Моцна націсніце на сканер"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Адбітак пальца распазнаны"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Твар распазнаны"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Твар распазнаны. Націсніце, каб пацвердзіць"</string>
@@ -745,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Дазваляе ўладальніку выконваць падключэнне да базавага інтэрфейсу сэрвісу абмену паведамленнямі аператара. Звычайныя праграмы ніколі не выкарыстоўваюць гэты дазвол."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"прывязвацца з сэрвісаў аператара"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Дазваляе ўладальніку ажыццяўляць прывязку да сэрвісаў аператара. Ніколі не павінна патрабавацца для звычайных праграм."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"атрымліваць доступ да рэжыму «Не турбаваць»"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Дазваляе праграме чытаць і выконваць запіс у канфігурацыю рэжыму «Не турбаваць»."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"запусціць выкарыстанне дазволаў на прагляд"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Дазваляе трымальніку запусціць выкарыстанне дазволаў праграмай. Не патрэбна для звычайных праграм."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"запускаць прагляд рашэнняў наконт дазволаў"</string>
@@ -1510,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Прапусціць"</string>
     <string name="no_matches" msgid="6472699895759164599">"Няма супадзенняў"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Знайсці на старонцы"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# супадзенне}one{# з {total}}few{# з {total}}many{# з {total}}other{# з {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Гатова"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Сціраюцца даныя абагуленага сховішча…"</string>
     <string name="share" msgid="4157615043345227321">"Абагуліць"</string>
@@ -1876,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Да <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Да <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (наступны будзільнік)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Пакуль не выключыце"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Пакуль вы не выключыце рэжым «Не турбаваць»"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Згарнуць"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не турбаваць"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Час бяздзеяння"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Будні вечар"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Выхадныя"</string>
@@ -2042,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Для выклікаў і апавяшчэнняў уключаны вібрасігнал"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Для выклікаў і апавяшчэнняў гук выключаны"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Сістэмныя змены"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не турбаваць"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Новае: у рэжыме \"Не турбаваць\" апавяшчэнні не паказваюцца"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Дакраніцеся, каб даведацца больш і змяніць."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Зменены налады рэжыму \"Не турбаваць\""</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Націсніце, каб паглядзець заблакіраванае."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Сістэма"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Налады"</string>
@@ -2059,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ОК"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Выключыць"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Даведацца больш"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"У версіі Android 12 Адаптыўныя апавяшчэнні Android заменены Палепшанымі апавяшчэннямі. Гэта функцыя ўпарадкоўвае вашы апавяшчэнні і паказвае прапановы дзеянняў і адказаў.\n\nПалепшаныя апавяшчэнні маюць доступ да змесціва ўсіх апавяшчэнняў, у тым ліку да асабістай інфармацыі – імён кантактаў і паведамленняў. Яшчэ гэта функцыя можа адхіляць апавяшчэнні ці адказваць на іх, напрыклад рэагаваць на тэлефонныя выклікі і кіраваць функцыяй \"Не турбаваць\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Апавяшчэнне з інфармацыяй пра ўсталяваны рэжым"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Акумулятар можа разрадзіцца хутчэй, чым прыйдзе час звычайнай зарадкі"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Каб павялічыць тэрмін работы акумулятара, уключаны рэжым эканоміі зараду"</string>
@@ -2265,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> працуе ў фонавым рэжыме і расходуе зарад акумулятара. Націсніце, каб праглядзець."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> працуе ў фонавым рэжыме працяглы час. Націсніце, каб праглядзець."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Праверце актыўныя праграмы"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"З гэтай прылады няма доступу да камеры."</string>
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 7183dce..dc393a3 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Тристранен разговор"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Отхвърляне на нежелани дразнещи обаждания"</string>
     <string name="CndMmi" msgid="185136449405618437">"Идентификация на повикванията"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Не безпокойте"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Стандартната идентификация на повикванията е „забранено“. За следващото обаждане тя е забранена."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Стандартната идентификация на повикванията е „забранено“. За следващото обаждане тя е разрешена."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Стандартната идентификация на повикванията е „разрешено“. За следващото обаждане тя е забранена."</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"има достъп до календара ви"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"да изпраща и преглежда SMS съобщения"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлове и документи"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"достъп до файловете и документите на устройството ви"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и друго аудиосъдържание"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"да има достъп до аудиофайловете на устройството ви"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Снимки и видеоклипове"</string>
@@ -547,8 +546,8 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Разрешава на приложението да рекламира на устройства с Bluetooth в близост"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"опред. на относителната позиция м/у у-вата с ултрашироколентови сигнали в близост"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Разрешаване на приложението да определя относителната позиция между устройствата с ултрашироколентови сигнали в близост"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Взаимодействие с устройствата с Wi-Fi в близост"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Разрешава на приложението да рекламира, да се свързва и да определя относителната позиция на у-вата с Wi-Fi в близост"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"взаимодействие с устройствата с Wi-Fi в близост"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Разрешава на приложението да рекламира, да се свързва и да определя относителната позиция на устройствата с Wi-Fi в близост"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информация за предпочитаната услуга за плащане чрез NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дава възможност на приложението да получава информация за предпочитаната услуга за плащане чрез NFC, като например регистрирани помощни средства и местоназначение."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"контролиране на комуникацията в близкото поле"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Въведете опцията си за заключване на екрана, за да продължите"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Установен е частичен отпечатък"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатъкът не бе обработен. Моля, опитайте отново."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Почистете сензора за отпечатъци и опитайте отново"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Почистете сензора и опитайте отново"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Натиснете добре върху сензора"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Преместихте пръста си твърде бавно. Моля, опитайте отново."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Опитайте с друг отпечатък"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Твърде светло е"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Всеки път променяйте леко позицията на пръста си"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отпечатъкът не е разпознат"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Натиснете добре върху сензора"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатъкът е удостоверен"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицето е удостоверено"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е удостоверено. Моля, натиснете „Потвърждаване“"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Разрешава на притежателя да се свърже към интерфейса от най-високото ниво на услуга за съобщения от оператор. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"свързване с услуги на оператор"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Разрешава на собственика да се свързва с услуги на оператор. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"достъп до „Не безпокойте“"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Предоставя на приложението достъп за четене и запис до конфигурацията на „Не безпокойте“."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"стартиране на прегледа на използваните разрешения"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Разрешава на притежателя да стартира прегледа на използваните разрешения за дадено приложение. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"стартиране на прегледа на решенията за разрешенията"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Пропускане"</string>
     <string name="no_matches" msgid="6472699895759164599">"Няма съответствия"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Намиране в страницата"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# съответствие}other{# от {total} съответствия}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Готово"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Споделеното хранилище се изтрива…"</string>
     <string name="share" msgid="4157615043345227321">"Споделяне"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"До следващия будилник (<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"До изключване"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Докато не изключите „Не безпокойте“"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Свиване"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не безпокойте"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Почивка"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Делнична нощ"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Събота и неделя"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"При обаждания и известия устройството ще вибрира"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Обажданията и известията ще бъдат заглушени"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Промени в системата"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не безпокойте"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Ново: Режимът „Не безпокойте“ скрива известията"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Докоснете, за да научите повече и да извършите промени."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Настройките за „Не безпокойте“ са променени"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Докоснете, за да проверите какво е блокирано."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Настройки"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Изключване"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Научете повече"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Адаптивните известия бяха заменени от функцията за подобрени известия в Android 12. Тя показва предложени действия и отговори и организира известията ви.\n\nФункцията може да осъществява достъп до съдържанието в известията, включително личната информация, като например имената на контактите и текстовите съобщения. Тя има възможност да отхвърля известията или да предприема действия в тях, като например приемане на телефонни обаждания или контролиране на режима „Не безпокойте“."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Известие с информация за режима на поредица"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерията може да се изтощи преди обичайното зареждане"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Режимът за запазване на батерията е активиран с цел удължаване на живота на батерията"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Съобщението бе преведено от <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност на заден план"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Активност на заден план"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> работи на заден план и изразходва батерията. Докоснете за преглед."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> работи на заден план и изразходва батерия. Докоснете за преглед."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> работи на заден план от дълго време. Докоснете за преглед."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете активните приложения"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не може да се осъществи достъп до камерата от това устройство"</string>
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 82932dc..a213c4d 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"তিন ভাবে কল করা"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"অবাঞ্ছিত বিরক্তিকর কলগুলি প্রত্যাখ্যান"</string>
     <string name="CndMmi" msgid="185136449405618437">"যে নম্বরটি থেকে কল করা হয় সেটি পাঠানো"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"বিরক্ত করবে না"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে৷ পরবর্তী কল: সীমাবদ্ধ নয়"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ডিফল্টরূপে কলার আইডি সীমাবদ্ধ করা থাকে না৷ পরবর্তী কল: সীমাবদ্ধ"</string>
@@ -546,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করুন"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"অ্যাপকে আশেপাশের Ultra-Wideband ডিভাইসগুলির আপেক্ষিক অবস্থান নির্ণয় করার অনুমতি দিন"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"আশপাশের ওয়াই-ফাই ডিভাইসের সাথে ইন্টার‍্যাক্ট করুন"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এটির ফলে অ্যাপ আশপাশের ওয়াই-ফাই ডিভাইসের তথ্য দেখাতে, তাদের সাথে কানেক্ট করতে এবং ত দূরত্বে আছে সেটি জানতে পারবে"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"এটির ফলে অ্যাপ আশপাশের ওয়াই-ফাই ডিভাইসের তথ্য দেখতে, তাদের সাথে কানেক্ট করতে এবং তা কত দূরত্বে আছে সেটি জানতে পারবে"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"পছন্দের NFC পেমেন্ট পরিষেবার তথ্য"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"অ্যাপের মাধ্যমে পছন্দসই এনএফসি পেমেন্ট পরিষেবার তথ্য, যেমন রেজিস্ট্রার করার সহায়তা এবং রুট ডেস্টিনেশন সম্পর্কিত তথ্য অ্যাক্সেস করার অনুমতি দেয়।"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"নিয়ার ফিল্ড কমিউনিকেশন নিয়ন্ত্রণ করে"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ধারককে, একটি ক্যারিয়ার মেসেজিং পরিষেবার উচ্চ স্তরের ইন্টারফেসে জুড়তে অনুমতি দেয়৷ সধারণ অ্যাপ্লিকেশনগুলির জন্য কখনই প্রয়োজন হয় না৷"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"পরিষেবা প্রদানকারীর সাথে যুক্ত হন"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"কোনো পরিষেবা প্রদানকারীর সাথে যুক্ত হতে ধারককে অনুমতি দিন। সাধারণ অ্যাপ্লিকেশানের জন্য প্র্রয়োজন হয় না।"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"\'বিরক্ত করবে না\' -তে অ্যাক্সেস"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"অ্যাপটিকে \'বিরক্ত করবে না\' কনফিগারেশন পড়া এবং লেখার অনুমতি দেয়।"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"দেখার অনুমতি কাজে লাগানো শুরু করুন"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"কোনও অ্যাপের কোনও নির্দিষ্ট অনুমতির ব্যবহার শুরু করার ক্ষেত্রে হোল্ডারকে সাহায্য করে। সাধারণ অ্যাপের জন্য এটির পরিবর্তন হওয়ার কথা নয়।"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"অনুমতি সংক্রান্ত সিদ্ধান্ত দেখা শুরু করুন"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"এড়িয়ে যান"</string>
     <string name="no_matches" msgid="6472699895759164599">"কোনো মিল নেই"</string>
     <string name="find_on_page" msgid="5400537367077438198">"পৃষ্ঠায় খুঁজুন"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{#টি ম্যাচ}one{{total}টির মধ্যে #টি}other{{total}টির মধ্যে #টি}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"সম্পন্ন হয়েছে"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"শেয়ার করা স্টোরেজ মুছে ফেলা হচ্ছে…"</string>
     <string name="share" msgid="4157615043345227321">"শেয়ার করুন"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত (পরবর্তী অ্যালার্ম)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"যতক্ষণ না আপনি বন্ধ করছেন"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"যতক্ষণ পর্যন্ত না আপনি বিরক্ত করবে না বন্ধ করছেন"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"সঙ্কুচিত করুন"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"বিরক্ত করবে না"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ডাউনটাইম"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"সপ্তাহান্তের রাত্রি"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"সপ্তাহান্ত"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"কল এবং বিজ্ঞপ্তি আসলে ভাইব্রেট হবে"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"কল এবং বিজ্ঞপ্তিগুলি মিউট করা হবে"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"সিস্টেমে হয়ে থাকা পরিবর্তন"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"বিরক্ত করবে না"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"নতুন: \'বিরক্ত করবে না\' মোড চালু আছে, তাই বিজ্ঞপ্তি লুকিয়ে ফেলা হচ্ছে"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"আরও জানতে এবং পরিবর্তন করতে ট্যাপ করুন।"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'বিরক্ত করবে না\' মোডের সেটিং বদলে গেছে"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"কী কী ব্লক করা আছে তা দেখতে ট্যাপ করুন।"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"সিস্টেম"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"সেটিংস"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ঠিক আছে"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"বন্ধ করুন"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"আরও জানুন"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 ভার্সনে Android অ্যাডাপ্টিভ বিজ্ঞপ্তির পরিবর্তে এনহ্যান্সড বিজ্ঞপ্তি এসেছে। এই ফিচারটি সাজেস্ট করা অ্যাকশন ও উত্তর দেখায় এবং আপনার বিজ্ঞপ্তিগুলি সাজিয়ে রাখে। \n\nএনহ্যান্সড বিজ্ঞপ্তি পরিচিতির নাম এবং মেসেজের মতো ব্যক্তিগত তথ্য সমেত বিজ্ঞপ্তির কন্টেন্টে অ্যাক্সেস করতে পারে। এছাড়া, এই ফিচার বিজ্ঞপ্তি খারিজ করতে বা তার উত্তর দিতে পারে, যেমন ফোন কলের উত্তর দেওয়া এবং \'বিরক্ত করবে না\' মোড নিয়ন্ত্রণ করা।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"রুটিন মোডের তথ্য সংক্রান্ত বিজ্ঞপ্তি"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"সাধারণত যখন চার্জ দেন, তার আগে চার্জ শেষ হয়ে যেতে পারে"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ডিভাইস বেশিক্ষণ চালু রাখতে ব্যাটারি সেভার চালু করা হয়েছে"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ব্যাকগ্রাউন্ডে চলছে এবং এর ফলে ব্যাটারির চার্জ কমে যাচ্ছে। পর্যালোচনা করতে ট্যাপ করুন।"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> অনেকক্ষণ ধরে ব্যাকগ্রাউন্ডে চলছে। পর্যালোচনা করতে ট্যাপ করুন।"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"অ্যাক্টিভ অ্যাপ চেক করুন"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"এই ডিভাইস থেকে ক্যামেরা অ্যাক্সেস করা যাচ্ছে না"</string>
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 4f4f7d6..9dc386c 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -71,6 +71,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Poziv između tri osobe"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Odbijanje neželjenih i dosadnih poziva"</string>
     <string name="CndMmi" msgid="185136449405618437">"Isporuka broja pozivaoca"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne ometaj"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Prikaz ID-a pozivaoca u zadanim postavkama zabranjen. Sljedeći poziv: zabranjen"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Prikaz ID-a pozivaoca u zadanim postavkama zabranjen. Sljedeći poziv: nije zabranjen"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Prikaz ID-a pozivaoca u zadanim postavkama nije zabranjen. Sljedeći poziv: zabranjen"</string>
@@ -737,6 +738,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dozvoljava vlasniku povezivanje s interfejsom najvišeg nivoa u servisu za poruke operatera. Nije potrebno za obične aplikacije."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"povezivanje na usluge operatera"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Omogućava vlasniku povezivanje sa uslugama operatera. Obično nije potrebno za obične aplikacije."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"pristup načinu rada Ne ometaj"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Omogućava aplikaciji da čita i upisuje konfiguraciju načina rada Ne ometaj."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"pokrenuti korištenje odobrenja za pregled"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dozvoljava vlasniku da pokrene korištenje odobrenja za aplikaciju. Ne bi trebalo biti potrebno za obične aplikacije."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"prikažite odluke o odobrenjima"</string>
@@ -1502,8 +1505,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Preskoči"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nema podudaranja"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Pronađi na stranici"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# podudaranje}one{# od ukupno {total}}few{# od ukupno {total}}other{# od ukupno {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Gotovo"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Brisanje dijeljene pohrane…"</string>
     <string name="share" msgid="4157615043345227321">"Dijeli"</string>
@@ -1868,8 +1870,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sljedeći alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Dok ne isključite"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dok ne isključite način rada Ne ometaj"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Suzi"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne ometaj"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Neaktivnost"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Radni dan uvečer"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
@@ -2034,7 +2038,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Pozivi i obavještenja će vibrirati"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Pozivi i obavještenja će se isključiti"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistemske promjene"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne ometaj"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: Način rada Ne ometaj sakriva obavještenja"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da saznate više i izvršite promjene."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Način rada Ne ometaj je promijenjen"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da provjerite šta je blokirano."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Postavke"</string>
@@ -2051,6 +2058,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Uredu"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Isključi"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Poboljšana obavještenja su zamijenila Prilagodljiva obavještenja Androida u verziji Android 12. Ova funkcija prikazuje predložene radnje i odgovore te organizira vaša obavještenja.\n\nPoboljšana obavještenja mogu pristupiti sadržaju obavještenja, uključujući lične informacije kao što su imena kontakata i poruke. Ova funkcija također može odbacivati obavještenja ili odgovarati na njih, npr. može odgovarati na telefonske pozive i kontrolirati funkciju Ne ometaj."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obavještenje za informacije Rutinskog načina"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Moguće je da će se baterija isprazniti prije uobičajenog punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Ušteda baterije je aktivirana da bi se produžio vijek trajanja baterije"</string>
@@ -2254,9 +2262,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Poruka je prevedena s jezika <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> na <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivnost u pozadini"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktivnost u pozadini"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> je pokrenuta u pozadini i troši bateriju. Dodirnite da pregledate."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> radi u pozadini i troši bateriju. Dodirnite da pregledate."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> dugo radi u pozadini. Dodirnite da pregledate."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Provjerite aktivne aplikacije"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nije moguće pristupiti kameri s ovog uređaja"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index fa531ad..a02b412 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Trucada a tres bandes"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rebuig de trucades molestes no desitjades"</string>
     <string name="CndMmi" msgid="185136449405618437">"Lliurament de número que truca"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"No molestis"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"El valor predeterminat de l\'identificador de trucada és restringit. Trucada següent: restringit"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"El valor predeterminat de l\'identificador de trucada és restringit. Trucada següent: no restringit"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"El valor predeterminat de l\'identificador de trucada és no restringit. Trucada següent: restringit"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accedir al calendari"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar i llegir missatges SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fitxers i documents"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"accedir als fitxers i documents del dispositiu"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música i altres fitxers d\'àudio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accedir a fitxers d\'àudio del dispositiu"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos i vídeos"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introdueix el teu bloqueig de pantalla per continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"S\'ha detectat una empremta digital parcial"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No s\'ha pogut processar l\'empremta digital. Torna-ho a provar."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Neteja el sensor d\'empremtes digitals i torna-ho a provar"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Neteja el sensor i torna-ho a provar"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Prem el sensor de manera ferma"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"El dit s\'ha mogut massa lentament. Torna-ho a provar."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prova una altra empremta digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hi ha massa llum"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Canvia lleugerament la posició del dit en cada intent"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"L\'empremta digital no s\'ha reconegut"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Prem el sensor de manera ferma"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"L\'empremta digital s\'ha autenticat"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Cara autenticada"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Cara autenticada; prem el botó per confirmar"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permet que el propietari la pugui vincular a la interfície principal del servei de missatgeria d\'un operador. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular-la a serveis de l\'operador de telefonia mòbil"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permet que el propietari la vinculi a serveis de l\'operador de telefonia mòbil. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"accedir a No molestis"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet que l\'aplicació llegeixi la configuració No molestis i hi escrigui."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"comença a utilitzar el permís de visualització"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet que un propietari comenci a utilitzar el permís amb una aplicació. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"inicia la visualització de les decisions sobre permisos"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Omet"</string>
     <string name="no_matches" msgid="6472699895759164599">"No s\'ha trobat cap coincidència"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Troba-ho a la pàgina"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# coincidència}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Fet"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"S\'està esborrant l\'emmagatzematge compartit…"</string>
     <string name="share" msgid="4157615043345227321">"Comparteix"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (propera alarma)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Fins que no el desactivis"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Fins que desactivis el mode No molestis"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Replega"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"No molestis"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Temps d\'inactivitat"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Nit entre setmana"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Cap de setmana"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Les trucades i les notificacions vibraran"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Les trucades i les notificacions se silenciaran"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Canvis del sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"No molestis"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novetat: el mode No molestis està amagant notificacions"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Toca per obtenir més informació i canviar la configuració."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"S\'ha canviat el mode No molestis"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toca per consultar què s\'ha bloquejat."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Configuració"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"D\'acord"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desactiva"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Més informació"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notificacions millorades han substituït les notificacions adaptatives d\'Android a Android 12. Aquesta funció mostra les accions i respostes suggerides, i organitza les teves notificacions.\n\nLes notificacions millorades poden accedir al contingut de les notificacions, inclosa la informació personal com els noms dels contactes i els missatges. Aquesta funció també pot ignorar les notificacions o respondre-hi; per exemple, pot contestar a trucades i controlar el mode No molestis."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificació d\'informació del mode de rutina"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"És possible que la bateria s\'esgoti abans de la càrrega habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"S\'ha activat l\'estalvi de bateria per prolongar-ne la durada"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Missatge traduït de <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> a <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activitat en segon pla"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Activitat en segon pla"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla i consumeix bateria. Toca per revisar-ho."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla i esgotant la bateria. Toca per revisar-ho."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Fa molta estona que <xliff:g id="APP">%1$s</xliff:g> s\'està executant en segon pla. Toca per revisar-ho."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta les aplicacions actives"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"No es pot accedir a la càmera des d\'aquest dispositiu"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index ee9d7bc..960eb82 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Konference tří účastníků"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Odmítnutí nevyžádaných obtěžujících hovorů"</string>
     <string name="CndMmi" msgid="185136449405618437">"Doručení volaného čísla"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Nerušit"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Ve výchozím nastavení je funkce ID volajícího omezena. Příští hovor: Omezeno"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Ve výchozím nastavení je funkce ID volajícího omezena. Příští hovor: Neomezeno"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Ve výchozím nastavení není funkce ID volajícího omezena. Příští hovor: Omezeno"</string>
@@ -306,10 +307,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"přístup ke kalendáři"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"odesílání a zobrazování zpráv SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Soubory a dokumenty"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"přístup k souborům a dokumentům v zařízení"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Hudba a ostatní zvuk"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"přístup ke zvukovým souborům v zařízení"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotky a videa"</string>
@@ -590,12 +589,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Pokračujte zadáním zámku obrazovky"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Byla zjištěna jen část otisku prstu"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Zpracování otisku prstu se nezdařilo. Zkuste to znovu."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Vyčistěte snímač otisků prstů a zkuste to znovu"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vyčistěte senzor a zkuste to znovu"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pevně zatlačte na senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pohyb prstem byl příliš pomalý. Zkuste to znovu."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Zkuste jiný otisk prstu"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Je příliš světlo"</string>
@@ -603,10 +599,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Pokaždé lehce změňte polohu prstu"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisk prstu nebyl rozpoznán"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pevně zatlačte na senzor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Otisk byl ověřen"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Obličej byl ověřen"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Obličej byl ověřen, stiskněte tlačítko pro potvrzení"</string>
@@ -745,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní služby zasílání zpráv prostřednictvím operátora. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"navázat se na služby operátora"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Umožňuje držiteli oprávnění navázat se na služby operátora. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"přístup k režimu Nerušit"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Umožňuje aplikaci číst a zapisovat konfiguraci režimu Nerušit."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"zahájení zobrazení využití oprávnění"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Umožňuje přístup zahájit využití oprávnění jiné aplikace. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"zobrazit rozhodnutí o oprávnění"</string>
@@ -1510,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Přeskočit"</string>
     <string name="no_matches" msgid="6472699895759164599">"Žádné shody"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Hledat na stránce"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# shoda}few{# z {total}}many{# z {total}}other{# z {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Hotovo"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Mazání sdíleného úložiště…"</string>
     <string name="share" msgid="4157615043345227321">"Sdílet"</string>
@@ -1876,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (příští budík)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Dokud funkci nevypnete"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dokud nevypnete režim Nerušit"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Sbalit"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Nerušit"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Doba klidu"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Večer v pracovním týdnu"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Víkend"</string>
@@ -2042,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Volání a oznámení budou vibrovat"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Volání a oznámení budou ztlumena"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Změny nastavení systému"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Nerušit"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novinka: Režim Nerušit skrývá oznámení"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Klepnutím zobrazíte další informace a provedete změny."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Nastavení režimu Nerušit se změnilo"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Klepnutím zkontrolujete, co je blokováno."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavení"</string>
@@ -2059,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Vypnout"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Další informace"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Adaptivní oznámení pro Android byla v systému Android 12 nahrazena vylepšenými oznámeními. Tato funkce ukazuje navrhované akce a odpovědi a uspořádává oznámení.\n\nVylepšená oznámení mají přístup k obsahu oznámení, včetně osobních údajů, jako jsou jména kontaktů a zprávy. Tato funkce také může zavírat oznámení nebo na ně odpovídat, například přijímat telefonní hovory a ovládat režim Nerušit."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informační oznámení režimu sledu činností"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterie se možná vybije před obvyklým časem nabití"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Byl aktivován spořič baterie za účelem prodloužení výdrže"</string>
@@ -2265,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je spuštěna na pozadí a vybíjí baterii. Klepnutím ji zkontrolujete."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikace <xliff:g id="APP">%1$s</xliff:g> je už dlouhou dobu spuštěna na pozadí. Klepnutím ji zkontrolujete."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Zkontrolujte aktivní aplikace"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Z tohoto zařízení nelze získat přístup k fotoaparátu"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 66a31e7..ddd4254 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Trevejsopkald"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Afvisning af uønskede, irriterende opkald"</string>
     <string name="CndMmi" msgid="185136449405618437">"Levering af nummervisning"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Forstyr ikke"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Standarder for opkalds-id til begrænset. Næste opkald: Begrænset"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Standarder for opkalds-id til begrænset. Næste opkald: Ikke begrænset"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Standarder for opkalds-id til ikke begrænset. Næste opkald: Begrænset"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"have adgang til din kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og se sms-beskeder"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer og dokumenter"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"få adgang til filer og dokumenter på din enhed"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik og anden lyd"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Få adgang til lydfiler på din enhed"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Billeder og videoer"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"fastlægge den relative position mellem UWB-enheder i nærheden"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Tillad, at appen fastlægger den relative position mellem UWB-enheder (Ultra-Wideband) i nærheden"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagere med Wi‑Fi-enheder i nærheden"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Giver appen tilladelse til at informere om, oprette forbindelse til og fastslå den relative placering af Wi‑Fi -enheder i nærheden"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Giver appen tilladelse til at informere om, oprette forbindelse til og fastslå den relative placering af Wi‑Fi-enheder i nærheden"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Foretrukne oplysninger vedrørende NFC-betalingstjeneste"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Tillader, at appen får foretrukne oplysninger vedrørende NFC-betalingstjeneste, f.eks. registrerede hjælpemidler og rutedestinationer."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"administrere Near Field Communication"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Angiv din skærmlås for at fortsætte"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Et delvist fingeraftryk blev registreret"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingeraftrykket kunne ikke behandles. Prøv igen."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengør fingeraftrykslæseren, og prøv igen"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengør læseren, og prøv igen"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Hold fingeren nede på læseren"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du bevægede fingeren for langsomt. Prøv igen."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv med et andet fingeraftryk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Der er for lyst"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Flyt fingeren en smule hver gang"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingeraftrykket blev ikke genkendt"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Hold fingeren nede på læseren"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeraftrykket blev godkendt"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansigtet er godkendt"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansigtet er godkendt. Tryk på Bekræft."</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Dette giver indehaveren mulighed for at knytte sig til det øverste grænsefladeniveau for et mobilselskabs beskedtjeneste. Dette bør ikke være nødvendigt i normale apps."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"knytte til tjenester fra mobilselskabet"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Tillader, at brugeren knytter sig til tjenester fra mobilselskabet. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"have adgang til Forstyr ikke"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Giver appen tilladelse til at læse og redigere konfigurationen af Forstyr ikke."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start brugen at tilladelsesvisning"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Tillader, at brugeren kan bruge en tilladelse for en app. Dette bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"starte visningen af beslutninger om tilladelser"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Spring over"</string>
     <string name="no_matches" msgid="6472699895759164599">"Der er ingen matches"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Find på siden"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# resultat}one{# af {total}}other{# af {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Udfør"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Sletter delt lagerplads…"</string>
     <string name="share" msgid="4157615043345227321">"Del"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (næste alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Indtil du deaktiverer"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Indtil du slår \"Forstyr ikke\" fra"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Skjul"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Forstyr ikke"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Nedetid"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Hverdagsaften"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Telefonen vibrerer ved opkald og notifikationer"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Der afspilles ikke lyd ved opkald og notifikationer"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Systemændringer"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Forstyr ikke"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nyhed! Forstyr ikke skjuler notifikationer"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tryk for at få flere oplysninger og foretage ændringer."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Tilstanden Forstyr ikke blev ændret"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tryk for at se, hvad der er blokeret."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Indstillinger"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Deaktiver"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Få flere oplysninger"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Tilpassede Android-notifikationer blev erstattet af forbedrede notifikationer i Android 12. Denne funktion viser foreslåede handlinger og svar samt organiserer dine notifikationer.\n\nForbedrede notifikationer kan få adgang til indhold i notifikationer, bl.a. personlige oplysninger såsom beskeder og navne på kontakter. Funktionen kan også afvise eller svare på notifikationer, f.eks. ved at besvare telefonopkald og justere Forstyr ikke."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifikation med oplysninger om rutinetilstand"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Enheden løber muligvis tør for batteri, inden du normalt oplader den"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparefunktion er aktiveret for at forlænge batteritiden"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> kører i baggrunden og dræner batteriet. Tryk for at gennemgå."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> har kørt i baggrunden i lang tid. Tryk for at gennemgå."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tjek aktive apps"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kameraet kan ikke tilgås fra denne enhed"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 781dd99..7e2e6c7 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Dreierkonferenz"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Ablehnung unerwünschter Anrufe"</string>
     <string name="CndMmi" msgid="185136449405618437">"Rufnummernübermittlung"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Bitte nicht stören"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Anrufer-ID ist standardmäßig beschränkt. Nächster Anruf: Beschränkt"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Anrufer-ID ist standardmäßig beschränkt. Nächster Anruf: Nicht beschränkt"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Anrufer-ID ist standardmäßig nicht beschränkt. Nächster Anruf: Beschränkt"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"auf deinen Kalender zugreifen"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS senden und abrufen"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Dateien und Dokumente"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"Auf Dateien und Dokumente auf deinem Gerät zugreifen"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik &amp; andere Audiodateien"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"Zugriff auf Audiodateien auf deinem Gerät"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos &amp; Videos"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Relative Distanz zwischen Ultrabreitband-Geräten in der Nähe bestimmen"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ermöglicht der App, die relative Distanz zwischen Ultrabreitband-Geräten in der Nähe zu bestimmen"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Mit WLAN-Geräten in der Nähe interagieren"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Erlaubt der App, Inhalte an WLAN-Geräte in der Nähe zu senden, sich mit ihnen zu verbinden und ihre relative Positionierung zu ermitteln"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Erlaubt der App, Inhalte an WLAN-Geräte in der Nähe zu senden, sich mit ihnen zu verbinden und ihre relative Position zu ermitteln"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informationen zum bevorzugten NFC-Zahlungsdienst"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Ermöglicht der App, Informationen zum bevorzugten NFC-Zahlungsdienst abzurufen, etwa registrierte Hilfsmittel oder das Routenziel."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Nahfeldkommunikation steuern"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Displaysperre eingeben, um fortzufahren"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Fingerabdruck wurde nur teilweise erkannt"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Fingerabdruck konnte nicht verarbeitet werden. Bitte versuche es noch einmal."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Reinige den Fingerabdrucksensor und versuch es noch einmal"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Reinige den Sensor und versuche es noch einmal"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Drücke fest auf den Sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Finger zu langsam bewegt. Bitte versuche es noch einmal."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Anderen Fingerabdruck verwenden"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zu hell"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ändere jedes Mal die Position deines Fingers"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingerabdruck nicht erkannt"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Drücke fest auf den Sensor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingerabdruck wurde authentifiziert"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gesicht authentifiziert"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gesicht authentifiziert, bitte bestätigen"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Ermöglicht dem Inhaber die Bindung an die Oberfläche eines Mobilfunkanbieter-Messaging-Dienstes auf oberster Ebene. Für normale Apps sollte dies nie erforderlich sein."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"An Mobilfunkanbieter-Dienste binden"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Ermöglicht dem Inhaber die Bindung an Mobilfunkanbieter-Dienste. Für normale Apps sollte dies nicht erforderlich sein."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Auf „Bitte nicht stören“ zugreifen"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ermöglicht der App Lese- und Schreibzugriff auf die „Bitte nicht stören“-Konfiguration"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Mit der Verwendung der Anzeigeberechtigung beginnen"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ermöglicht dem Inhaber, die Berechtigungsnutzung für eine App zu beginnen. Sollte für normale Apps nie benötigt werden."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"Entscheidungen zu Leseberechtigung starten"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Überspringen"</string>
     <string name="no_matches" msgid="6472699895759164599">"Keine Treffer"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Auf Seite suchen"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# Übereinstimmung}other{# von {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Fertig"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Freigegebener Speicher wird gelöscht…"</string>
     <string name="share" msgid="4157615043345227321">"Teilen"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nächste Weckzeit)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Bis zur Deaktivierung"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Bis zur Deaktivierung von „Bitte nicht stören“"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Minimieren"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Bitte nicht stören"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Ruhezeit"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Abends unter der Woche"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Wochenende"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Gerät vibriert bei Anrufen und Benachrichtigungen"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Anrufe und Benachrichtigungen stummgeschaltet"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Systemänderungen"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Bitte nicht stören"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Neu: Durch „Bitte nicht stören“ werden Benachrichtigungen nicht mehr angezeigt"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Für weitere Informationen und zum Ändern tippen."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„Bitte nicht stören“ wurde geändert"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tippe, um zu überprüfen, welche Inhalte blockiert werden."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Einstellungen"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Ausschalten"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Weitere Informationen"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Die adaptiven Benachrichtigungen wurden in Android 12 durch die Funktion „Erweiterte Benachrichtigungen“ ersetzt. Diese Funktion zeigt Vorschläge für Aktionen und Antworten an und sortiert Benachrichtigungen.\n\nDie Funktion hat Zugriff auf alle Benachrichtigungen, darunter auch personenbezogene Daten wie Kontaktnamen und Nachrichten. Außerdem kann sie auf Benachrichtigungen antworten oder diese schließen und so beispielsweise Anrufe entgegennehmen oder „Bitte nicht stören“ steuern."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Infomitteilung zum Ablaufmodus"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Dein Akku könnte vor der gewöhnlichen Ladezeit leer sein"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Energiesparmodus aktiviert, um die Akkulaufzeit zu verlängern"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> wird im Hintergrund ausgeführt und belastet den Akku. Zum Prüfen tippen."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> wird schon längere Zeit im Hintergrund ausgeführt. Zum Prüfen tippen."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktive Apps prüfen"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Von diesem Gerät aus ist kein Zugriff auf die Kamera möglich"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index c9716d6..c6589c5 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Τριμερής κλήση"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Απόρριψη ανεπιθύμητων, ενοχλητικών κλήσεων"</string>
     <string name="CndMmi" msgid="185136449405618437">"Παράδοση καλούμενου αριθμού"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Μην ενοχλείτε"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Η αναγνώριση κλήσης βρίσκεται από προεπιλογή στην \"περιορισμένη\". Επόμενη κλήση: Περιορισμένη."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Η αναγνώριση κλήσης βρίσκεται από προεπιλογή στην \"περιορισμένη\". Επόμενη κλήση: Μη περιορισμένη"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Η αναγνώριση κλήσης βρίσκεται από προεπιλογή στην \"μη περιορισμένη\". Επόμενη κλήση: Περιορισμένη."</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"έχει πρόσβαση στο ημερολόγιό σας"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"στέλνει και να διαβάζει μηνύματα SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Αρχεία και έγγραφα"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"πρόσβαση σε αρχεία και έγγραφα στη συσκευή σας"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Μουσική και άλλο ηχητικό περιεχόμενο"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"πρόσβαση σε αρχεία ήχου στη συσκευή σας"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Φωτογραφίες και βίντεο"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Χρησιμοποιήστε το κλείδωμα οθόνης για να συνεχίσετε"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Εντοπίστηκε μέρους του δακτυλικού αποτυπώματος"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Δεν ήταν δυνατή η επεξεργασία του δακτυλικού αποτυπώματος. Δοκιμάστε ξανά."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Καθαρίστε τον αισθητήρα δακτυλικών αποτυπωμάτων και δοκιμάστε ξανά"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Καθαρίστε τον αισθητήρα και δοκιμάστε ξανά"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Πιέστε σταθερά τον αισθητήρα"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Πολύ αργή κίνηση δαχτύλου. Δοκιμάστε ξανά."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Δοκιμάστε άλλο δακτυλικό αποτύπωμα"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Υπερβολικά έντονος φωτισμός"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Αλλάζετε ελαφρώς τη θέση του δακτύλου σας κάθε φορά."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Δεν είναι δυνατή η αναγνώριση του δακτυλικού αποτυπώματος"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Πιέστε σταθερά τον αισθητήρα"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Η ταυτότητα του δακτυλικού αποτυπώματος ελέγχθηκε"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Έγινε έλεγχος ταυτότητας προσώπου"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Έγινε έλεγχος ταυτότητας προσώπου, πατήστε \"Επιβεβαίωση\""</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας ανταλλαγής μηνυμάτων εταιρείας κινητής τηλεφωνίας. Δεν απαιτείται για συνήθεις εφαρμογές."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"δεσμεύεται σε υπηρεσίες του παρόχου κινητής τηλεφωνίας"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Δίνει στον κάτοχο τη δυνατότητα δέσμευσης σε υπηρεσίες εταιρείας κινητής τηλεφωνίας. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"έχει πρόσβαση στη λειτουργία \"Μην ενοχλείτε\""</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Επιτρέπει στην εφαρμογή την εγγραφή και τη σύνταξη διαμόρφωσης για τη λειτουργία \"Μην ενοχλείτε\"."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"έναρξη χρήσης άδειας προβολής"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Επιτρέπει στον κάτοχο να ξεκινήσει τη χρήση της άδειας για μια εφαρμογή. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"έναρξη προβολής αποφάσεων για άδειες"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Παράβλεψη"</string>
     <string name="no_matches" msgid="6472699895759164599">"Δεν υπάρχουν αποτελέσματα"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Εύρεση στη σελίδα"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# αποτέλεσμα}other{# από {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Τέλος"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Διαγραφή κοινόχρηστου αποθηκευτικού χώρου…"</string>
     <string name="share" msgid="4157615043345227321">"Κοινή χρ."</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Έως τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Μέχρι τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (επόμενο ξυπνητήρι)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Μέχρι την απενεργοποίηση"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Μέχρι να απενεργοποιήσετε \"Μην ενοχλείτε\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Σύμπτυξη"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Μην ενοχλείτε"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Διακοπή λειτουργίας"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Νύχτα καθημερινής"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Σαββατοκύριακο"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Θα υπάρχει δόνηση για κλήσεις και ειδοποιήσεις"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Οι κλήσεις και οι ειδοποιήσεις θα τεθούν σε παύση"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Αλλαγές στο σύστημα"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Μην ενοχλείτε"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Νέο: Η λειτουργία \"Μην ενοχλείτε\" αποκρύπτει ειδοποιήσεις"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Πατήστε για να μάθετε περισσότερα και να κάνετε αλλαγές."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Η λειτουργία \"Μην ενοχλείτε\" άλλαξε"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Πατήστε για να ελέγξετε το περιεχόμενο που έχει αποκλειστεί."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Σύστημα"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Ρυθμίσεις"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ΟΚ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Απενεργοποίηση"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Μάθετε περισσότερα"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Στο Android 12, οι Βελτιωμένες ειδοποιήσεις αντικατέστησαν τις Προσαρμοστικές ειδοποιήσεις Android. Αυτή η λειτουργία εμφανίζει προτεινόμενες ενέργειες και απαντήσεις και οργανώνει τις ειδοποιήσεις σας.\n\nΟι Βελτιωμένες ειδοποιήσεις μπορούν να αποκτήσουν πρόσβαση σε περιεχόμενο ειδοποιήσεων, συμπεριλαμβανομένων προσωπικών στοιχείων, όπως ονομάτων επαφών και μηνυμάτων Αυτή η λειτουργία παρέχει επίσης τη δυνατότητα παράβλεψης ειδοποιήσεων ή απάντησης σε αυτές, όπως η απάντηση σε τηλεφωνικές κλήσεις και ο έλεγχος της λειτουργίας Μην ενοχλείτε."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ειδοποίηση πληροφοριών λειτουργίας Ρουτίνας"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Η μπαταρία μπορεί να εξαντληθεί πριν από τη συνηθισμένη φόρτιση"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Η Εξοικονόμηση μπαταρίας ενεργοποιήθηκε για την επέκταση της διάρκειας ζωής της μπαταρίας"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Μήνυμα που έχει μεταφραστεί από τα <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> στα <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Δραστηριότητα στο παρασκήνιο"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Δραστηριότητα στο παρασκήνιο"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται στο παρασκήνιο και καταναλώνει μπαταρία. Πατήστε για έλεγχο."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Το <xliff:g id="APP">%1$s</xliff:g> εκτελείται στο παρασκήνιο και καταναλώνει μπαταρία. Έλεγχος."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> εκτελείται στο παρασκήνιο για πολύ ώρα. Πατήστε για έλεγχο."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Έλεγχος ενεργών εφαρμογών"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Δεν είναι δυνατή η πρόσβαση στην κάμερα από αυτήν τη συσκευή."</string>
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 79a2e38..d417a07 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Three-way calling"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejection of undesired annoying calls"</string>
     <string name="CndMmi" msgid="185136449405618437">"Calling number delivery"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Do not disturb"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Caller ID defaults to restricted. Next call: Restricted"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Caller ID defaults to restricted. Next call: Not restricted"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Caller ID defaults to not restricted. Next call: Restricted"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"start view permission decisions"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Skip"</string>
     <string name="no_matches" msgid="6472699895759164599">"No matches"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Find on page"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# match}other{# of {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Done"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Erasing shared storage…"</string>
     <string name="share" msgid="4157615043345227321">"Share"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Until you turn off"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Until you turn off Do not disturb"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Collapse"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Do not disturb"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Downtime"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Weeknight"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Calls and notifications will vibrate"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Calls and notifications will be muted"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"System changes"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Do not disturb"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"New: Do Not Disturb is hiding notifications"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tap to find out more and change."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Settings"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Turn off"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Enhanced notifications replaced Android adaptive notifications in Android 12. This feature shows suggested actions and replies, and organises your notifications.\n\nEnhanced notifications can access notification content, including personal information like contact names and messages. This feature can also dismiss or respond to notifications, such as answering phone calls, and control Do Not Disturb."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
 </resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index da99fdd..309f09e 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Three-way calling"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejection of undesired annoying calls"</string>
     <string name="CndMmi" msgid="185136449405618437">"Calling number delivery"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Do not disturb"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Caller ID defaults to restricted. Next call: Restricted"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Caller ID defaults to restricted. Next call: Not restricted"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Caller ID defaults to not restricted. Next call: Restricted"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"start view permission decisions"</string>
@@ -1319,7 +1322,7 @@
     <string name="sms_short_code_confirm_deny" msgid="1356917469323768230">"Cancel"</string>
     <string name="sms_short_code_remember_choice" msgid="1374526438647744862">"Remember my choice"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="2620984439143080410">"You can change this later in Settings &gt; Apps"</string>
-    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Always Allow*"</string>
+    <string name="sms_short_code_confirm_always_allow" msgid="2223014893129755950">"Always allow"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="2688828813521652079">"Never Allow"</string>
     <string name="sim_removed_title" msgid="5387212933992546283">"SIM card removed"</string>
     <string name="sim_removed_message" msgid="9051174064474904617">"The mobile network will be unavailable until you restart with a valid SIM card inserted."</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Skip"</string>
     <string name="no_matches" msgid="6472699895759164599">"No matches"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Find on page"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# match}other{# of {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Done"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Erasing shared storage…"</string>
     <string name="share" msgid="4157615043345227321">"Share"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Until you turn off"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Until you turn off Do not disturb"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Collapse"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Do not disturb"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Downtime"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Weeknight"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Calls and notifications will vibrate"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Calls and notifications will be muted"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"System changes"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Do not disturb"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"New: Do Not Disturb is hiding notifications"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tap to find out more and change."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Settings"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Turn off"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Enhanced notifications replaced Android adaptive notifications in Android 12. This feature shows suggested actions and replies, and organises your notifications.\n\nEnhanced notifications can access notification content, including personal information like contact names and messages. This feature can also dismiss or respond to notifications, such as answering phone calls, and control Do Not Disturb."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index f01b9af..9b4a7a8 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Three-way calling"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejection of undesired annoying calls"</string>
     <string name="CndMmi" msgid="185136449405618437">"Calling number delivery"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Do not disturb"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Caller ID defaults to restricted. Next call: Restricted"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Caller ID defaults to restricted. Next call: Not restricted"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Caller ID defaults to not restricted. Next call: Restricted"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"start view permission decisions"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Skip"</string>
     <string name="no_matches" msgid="6472699895759164599">"No matches"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Find on page"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# match}other{# of {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Done"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Erasing shared storage…"</string>
     <string name="share" msgid="4157615043345227321">"Share"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Until you turn off"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Until you turn off Do not disturb"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Collapse"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Do not disturb"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Downtime"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Weeknight"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Calls and notifications will vibrate"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Calls and notifications will be muted"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"System changes"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Do not disturb"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"New: Do Not Disturb is hiding notifications"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tap to find out more and change."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Settings"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Turn off"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Enhanced notifications replaced Android adaptive notifications in Android 12. This feature shows suggested actions and replies, and organises your notifications.\n\nEnhanced notifications can access notification content, including personal information like contact names and messages. This feature can also dismiss or respond to notifications, such as answering phone calls, and control Do Not Disturb."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e509c70..34f5337 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Three-way calling"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejection of undesired annoying calls"</string>
     <string name="CndMmi" msgid="185136449405618437">"Calling number delivery"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Do not disturb"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Caller ID defaults to restricted. Next call: Restricted"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Caller ID defaults to restricted. Next call: Not restricted"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Caller ID defaults to not restricted. Next call: Restricted"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Allows the holder to bind to the top-level interface of an operator messaging service. Should never be needed for normal apps."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind to operator services"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Allows the holder to bind to operator services. Should never be needed for normal apps."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"access Do Not Disturb"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Allows the app to read and write Do Not Disturb configuration."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start view permission usage"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Allows the holder to start the permission usage for an app. Should never be needed for normal apps."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"start view permission decisions"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Skip"</string>
     <string name="no_matches" msgid="6472699895759164599">"No matches"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Find on page"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# match}other{# of {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Done"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Erasing shared storage…"</string>
     <string name="share" msgid="4157615043345227321">"Share"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (next alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Until you turn off"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Until you turn off Do not disturb"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Collapse"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Do not disturb"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Downtime"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Weeknight"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Calls and notifications will vibrate"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Calls and notifications will be muted"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"System changes"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Do not disturb"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"New: Do Not Disturb is hiding notifications"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tap to find out more and change."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Do Not Disturb has changed"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tap to check what\'s blocked."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Settings"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Turn off"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Learn more"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Enhanced notifications replaced Android adaptive notifications in Android 12. This feature shows suggested actions and replies, and organises your notifications.\n\nEnhanced notifications can access notification content, including personal information like contact names and messages. This feature can also dismiss or respond to notifications, such as answering phone calls, and control Do Not Disturb."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Routine Mode info notification"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Battery may run out before usual charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Battery Saver activated to extend battery life"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> is running in the background and draining battery. Tap to review."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> is running in the background for a long time. Tap to review."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Check active apps"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Cannot access camera from this device"</string>
 </resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index ec6400c..3da96a9 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‎Three way calling‎‏‎‎‏‎"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎Rejection of undesired annoying calls‎‏‎‎‏‎"</string>
     <string name="CndMmi" msgid="185136449405618437">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‎‏‎‏‎Calling number delivery‎‏‎‎‏‎"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‎Do not disturb‎‏‎‎‏‎"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‎‎‎Caller ID defaults to restricted. Next call: Restricted‎‏‎‎‏‎"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‎‏‎Caller ID defaults to restricted. Next call: Not restricted‎‏‎‎‏‎"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎Caller ID defaults to not restricted. Next call: Restricted‎‏‎‎‏‎"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps.‎‏‎‎‏‎"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎bind to carrier services‎‏‎‎‏‎"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎Allows the holder to bind to carrier services. Should never be needed for normal apps.‎‏‎‎‏‎"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‎access Do Not Disturb‎‏‎‎‏‎"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎Allows the app to read and write Do Not Disturb configuration.‎‏‎‎‏‎"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‎start view permission usage‎‏‎‎‏‎"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎Allows the holder to start the permission usage for an app. Should never be needed for normal apps.‎‏‎‎‏‎"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎start view permission decisions‎‏‎‎‏‎"</string>
@@ -1866,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎Until ‎‏‎‎‏‏‎<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎Until ‎‏‎‎‏‏‎<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ (next alarm)‎‏‎‎‏‎"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎Until you turn off‎‏‎‎‏‎"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎Until you turn off Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="FIRST">%1$s</xliff:g>‎‏‎‎‏‏‏‎ / ‎‏‎‎‏‏‎<xliff:g id="REST">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎Collapse‎‏‎‎‏‎"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‎Do not disturb‎‏‎‎‏‎"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎Downtime‎‏‎‎‏‎"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎Weeknight‎‏‎‎‏‎"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎Weekend‎‏‎‎‏‎"</string>
@@ -2032,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎Calls and notifications will vibrate‎‏‎‎‏‎"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎Calls and notifications will be muted‎‏‎‎‏‎"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‎System changes‎‏‎‎‏‎"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‏‎‏‎Do Not Disturb‎‏‎‎‏‎"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎New: Do Not Disturb is hiding notifications‎‏‎‎‏‎"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎Tap to learn more and change.‎‏‎‎‏‎"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎Do Not Disturb has changed‎‏‎‎‏‎"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎Tap to check what\'s blocked.‎‏‎‎‏‎"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‎System‎‏‎‎‏‎"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‎‏‏‎Settings‎‏‎‎‏‎"</string>
@@ -2049,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‎‎OK‎‏‎‎‏‎"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎Turn off‎‏‎‎‏‎"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎Learn more‎‏‎‎‏‎"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‎Enhanced notifications replaced Android Adaptive Notifications in Android 12. This feature shows suggested actions and replies, and organizes your notifications.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Enhanced notifications can access notification content, including personal information like contact names and messages. This feature can also dismiss or respond to notifications, such as answering phone calls, and control Do Not Disturb.‎‏‎‎‏‎"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‏‎‎‎‎‎‎Routine Mode info notification‎‏‎‎‏‎"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎Battery may run out before usual charge‎‏‎‎‏‎"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎Battery Saver activated to extend battery life‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 23531ea..f965231 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Llamada de tres direcciones"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rechazo de llamadas molestas no deseadas"</string>
     <string name="CndMmi" msgid="185136449405618437">"Entrega de número de llamada"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"No interrumpir"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"El identificador de llamadas está predeterminado en restringido. Llamada siguiente: restringida"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"El Identificador de llamadas está predeterminado en restringido. Llamada siguiente: no restringido"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"El identificador de llamadas está predeterminado en no restringido. Llamada siguiente: restringida"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder al calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Archivos y documentos"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"Accede a archivos y documentos en tu dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música y otro contenido de audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a los archivos de audio en tu dispositivo"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos y videos"</string>
@@ -341,7 +340,7 @@
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Gestos del sensor de huellas dactilares"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Capturará los gestos que se hacen en el sensor de huellas dactilares del dispositivo."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Tomar captura de pantalla"</string>
-    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede tomar una captura de la pantalla."</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Puede tomar capturas de pantalla."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"desactivar o modificar la barra de estado"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Permite que la aplicación inhabilite la barra de estado o que agregue y elimine íconos del sistema."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"aparecer en la barra de estado"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ingresa tu bloqueo de pantalla para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Detección parcial de una huella dactilar"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se pudo procesar la huella dactilar. Vuelve a intentarlo."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpia el sensor de huellas dactilares y vuelve a intentarlo"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpia el sensor y vuelve a intentarlo"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Presiona con firmeza el sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moviste el dedo muy lento. Vuelve a intentarlo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella dactilar"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia un poco la posición del dedo cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"No se reconoció la huella dactilar"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Presiona con firmeza el sensor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se autenticó la huella dactilar"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Se autenticó el rostro"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se autenticó el rostro; presiona Confirmar"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite al propietario vincularse a la interfaz de nivel superior del servicio de mensajería del proveedor. Las aplicaciones regulares no lo necesitan."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular con servicios de proveedores"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permite al propietario vincular con servicios de proveedores. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Acceso a la función No interrumpir"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite que la aplicación lea y modifique la configuración de la función No interrumpir."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso de permiso de vista"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que el propietario inicie el uso de permisos para una app. No debería requerirse para apps normales."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"iniciar vista de las decisiones sobre permisos"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Omitir"</string>
     <string name="no_matches" msgid="6472699895759164599">"Sin coincidencias"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Buscar en la página"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# coincidencia}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Listo"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Borrando almacenamiento compartido…"</string>
     <string name="share" msgid="4157615043345227321">"Compartir"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Hasta la(s) <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Hasta la hora <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próxima alarma)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Hasta que lo desactives"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Hasta que desactives No interrumpir"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Contraer"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"No interrumpir"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Tiempo de inactividad"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noche, en la semana"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibrarán las llamadas y notificaciones"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Se silenciarán las llamadas y notificaciones"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Cambios del sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"No interrumpir"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nuevo: No interrumpir oculta las notificaciones"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Presiona para obtener más información y realizar cambios."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Se modificó la opción No interrumpir"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Presiona para consultar lo que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Configuración"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Aceptar"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desactivar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas reemplazaron a las notificaciones adaptables en Android 12. Esta función muestra respuestas y acciones sugeridas, y organiza tus notificaciones.\n\nLas notificaciones mejoradas pueden acceder a todo el contenido de notificaciones, lo que incluye información personal, como nombres de contactos y mensajes. También puede descartar o responder notificaciones (como atender llamadas) y controlar la función No interrumpir."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación de información del modo de Rutinas"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Es posible que la batería se agote antes de la carga habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se activó el Ahorro de batería para extender la duración de la batería"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Se tradujo el mensaje del <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> al <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Actividad en segundo plano"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Actividad en segundo plano"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano y está agotando la batería. Presiona para revisar esta actividad."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano y está agotando la batería. Presiona para revisar."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Hace mucho tiempo que <xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano. Presiona para revisar esta actividad."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consulta las apps activas"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"No se puede acceder a la cámara desde este dispositivo"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 7c0d36b..8231b01b 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Llamada a tres"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rechazo de llamadas molestas no deseadas"</string>
     <string name="CndMmi" msgid="185136449405618437">"Entrega de número de llamada entrante"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"No molestar"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"La identificación del emisor presenta el valor predeterminado de restringido. Siguiente llamada: Restringido"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"La identificación del emisor presenta el valor predeterminado de restringido. Siguiente llamada: No restringido"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"La la identificación del emisor presenta el valor predeterminado de no restringido. Siguiente llamada: Restringido"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder a tu calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar y ver mensajes SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Archivos y documentos"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"acceder a archivos y documentos de tu dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música y otros archivos de audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a los archivos de audio de tu dispositivo"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos y vídeos"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"calcular posición de dispositivos de banda ultraancha cercanos"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permite que la aplicación determine la posición relativa de los dispositivos de banda ultraancha cercanos"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Interactuar con dispositivos Wi-Fi cercanos"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite a la aplicación mostrar información de dispositivos Wi-Fi cercanos, conectarse a ellos y determinar su posición"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite a la aplicación mostrar, conectar y determinar la posición relativa de dispositivos Wi-Fi cercanos"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Información sobre el servicio de pago por NFC preferido"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que la aplicación obtenga información sobre el servicio de pago por NFC preferido, como identificadores de aplicación registrados y destinos de rutas."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar Comunicación de campo cercano (NFC)"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduce tu bloqueo de pantalla para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Huella digital parcial detectada"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"No se ha podido procesar la huella digital. Vuelve a intentarlo."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpia el sensor de huellas digitales e inténtalo de nuevo"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpia el sensor e inténtalo de nuevo"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Mantén pulsado firmemente el sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Has movido el dedo demasiado despacio. Vuelve a intentarlo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prueba con otra huella digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Demasiada luz"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia ligeramente el dedo de posición cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Huella digital no reconocida"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Mantén pulsado firmemente el sensor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Se ha autenticado la huella digital"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Cara autenticada"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Se ha autenticado la cara, pulsa para confirmar"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite vincular con la interfaz de nivel superior del servicio de mensajería de un operador. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular con servicios de operador"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permite vincular con servicios de operador. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"acceso a No molestar"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite que la aplicación lea y modifique la configuración de No molestar."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso de permiso de visualización"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que el titular inicie el uso de permisos de una aplicación. Las aplicaciones normales no deberían necesitar nunca este permiso."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"iniciar la revisión de decisiones sobre los permisos"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Saltar"</string>
     <string name="no_matches" msgid="6472699895759164599">"No hay coincidencias."</string>
     <string name="find_on_page" msgid="5400537367077438198">"Buscar en la página"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# coincidencia}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Hecho"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Borrando almacenamiento compartido…"</string>
     <string name="share" msgid="4157615043345227321">"Compartir"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Hasta <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Hasta las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próxima alarma)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Hasta que lo desactives"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Hasta que desactives la opción No molestar"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Contraer"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"No molestar"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Periodo de descanso"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noche de entre semana"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Las llamadas y las notificaciones vibrarán"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Las llamadas y las notificaciones se silenciarán"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Cambios del sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"No molestar"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novedad: El modo No molestar oculta las notificaciones"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Toca para obtener más información y hacer cambios."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ha cambiado el modo No molestar"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toca para consultar lo que se está bloqueando."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Ajustes"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Aceptar"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desactivar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas sustituyen a las notificaciones adaptativas en Android 12. Esta nueva función te sugiere acciones y respuestas, y organiza tus notificaciones.\n\nLa función puede acceder al contenido de tus notificaciones, incluida información personal, como nombres de contactos y mensajes. También puede cerrar o responder a notificaciones; por ejemplo, puede contestar llamadas telefónicas y controlar el modo No molestar."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación sobre el modo rutina"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Quizás se agote la batería antes de lo habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se ha activado el modo Ahorro de batería para aumentar la duración de la batería"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mensaje traducido del <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> al <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Actividad en segundo plano"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Actividad en segundo plano"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano y consumiendo batería. Toca para revisarlo."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando en segundo plano y agotando batería. Toca para revisarlo."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> lleva mucho tiempo ejecutándose en segundo plano. Toca para revisarlo."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Consultar aplicaciones activas"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"No se puede acceder a la cámara desde este dispositivo"</string>
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 8c2e458..a3bdfc9 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Kolmesuunaline kõne"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Soovimatute tüütute kõnede hülgamine"</string>
     <string name="CndMmi" msgid="185136449405618437">"Helistaja numbri kohaletoimetamine"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Mitte häirida"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Helistaja ID vaikimisi piiratud. Järgmine kõne: piiratud"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Helistaja ID vaikimisi piiratud. Järgmine kõne: pole piiratud"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Vaikimisi pole helistaja ID piiratud. Järgmine kõne: piiratud"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"juurdepääs kalendrile"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"saata ja vaadata SMS-sõnumeid"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Failid ja dokumendid"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"juurdepääs teie seadmes olevatele failidele ja dokumentidele"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muusika ja muud helifailid"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pääseda juurde teie seadmes olevatele helifailidele"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotod ja videod"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jätkamiseks sisestage oma ekraanilukk"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Tuvastati osaline sõrmejälg"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sõrmejälge ei õnnestunud töödelda. Proovige uuesti."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Puhastage sõrmejäljeandur ja proovige uuesti"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Puhastage andur ja proovige uuesti"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Vajutage tugevalt andurile"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Sõrm liikus liiga aeglaselt. Proovige uuesti."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proovige teist sõrmejälge"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liiga ere"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Muutke iga kord pisut oma sõrme asendit"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Sõrmejälge ei tuvastatud"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Vajutage tugevalt andurile"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sõrmejälg autenditi"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Nägu on autenditud"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Nägu on autenditud, vajutage käsku Kinnita"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Lubab omanikul luua seose operaatori sõnumisideteenuse ülataseme liidesega. Pole kunagi vajalik tavalise rakenduse puhul."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"sidumine operaatoriteenustega"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Lubab omanikul siduda operaatoriteenustega. Seda ei tohiks tavarakenduste puhul kunagi tarvis minna."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"juurdepääs funktsioonile Mitte segada"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Võimaldab rakendusel lugeda ja kirjutada funktsiooni Mitte segada seadistusi."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"vaatamisloa kasutamise alustamine"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Võimaldab omanikul rakenduse puhul alustada loa kasutamist. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"Alustada lubade otsuste vaatamist."</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Jäta vahele"</string>
     <string name="no_matches" msgid="6472699895759164599">"Vasted puuduvad"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Otsige lehelt"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# vaste}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Valmis"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Jagatud salvestusruumi tühjendamine …"</string>
     <string name="share" msgid="4157615043345227321">"Jaga"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (järgmine äratus)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Kuni välja lülitate"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Kuni lülitate välja valiku Mitte segada"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Ahendamine"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Mitte segada"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Puhkeaeg"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Argiõhtu"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Nädalavahetus"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Kõnede ja märguannete puhul seade vibreerib"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Kõned ja märguanded on vaigistatud"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Süsteemi muudatused"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Mitte segada"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Uus: režiim Mitte segada peidab märguandeid"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Puudutage lisateabe vaatamiseks ja muutmiseks."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režiimi Mitte segada muudeti"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Puudutage, et kontrollida, mis on blokeeritud."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Süsteem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Seaded"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Lülita välja"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lisateave"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Androidi versioonis 12 asendasid täiustatud märguanded Androidi kohanduvad märguanded. See funktsioon näitab soovitatud toiminguid ja vastuseid ning korrastab teie märguandeid.\n\nTäiustatud märguanded pääsevad juurde märguande sisule, sh isiklikule teabele, nagu kontaktide nimed ja sõnumid. Samuti saab selle funktsiooni abil märguannetest loobuda või neile vastata (nt vastata telefonikõnedele ja juhtida funktsiooni Mitte segada)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutiinirežiimi teabe märguanne"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Aku võib enne tavapärast laadimist tühjaks saada"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akusäästja aktiveeriti aku tööea pikendamiseks"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> töötab taustal ja kulutab akut. Puudutage ülevaatamiseks."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> on taustal töötanud kaua aega. Puudutage ülevaatamiseks."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vaadake aktiivseid rakendusi"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Sellest seadmest ei pääse kaamerale juurde"</string>
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 4c07e40..b0097b4 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Hiru hizlaritako deiak"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Nahigabeko dei gogaikarriak ukatzea"</string>
     <string name="CndMmi" msgid="185136449405618437">"Deitzailearen zenbakia ematea"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ez molestatzeko modua"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Deien identifikazio-zerbitzuaren balio lehenetsiak murriztapenak ezartzen ditu. Hurrengo deia: murriztapenekin"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Deien identifikazio-zerbitzuaren balio lehenetsiak murriztapenak ezartzen ditu. Hurrengo deia: murriztapenik gabe"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Deien identifikazio-zerbitzuaren balio lehenetsiak ez du murriztapenik ezartzen. Hurrengo deia: murriztapenekin"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"atzitu egutegia"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMSak"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"bidali eta ikusi SMS mezuak"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fitxategiak eta dokumentuak"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"gailuko fitxategiak eta dokumentuak atzitu"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musika eta bestelako audioa"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"atzitu gailuko audio-fitxategiak"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Argazkiak eta bideoak"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Aurrera egiteko, desblokeatu pantailaren blokeoa"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Hatz-marka ez da osorik hauteman"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ezin izan da prozesatu hatz-marka. Saiatu berriro."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Garbitu hatz-marken sentsorea eta saiatu berriro"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Garbitu sentsorea eta saiatu berriro"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sakatu irmo sentsorea"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Mantsoegi mugitu duzu hatza. Saiatu berriro."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Erabili beste hatz-marka bat"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Argi gehiegi dago"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Aldi bakoitzean, aldatu hatzaren posizioa apur bat"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Ez da ezagutu hatz-marka"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sakatu irmo sentsorea"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentifikatu da hatz-marka"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Autentifikatu da aurpegia"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autentifikatu da aurpegia; sakatu Berretsi"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Operadore baten mezularitza-zerbitzuaren goi-mailako interfazeari lotzea baimentzen die erabiltzaileei. Aplikazio normalek ez lukete inoiz beharko."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"lotu operadorearen zerbitzuei"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Operadorearen zerbitzuei lotzea baimentzen die titularrei. Aplikazio normalek ez dute baimen hau behar."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"atzitu ez molestatzeko modua"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ez molestatzeko moduaren konfigurazioa irakurtzeko eta bertan idazteko baimena ematen die aplikazioei."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"hasi ikusteko baimena erabiltzen"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Aplikazioaren baimena erabiltzen hasteko baimena ematen die titularrei. Aplikazio normalek ez lukete beharko."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"hasi baimenen inguruko erabakiak ikusten"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Saltatu"</string>
     <string name="no_matches" msgid="6472699895759164599">"Ez dago emaitzarik"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Aurkitu orri honetan"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# emaitza}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Eginda"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Biltegi partekatuko eduki guztia ezabatzen…"</string>
     <string name="share" msgid="4157615043345227321">"Partekatu"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte (hurrengo alarma)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Zuk desaktibatu arte"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Ez molestatzeko modua desaktibatzen duzun arte"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Tolestu"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ez molestatzeko modua"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Jarduerarik gabeko denbora"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Lanegunetako gaua"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Asteburua"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Dar-dar egingo du deiak eta jakinarazpenak jasotzean"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Ez da joko tonurik deiak eta jakinarazpenak jasotzean"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistema-aldaketak"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ez molestatzeko modua"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Berria: Ez molestatzeko modua jakinarazpenak ezkutatzen ari da"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Sakatu informazio gehiago lortzeko eta portaera aldatzeko."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ez molestatzeko modua aldatu da"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Sakatu zer dagoen blokeatuta ikusteko."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Ezarpenak"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Ados"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desaktibatu"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lortu informazio gehiago"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-n, jakinarazpen hobetuek ordeztu dituzte Android-eko jakinarazpen egokituak. Eginbide horrek, iradokitako ekintzak eta erantzunak erakusten, eta zure jakinarazpenak antolatzen ditu.\n\nJakinarazpen hobetuek jakinarazpenen eduki osoa atzi dezakete, informazio pertsonala barne (esaterako, kontaktuen izenak eta mezuak). Halaber, eginbideak jakinarazpenak baztertu, edo haiei erantzun diezaieke; adibidez, telefono-deiei erantzun diezaieke, eta ez molestatzeko modua kontrolatu."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ohitura moduaren informazio-jakinarazpena"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baliteke bateria ohi baino lehenago agortzea"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Bateria-aurrezlea aktibatuta dago bateriaren iraupena luzatzeko"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> hizkuntzatik <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> hizkuntzara itzuli da mezua."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Atzeko planoko jarduerak"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Atzeko planoko jarduerak"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> atzeko planoan exekutatzen eta bateria xahutzen ari da. Sakatu berrikusteko."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g>, atzeko planoan exekutatzen, eta bateria xahutzen ari da. Sakatu berrikusteko."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> aplikazioak denbora asko darama atzeko planoan exekutatzen. Sakatu berrikusteko."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ikusi zer aplikazio dauden aktibo"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ezin da atzitu kamera gailu honetatik"</string>
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 9b35e07..5734803 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"سه روش برقراری تماس"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"رد تماس‌های ناخواسته و آزار دهنده"</string>
     <string name="CndMmi" msgid="185136449405618437">"تحویل شماره تماس"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"مزاحم نشوید"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"پیش‌فرض شناسه تماس‌گیرنده روی محدود است. تماس بعدی: محدود"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"پیش‌فرض شناسه تماس‌گیرنده روی محدود است. تماس بعدی: بدون محدودیت"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"پیش‌فرض شناسه تماس‌گیرنده روی غیرمحدود است. تماس بعدی: محدود"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"دسترسی به تقویم شما"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"پیامک"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ارسال و مشاهده پیامک‌ها"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"فایل‌ها و اسناد"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"دسترسی به فایل‌ها و اسناد موجود در دستگاه"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"موسیقی و فایل‌های صوتی دیگر"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"دسترسی به فایل‌های صوتی موجود در دستگاه"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"عکس‌ها و ویدیوها"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"برای ادامه، قفل صفحه‌تان را وارد کنید"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"بخشی از اثر انگشت شناسایی شد"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"اثرانگشت پردازش نشد. لطفاً دوباره امتحان کنید."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"حسگر اثر انگشت را تمیز و دوباره امتحان کنید"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"حسگر را تمیز و دوباره امتحان کنید"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"محکم روی حسگر فشار دهید"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"حرکت انگشت خیلی آهسته بود. لطفاً دوباره امتحان کنید."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"اثر انگشت دیگری را امتحان کنید"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"خیلی روشن است"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"هربار موقعیت انگشتتان را کمی تغییر دهید"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"اثر انگشت تشخیص داده نشد"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"محکم روی حسگر فشار دهید"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"اثر انگشت اصالت‌سنجی شد"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"چهره اصالت‌سنجی شد"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"چهره اصالت‌سنجی شد، لطفاً تأیید را فشار دهید"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"به کنترل‌کننده اجازه می‌دهد که به سطح بالای میانای کاربر سرویس پیام‌رسانی شرکت مخابراتی مقید شود. هرگز نباید برای برنامه‌های عادی مورد نیاز شود."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"اتصال به سرویس‌های شرکت مخابراتی"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"به دارنده امکان می‌دهد به سرویس‌های شرکت مخابراتی متصل شود. هرگز نباید برای برنامه‌های عادی مورد نیاز باشد."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"دسترسی به حالت «مزاحم نشوید»"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"به برنامه امکان می‌دهد پیکربندی «مزاحم نشوید» را بخواند و بنویسد."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"شروع مشاهده استفاده از مجوز"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"به دارنده اجازه شروع استفاده از مجوز را برای برنامه می‌دهد. هرگز برای برنامه‌های معمول نیاز نیست."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"شروع مشاهده تصمیم‌های مربوط به اجازه‌ها"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"رد شدن"</string>
     <string name="no_matches" msgid="6472699895759164599">"مورد منطبقی موجود نیست"</string>
     <string name="find_on_page" msgid="5400537367077438198">"یافتن در صفحه"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# مورد منطبق}one{# از {total}}other{# از {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"تمام"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"درحال پاک کردن فضای ذخیره‌سازی هم‌رسانی‌شده…"</string>
     <string name="share" msgid="4157615043345227321">"هم‌رسانی"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (زنگ بعدی)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"تا زمانی‌که آن را خاموش کنید"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"تا زمانی که «مزاحم نشوید» را خاموش کنید"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> /‏ <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"کوچک کردن"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"مزاحم نشوید"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"فرویش"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"شب آخر هفته"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"آخر هفته"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"دستگاهتان برای تماس‌ها و اعلان‌ها می‌لرزد"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"دستگاهتان برای تماس‌ها و اعلان‌ها بی‌صدا خواهد شد"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"تغییرات سیستم"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"مزاحم نشوید"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"جدید: «مزاحم نشوید» اعلان‌ها را پنهان می‌کند"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"برای اطلاعات بیشتر و تغییر دادن، ضربه بزنید."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"«مزاحم نشوید» تغییر کرده است"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"برای بررسی موارد مسدودشده ضربه بزنید."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"سیستم"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"تنظیمات"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"تأیید"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"خاموش کردن"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"بیشتر بدانید"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏در Android نسخه ۱۲، اعلان‌های بهبودیافته جایگزین «اعلان‌های تطبیقی» شده است. این ویژگی پاسخ‌ها و کنش‌های پیشنهادی را نمایش می‌دهد و اعلان‌هایتان را سازمان‌دهی می‌کند.\n\nاعلان‌های بهبودیافته می‌توانند به محتوای اعلان، ازجمله اطلاعات شخصی مثل نام‌ها و پیام‌های مخاطبین دسترسی داشته باشند. این ویژگی همچنین می‌تواند اعلان‌ها را رد کند یا به آن‌ها پاسخ دهد؛ مثلاً پاسخ به تماس‌های تلفنی و کنترل کردن «مزاحم نشوید»."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"اعلان اطلاعات حالت روال معمول"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ممکن است شارژ باتری قبل از شارژ معمول تمام شود"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"جهت افزایش عمر باتری، «بهینه‌سازی باتری» فعال شد"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیام از <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> به <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ترجمه شد."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"فعالیت در پس‌زمینه"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"فعالیت در پس‌زمینه"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> در پس‌زمینه اجرا می‌شود و شارژ باتری را تخلیه می‌کند. برای مرور، ضربه بزنید."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"‫<xliff:g id="APP">%1$s</xliff:g> در پس‌زمینه اجرا می‌شود و شارژ باتری را تخلیه می‌کند. برای مرور، ضربه بزنید."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> برای مدتی طولانی در پس‌زمینه اجرا می‌شود. برای مرور، ضربه بزنید."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"بررسی برنامه‌های فعال"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"نمی‌توان از این دستگاه به دوربین دسترسی پیدا کرد"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 10adae8..0348505 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Kolmisuuntainen puhelu"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Ei-toivottujen ja ärsyttävien puheluiden hylkääminen"</string>
     <string name="CndMmi" msgid="185136449405618437">"Soittajan numeron näyttäminen"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Älä häiritse"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Soittajan tunnukseksi muutetaan rajoitettu. Seuraava puhelu: rajoitettu"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Soittajan tunnukseksi muutetaan rajoitettu. Seuraava puhelu: ei rajoitettu"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Soittajan tunnukseksi muutetaan rajoittamaton. Seuraava puhelu: rajoitettu"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"käyttää kalenteria"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Tekstiviestit"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"lähettää ja tarkastella tekstiviestejä"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Tiedostot ja dokumentit"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"pääsyn laitteesi tiedostoihin ja dokumentteihin"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiikki ja muu audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pääsy laitteesi audiotiedostoihin"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Kuvat ja videot"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Jatka lisäämällä näytön lukituksen avaustapa"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Osittainen sormenjälki havaittu"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Sormenjäljen prosessointi epäonnistui. Yritä uudelleen."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Puhdista sormenjälkitunnistin ja yritä uudelleen"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Puhdista anturi ja yritä uudelleen"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Paina anturia voimakkaasti"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Liikutit sormea liian hitaasti. Yritä uudelleen."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Kokeile toista sormenjälkeä"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Liian kirkas"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Liikuta sormeasi hieman joka kerralla"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Sormenjälkeä ei tunnistettu"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Paina anturia voimakkaasti"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sormenjälki tunnistettu"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Kasvot tunnistettu"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Kasvot tunnistettu, valitse Vahvista"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Antaa sovelluksen sitoutua operaattorin viestipalvelun ylätason liittymään. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"Luo sidos operaattorin palveluun"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Antaa sovelluksen luoda sidoksen operaattorin palveluun. Ei tavallisten sovelluksien käyttöön."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Älä häiritse -tilan käyttöoikeus"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Sallii sovelluksen lukea ja muokata Älä häiritse -tilan asetuksia."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"aloita katseluoikeuksien käyttö"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Antaa luvanhaltijan käynnistää sovelluksen käyttöoikeuksien käytön. Ei tavallisten sovelluksien käyttöön."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"aloita lupapäätösten tarkistaminen"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Ohita"</string>
     <string name="no_matches" msgid="6472699895759164599">"Ei tuloksia"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Etsi sivulta"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# osuma}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Valmis"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Tyhjennetään jaettua tallennustilaa…"</string>
     <string name="share" msgid="4157615043345227321">"Jaa"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Kunnes kello on <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> asti (seuraava hälytys)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Kunnes laitat pois päältä"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Kunnes poistat Varattu-tilan käytöstä."</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Kutista"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Älä häiritse"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Vapaalla"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Arki-iltaisin"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Viikonloppuna"</string>
@@ -1960,7 +1957,7 @@
     <string name="demo_restarting_message" msgid="1160053183701746766">"Palautetaan asetuksia…"</string>
     <string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> ei ole käytössä."</string>
     <string name="conference_call" msgid="5731633152336490471">"Puhelinneuvottelu"</string>
-    <string name="tooltip_popup_title" msgid="7863719020269945722">"Työkaluvinkki"</string>
+    <string name="tooltip_popup_title" msgid="7863719020269945722">"Vihjeteksti"</string>
     <string name="app_category_game" msgid="4534216074910244790">"Pelit"</string>
     <string name="app_category_audio" msgid="8296029904794676222">"Musiikki ja ääni"</string>
     <string name="app_category_video" msgid="2590183854839565814">"Elokuvat ja videot"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Puhelut ja ilmoitukset värisevät"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Puhelut ja ilmoitukset mykistetään"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Järjestelmän muutokset"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Älä häiritse"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Uutta: Älä häiritse ‑tila piilottaa ilmoitukset"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Napauta, jos haluat lukea lisää ja tehdä muutoksia."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Älä häiritse ‑tila muuttui"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Napauta niin näet, mitä on estetty."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Järjestelmä"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Asetukset"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Laita pois päältä"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Lue lisää"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Parannetut ilmoitukset korvasivat Androidin mukautuvat ilmoitukset Android 12:ssa. Tämä ominaisuus näyttää toiminto- ja vastausehdotuksia ja järjestää ilmoituksesi.\n\nParannetuilla ilmoituksilla on pääsy kaikkeen ilmoitussisältöön, myös henkilökohtaisiin tietoihin (esim. kontaktien nimet ja viestit). Ominaisuus voi myös ohittaa ilmoituksia tai vastata niihin, esim. vastata puheluihin ja ohjata Älä häiritse ‑tilaa."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ohjelmatilan tietoilmoitus"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akku saattaa loppua ennen normaalia latausaikaa"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Virransäästö otettu käyttöön akunkeston pidentämiseksi"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> on käynnissä taustalla ja kuluttaa akkua. Tarkista napauttamalla."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> on ollut käynnissä taustalla pitkän aikaa. Tarkista napauttamalla."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tarkista aktiiviset sovellukset"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ei pääsyä kameraan tältä laitteelta"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 43b061d..b877da2 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Conférence téléphonique à trois"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejeter les appels indésirables"</string>
     <string name="CndMmi" msgid="185136449405618437">"Livraison du numéro d\'appel"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne pas déranger"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : restreint"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : non restreint"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : restreint"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Messagerie texte"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et afficher des messages texte"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fichiers et documents"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"accédez aux fichiers et aux documents sur votre appareil"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musique et autres fichiers audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accéder aux fichiers audio de votre appareil"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos et vidéos"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autorisez l\'application à déterminer la position relative entre des appareils à bande ultralarge à proximité"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'application d\'annoncer, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'application de diffuser des annonces, de se connecter et de déterminer la position relative des appareils Wi-Fi à proximité"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Information sur le service préféré de paiement CCP"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir de l\'information sur le service préféré de paiement CCP comme les aides enregistrées et la route de destination."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"gérer la communication en champ proche"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Entrez votre verrouillage d\'écran pour continuer"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Empreinte digitale partielle détectée"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le capteur d\'empreintes digitales et réessayez"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le capteur et réessayez"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez fermement sur le capteur"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte digitale"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop lumineux"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Modifiez légèrement la position de votre doigt chaque fois"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Empreinte digitale non reconnue"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Appuyez fermement sur le capteur"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Visage authentifié"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur le bouton Confirmer"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service de messagerie d\'un fournisseur. Les applications standards ne devraient jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"s\'associer aux services d\'un fournisseur"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permet à l\'application autorisée de s\'associer aux services d\'un fournisseur. Ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"accéder au mode Ne pas déranger"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"démarrer l\'affichage de l\'usage des autorisations"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet au détenteur de démarrer l\'usage des autorisations pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"démarrer les décisions d\'autorisation de lecture"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Ignorer"</string>
     <string name="no_matches" msgid="6472699895759164599">"Aucune partie"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# correspondance}one{# sur {total}}other{# sur {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Terminé"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Effacement du stockage partagé en cours…"</string>
     <string name="share" msgid="4157615043345227321">"Partager"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarme suivante)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Jusqu\'à la désactivation"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Jusqu\'à ce que vous désactiviez le mode « Ne pas déranger »"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Réduire"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne pas déranger"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Temps d\'arrêt"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Soirs de semaine"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semaine"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Les appels et les notifications vibreront"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Les appels et les notifications seront silencieux"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Changements système"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne pas déranger"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nouveau : Le mode Ne pas déranger masque les notifications"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Touchez ici pour en savoir plus et changer les paramètres"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Les paramètres du mode Ne pas déranger ont changé"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Touchez l\'écran pour vérifier ce qui est bloqué."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Système"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Paramètres"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Désactiver"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notifications améliorées ont remplacé les notifications adaptatives Android sous Android 12. Cette fonctionnalité vous présente des suggestions d\'actions et de réponses, et organise vos notifications.\n\nLes notifications améliorées peuvent accéder au contenu de toutes les notifications, y compris les renseignements personnels comme le nom des contacts et les messages. Cette fonctionnalité peut aussi fermer des notifications ou interagir avec elles, comme répondre aux appels téléphoniques et gérer le mode Ne pas déranger."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"La pile pourrait s\'épuiser avant la charge habituelle"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Le mode Économiseur de pile est activé afin de prolonger l\'autonomie"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Message traduit : <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> vers <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Activité en arrière-plan"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Activité en arrière-plan"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan et décharge rapidement la pile. Touchez pour examiner."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan et décharge la pile. Touchez pour examiner."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan depuis longtemps. Touchez pour examiner."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applications actives"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Impossible d\'accéder à l\'appareil photo à partir de cet appareil"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 7770aed..f73398e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Conférence téléphonique à trois"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejeter les appels indésirables"</string>
     <string name="CndMmi" msgid="185136449405618437">"Livraison du numéro d\'appel"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne pas déranger"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : restreint"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : non restreint"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Par défaut, les numéros des appelants ne sont pas restreints. Appel suivant : restreint"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"accéder à votre agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envoyer et consulter des SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fichiers et documents"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"accéder aux fichiers et documents sur votre appareil"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musique et autres contenus audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"accès aux fichiers audio sur votre appareil"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Photos et vidéos"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"déterminer position relative entre appareils ultra-wideband à proximité"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Autoriser l\'appli à déterminer la position relative entre des appareils ultra-wideband à proximité"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir avec les appareils Wi-Fi à proximité"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de déterminer la position relative des appareils Wi‑Fi à proximité, vous en informer et s\'y connecter"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permet à l\'appli de déterminer la position approximative des appareils Wi‑Fi à proximité, de les afficher et de s\'y connecter"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informations sur le service de paiement NFC préféré"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permet à l\'application d\'obtenir des informations sur le service de paiement NFC préféré, y compris les ID d\'applications et les destinations de routage enregistrés."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"contrôler la communication en champ proche"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Utilisez le verrouillage de l\'écran pour continuer"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Empreinte partielle détectée"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Impossible de reconnaître l\'empreinte digitale. Veuillez réessayer."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Nettoyez le lecteur d\'empreinte digitale et réessayez"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Nettoyez le lecteur et réessayez"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Appuyez bien sur le lecteur"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vous avez déplacé votre doigt trop lentement. Veuillez réessayer."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Essayez une autre empreinte"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Trop de lumière"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Changez légèrement de position chaque fois"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Empreinte digitale non reconnue"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Appuyez bien sur le lecteur"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Empreinte digitale authentifiée"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Visage authentifié"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Visage authentifié, veuillez appuyer sur \"Confirmer\""</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permettre à l\'application de s\'associer à l\'interface de niveau supérieur du service SMS/MMS d\'un opérateur. Ne devrait jamais être nécessaire pour les applications standards."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"associer aux services de l\'opérateur"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permet à l\'application autorisée de s\'associer aux services d\'un opérateur. Ne devrait pas être nécessaire pour les applications standards."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"accéder au mode Ne pas déranger"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permet à l\'application de consulter et de modifier la configuration du mode Ne pas déranger."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"activer l\'utilisation de l\'autorisation d\'affichage"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permet à l\'application autorisée d\'activer l\'utilisation de l\'autorisation pour une application. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"activer l\'affichage des décisions liées aux autorisations"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Ignorer"</string>
     <string name="no_matches" msgid="6472699895759164599">"Aucune correspondance"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# correspondance}one{# sur {total}}other{# sur {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"OK"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Suppression de l\'espace de stockage partagé…"</string>
     <string name="share" msgid="4157615043345227321">"Partager"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarme suivante)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Jusqu\'à la désactivation"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Jusqu\'à ce que vous désactiviez la fonctionnalité \"Ne pas déranger\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Réduire"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne pas déranger"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Temps d\'arrêt"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Soirée de semaine"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Week-end"</string>
@@ -1967,7 +1964,7 @@
     <string name="app_category_image" msgid="7307840291864213007">"Photos et images"</string>
     <string name="app_category_social" msgid="2278269325488344054">"Réseaux sociaux et communication"</string>
     <string name="app_category_news" msgid="1172762719574964544">"Actualités et magazines"</string>
-    <string name="app_category_maps" msgid="6395725487922533156">"Plans et navigation"</string>
+    <string name="app_category_maps" msgid="6395725487922533156">"Cartes et navigation"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"Productivité"</string>
     <string name="app_category_accessibility" msgid="6643521607848547683">"Accessibilité"</string>
     <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"Mémoire de l\'appareil"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibreur pour les appels et les notifications"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Sons désactivés pour les appels et les notifications"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Modifications du système"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne pas déranger"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nouveau : Le mode Ne pas déranger masque les notifications"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Appuyez pour en savoir plus et pour modifier les paramètres."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Le mode Ne pas déranger a été modifié"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Appuyez pour vérifier les contenus bloqués."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Système"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Paramètres"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Désactiver"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"En savoir plus"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Les notifications améliorées remplacent les notifications intelligentes dans Android 12. Cette fonctionnalité affiche les suggestions d\'actions et de réponses, et organise vos notifications.\n\nElle a accès au contenu des notifications, y compris aux informations personnelles tels que les noms des contacts et les messages. Elle peut aussi fermer les notifications ou effectuer des actions comme répondre à un appel téléphonique et contrôler le mode Ne pas déranger."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification d\'information du mode Routine"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Vous risquez d\'être à court de batterie plus tôt que prévu"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Économiseur de batterie activé pour prolonger l\'autonomie"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan et décharge la batterie. Appuyez ici pour en savoir plus."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> s\'exécute en arrière-plan depuis longtemps. Appuyez ici pour en savoir plus."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Vérifier les applis actives"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Impossible d\'accéder à l\'appareil photo depuis cet appareil"</string>
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 6db4a32..dfc6e69 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Chamada a tres"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rexeitamento de chamadas molestas non desexadas"</string>
     <string name="CndMmi" msgid="185136449405618437">"Entrega de número de chamada entrante"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Non molestar"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"O valor predeterminado do identificador de chamada é restrinxido. Próxima chamada: restrinxido"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"O valor predeterminado do identificador de chamada é restrinxido. Próxima chamada: non restrinxido"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"O valor predeterminado do identificador de chamada é non restrinxido. Próxima chamada: restrinxido"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acceder ao teu calendario"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e consultar mensaxes de SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Ficheiros e documentos"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"acceder a ficheiros e documentos do dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outro contido de audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acceder a ficheiros de audio do teu dispositivo"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Desbloquea a pantalla para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Detectouse unha impresión dixital parcial"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Non se puido procesar a impresión dixital. Téntao de novo."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpa o sensor de impresión dixital e téntao de novo"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpa o sensor e téntao de novo"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Preme o sensor con firmeza"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O dedo moveuse demasiado lento. Téntao de novo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Proba con outra impresión dixital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Hai demasiada luz"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Cambia lixeiramente a posición do dedo en cada intento"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Non se recoñeceu a impresión dixital"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Preme o sensor con firmeza"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autenticouse a impresión dixital"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Autenticouse a cara"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Autenticouse a cara, preme Confirmar"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite ao propietario vincularse á interface de nivel superior dun servizo de mensaxaría. As aplicacións normais non deberían necesitar este permiso."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular aos servizos do operador"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permite ao titular vincularse aos servizos do operador. As aplicacións normais non deberían necesitar este permiso."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"acceso a Non molestar"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite á aplicación ler e escribir a configuración do modo Non molestar."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso de permiso de vista"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite ao propietario iniciar o uso de permisos dunha aplicación. As aplicacións normais non deberían precisalo nunca."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"iniciar vista das decisións sobre os permisos"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Omitir"</string>
     <string name="no_matches" msgid="6472699895759164599">"Non hai coincidencias"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Buscar na páxina"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# coincidencia}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Feito"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Borrando almacenamento compartido…"</string>
     <string name="share" msgid="4157615043345227321">"Compartir"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próxima alarma)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Ata a desactivación"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Ata que desactives o modo Non molestar"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Contraer"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Non molestar"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Tempo de descanso"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noite da semana"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fin de semana"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"As chamadas e as notificacións vibrarán"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"As chamadas e as notificacións estarán silenciadas"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Cambios no sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Non molestar"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novidade! O modo Non molestar oculta as notificacións"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Toca para obter máis información e facer cambios."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo Non molestar cambiou"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toca para comprobar o contido bloqueado."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Configuración"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Aceptar"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desactivar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Máis información"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"En Android 12, as notificacións melloradas substitúen as notificacións intelixentes. Esta función ofréceche suxestións de accións e respostas, ademais de organizar as notificacións.\n\nEste servizo pode acceder ao contido das notificacións, mesmo á información persoal, como os nomes dos contactos e as mensaxes. Ademais, esta función pode ignorar ou responder as notificacións (por exemplo, coller chamadas telefónicas e controlar o modo Non molestar)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación da información do modo de rutina"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A batería pode esgotarse antes do habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Para ampliar a duración da batería activouse a función Aforro de batería"</string>
@@ -2102,11 +2103,11 @@
     <string name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" msgid="1057878690209817886">"Selector de atallos de accesibilidade en pantalla"</string>
     <string name="accessibility_system_action_hardware_a11y_shortcut_label" msgid="5764644187715255107">"Atallo de accesibilidade"</string>
     <string name="accessibility_system_action_dismiss_notification_shade" msgid="8931637495533770352">"Ignorar panel despregable"</string>
-    <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Botón direccional: arriba"</string>
-    <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Botón direccional: abaixo"</string>
-    <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Botón direccional: esquerda"</string>
-    <string name="accessibility_system_action_dpad_right_label" msgid="9180196950365804081">"Botón direccional: dereita"</string>
-    <string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Botón direccional: centro"</string>
+    <string name="accessibility_system_action_dpad_up_label" msgid="1029042950229333782">"Cruceta: arriba"</string>
+    <string name="accessibility_system_action_dpad_down_label" msgid="3441918448624921461">"Cruceta: abaixo"</string>
+    <string name="accessibility_system_action_dpad_left_label" msgid="6557647179116479152">"Cruceta: esquerda"</string>
+    <string name="accessibility_system_action_dpad_right_label" msgid="9180196950365804081">"Cruceta: dereita"</string>
+    <string name="accessibility_system_action_dpad_center_label" msgid="8149791419358224893">"Cruceta: centro"</string>
     <string name="accessibility_freeform_caption" msgid="8377519323496290122">"Barra de subtítulos de <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> incluíuse no grupo RESTRINXIDO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está executándose en segundo plano e consumindo batería. Toca para revisalo."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> leva moito tempo executándose en segundo plano. Toca para revisalo."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Comprobar aplicacións activas"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Non se pode acceder á cámara desde este dispositivo"</string>
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index fe1b92b..3cd24d2 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"ત્રણ રીતે કૉલિંગ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"અનિચ્છિત પજવણીકારક કૉલ્સનો અસ્વીકાર"</string>
     <string name="CndMmi" msgid="185136449405618437">"કૉલિંગ નંબર વિતરણ"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ખલેલ પાડશો નહીં"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"કૉલર ID પ્રતિબંધિત પર ડિફોલ્ટ છે. આગલો કૉલ: પ્રતિબંધિત છે"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"કૉલર ID પ્રતિબંધિત પર ડિફોલ્ટ છે. આગલો કૉલ: પ્રતિબંધિત નહીં"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"કૉલર ID પ્રતિબંધિત નહીં પર ડિફોલ્ટ છે. આગલો કૉલ: પ્રતિબંધિત"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"તમારા કેલેન્ડરને ઍક્સેસ કરવાની"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS સંદેશા મોકલવાની અને જોવાની"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"ફાઇલો અને દસ્તાવેજો"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"તમારા ડિવાઇસ પર ફાઇલો અને દસ્તાવેજો ઍક્સેસ કરો"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"મ્યુઝિક અને અન્ય ઑડિયો"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"તમારા ડિવાઇસ પર ઑડિયો ફાઇલો ઍક્સેસ કરવા માટે"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ફોટા અને વીડિયો"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"આગળ વધવા માટે તમારું સ્ક્રીન લૉક દાખલ કરો"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"આંશિક ફિંગરપ્રિન્ટ મળી"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ફિંગરપ્રિન્ટ પ્રક્રિયા કરી શકાઈ નથી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ફિંગરપ્રિન્ટ સેન્સર સાફ કરો અને ફરી પ્રયાસ કરો"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"સેન્સર સાફ કરો અને ફરી પ્રયાસ કરો"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"સેન્સર પર જોરથી દબાવો"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"આંગળી બહુ જ ધીમેથી ખસેડી. કૃપા કરીને ફરી પ્રયાસ કરો."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"અન્ય ફિંગરપ્રિન્ટ અજમાવી જુઓ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"અતિશય પ્રકાશિત"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"દરેક વખતે સ્કૅનર પર તમારી આંગળીની સ્થિતિ સહેજ બદલતા રહો"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ફિંગરપ્રિન્ટ ઓળખી શકાઈ નથી"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"સેન્સર પર જોરથી દબાવો"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ફિંગરપ્રિન્ટ પ્રમાણિત કરી"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ચહેરા પ્રમાણિત"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ચહેરા પ્રમાણિત, કૃપા કરીને કન્ફર્મ કરો"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ધારકને કેરીઅર મેસેજિંગ સેવાના ઉચ્ચ-સ્તર ઇન્ટરફેસથી પ્રતિબદ્ધ થવાની મંજૂરી આપે છે. સામાન્ય ઍપ્લિકેશનો માટે ક્યારેય જરૂરી હોતું નથી."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"કેરીઅર સેવાઓથી પ્રતિબદ્ધ થાઓ"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"ધારકને કેરીઅર સેવાઓ સાથે પ્રતિબદ્ધ થવાની મંજૂરી આપે છે. સામાન્ય ઍપ્લિકેશનો માટે ક્યારેય જરૂરી હોતું નથી."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"ખલેલ પાડશો નહીં ઍક્સેસ કરો"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"એપ્લિકેશનને ખલેલ પાડશો નહીં ગોઠવણી વાંચવા અને લખવાની મંજૂરી આપે છે."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"પરવાનગી વપરાશ જુઓને શરૂ કરો"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"કોઈ ઍપ માટે પરવાનગી વપરાશ શરૂ કરવાની ધારકને મંજૂરી આપે છે. સામાન્ય ઍપ માટે ક્યારેય જરૂર પડી ન શકે."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"પરવાનગી સંબંધિત નિર્ણયો જોવાનું શરૂ કરો"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"છોડો"</string>
     <string name="no_matches" msgid="6472699895759164599">"કોઈ મેળ નથી"</string>
     <string name="find_on_page" msgid="5400537367077438198">"પૃષ્ઠ પર શોધો"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# મૅચ}one{{total}માંથી #}other{{total}માંથી #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"થઈ ગયું"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"શેર કરેલ સ્ટોરેજ ભૂસી રહ્યાં છીએ…"</string>
     <string name="share" msgid="4157615043345227321">"શેર કરો"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> સુધી"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (આગલા એલાર્મ) સુધી"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"તમે બંધ ન કરો ત્યાં સુધી"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"તમે ખલેલ પાડશો નહીં બંધ ન કરો ત્યાં સુધી"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"સંકુચિત કરો"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ખલેલ પાડશો નહીં"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ડાઉનટાઇમ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"સપ્તાહાંત રાત્રિ"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"સપ્તાહાંત"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"કૉલ અને નોટિફિકેશન માટે ઉપકરણ વાઇબ્રેટ થશે"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"કૉલ અને નોટિફિકેશન મ્યૂટ કરવામાં આવશે"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"સિસ્ટમના ફેરફારો"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ખલેલ પાડશો નહીં"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"નવું: ખલેલ પાડશો નહીં હવે નોટિફિકેશન છુપાવી શકે છે"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"વધુ જાણવા અને બદલવા માટે ટૅપ કરો."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ખલેલ પાડશો નહીંમાં ફેરફાર થયો છે"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"શું બ્લૉક કરેલ છે તે તપાસવા માટે ટૅપ કરો."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"સિસ્ટમ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"સેટિંગ"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ઓકે"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"બંધ કરો"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"વધુ જાણો"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12માં Android માટે અનુકૂળ નોટિફિકેશનને બદલે વધુ સારા નોટિફિકેશન છે. આ સુવિધા સૂચિત ક્રિયાઓ અને જવાબો બતાવે છે તેમજ તમારા નોટિફિકેશનની યોગ્ય ગોઠવણી કરે છે.\n\nવધુ સારા નોટિફિકેશન સંપર્કોના નામ અને સંદેશા જેવી વ્યક્તિગત માહિતી સહિત નોટિફિકેશનનું બધું કન્ટેન્ટ ઍક્સેસ કરી શકે છે. આ સુવિધા ફોન કૉલના જવાબ આપવા કે \'ખલેલ પાડશો નહીં\'નું નિયંત્રણ કરવા જેવા નોટિફિકેશન છોડવાની કે તેનો જવાબ આપવાની ક્રિયા પણ કરી શકે છે."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"રૂટિન મોડની માહિતીનું નોટિફિકેશન"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"સામાન્ય રીતે ચાર્જ કરવાના સમય પહેલાં બૅટરી સમાપ્ત થઈ શકે છે"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"બૅટરી આવરદા વધારવા માટે બૅટરી સેવર ચાલુ કર્યું"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> બૅકગ્રાઉન્ડમાં ચાલી રહી છે અને અતિશય બૅટરી વાપરી રહી છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> લાંબા સમયથી બૅકગ્રાઉન્ડમાં ચાલી રહી છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"સક્રિય ઍપ ચેક કરો"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"આ ડિવાઇસમાંથી કૅમેરા ઍક્સેસ કરી શકાતો નથી"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 3cf2137..00b29d3 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"त्रिमार्गी कॉलिंग"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"अवांछित कष्टप्रद कॉल की अस्वीकृति"</string>
     <string name="CndMmi" msgid="185136449405618437">"कॉलिंग नंबर वितरण"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"परेशान न करें"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"कॉलर आईडी डिफ़ॉल्ट रूप से सीमित है. अगली कॉल: सीमित"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"कॉलर आईडी डिफ़ॉल्ट रूप से सीमित है. अगली कॉल: सीमित नहीं"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"कॉलर आईडी डिफ़ॉल्ट रूप से सीमित नहीं है. अगली कॉल: सीमित"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"अपने कैलेंडर को ऐक्सेस करें"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"मैसेज (एसएमएस)"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"मैसेज (एसएमएस) भेजें और देखें"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"फ़ाइलें और दस्तावेज़"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"अपने डिवाइस पर मौजूद फ़ाइलें और दस्तावेज़ ऐक्सेस करने की अनुमति दें"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"संगीत और अन्य ऑडियो"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"आपके डिवाइस पर मौजूद, ऑडियो फ़ाइलों का ऐक्सेस"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"फ़ोटो और वीडियो"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"जारी रखने के लिए, अपने स्क्रीन लॉक की पुष्टि करें"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"पूरा फ़िंगरप्रिंट पहचाना नहीं जा सका"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"फ़िंगरप्रिंट प्रोसेस नहीं हो सका. कृपया दोबारा कोशिश करें."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"फ़िंगरप्रिंट सेंसर को साफ़ करके फिर से कोशिश करें"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"सेंसर को उंगली से ज़ोर से दबाएं"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"उंगली बहुत धीरे चलाई गई. कृपया फिर से कोशिश करें."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"किसी दूसरे फ़िंगरप्रिंट से कोशिश करें"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"बहुत रोशनी है"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"फ़िंगरप्रिंट सेट अप करते समय, अपनी उंगली को हर बार थोड़ी अलग स्थिति में रखें"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"फ़िंगरप्रिंट की पहचान नहीं हो पाई"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"सेंसर को उंगली से ज़ोर से दबाएं"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"फ़िंगरप्रिंट की पुष्टि हो गई"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"चेहरे की पहचान की गई"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"चेहरे की पहचान की गई, कृपया पुष्टि बटन दबाएं"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"उपयोगकर्ता को किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी की मैसेज सेवा के सबसे बढ़िया इंटरफ़ेस से जोड़ता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से जुड़ें"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"उपयोगकर्ता को किसी मोबाइल और इंटरनेट सेवा देने वाली कंपनी से जोड़ता है. सामान्‍य ऐप के लिए इसकी कभी ज़रूरत नहीं होती."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"\'परेशान न करें\' को ऐक्सेस करें"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ऐप को परेशान न करें कॉन्फ़िगरेशन पढ़ने और लिखने देती है."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"देखने की अनुमतियां चालू करें"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"इस्तेमाल करने वाले को किसी ऐप्लिकेशन के लिए अनुमतियों का इस्तेमाल शुरू करने देता है. सामान्य ऐप्लिकेशन के लिए इसकी ज़रूरत कभी नहीं पड़ती."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"अनुमतियों को देखना चालू करना"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"अभी नहीं"</string>
     <string name="no_matches" msgid="6472699895759164599">"कोई मिलान नहीं"</string>
     <string name="find_on_page" msgid="5400537367077438198">"पेज पर ढूंढें"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# नतीजा}one{{total} में से #}other{{total} में से #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"हो गया"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"शेयर की गई मेमोरी हमेशा के लिए मिटाई जा रही है…"</string>
     <string name="share" msgid="4157615043345227321">"शेयर करें"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> तक"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (अगले अलार्म) तक"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"जब तक आप बंद नहीं करते"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"जब तक कि आप परेशान ना करें को बंद नहीं कर देते"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"छोटा करें"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"परेशान ना करें"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"बंद रहने का समय"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"हफ़्ते की रात"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"सप्ताहांत"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"कॉल और सूचनाओं के लिए डिवाइस वाइब्रेट हाेगा"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"कॉल और सूचनाओं के लिए डिवाइस म्यूट रहेगा"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"सिस्टम में हुए बदलाव"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"परेशान न करें"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"नई सुविधा: परेशान न करें सुविधा चालू होने की वजह से सूचनाएं नहीं दिखाई जा रही हैं"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ज़्यादा जानने और बदलाव करने के लिए टैप करें."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"परेशान न करें की सुविधा बदल गई है"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"टैप करके देखें कि किन चीज़ों पर रोक लगाई गई है."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"सिस्टम"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"सेटिंग"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"चालू करें"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"बंद करें"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ज़्यादा जानें"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 में, ज़रूरत के हिसाब से सूचनाएं पाने की सुविधा की जगह अब \'बेहतर सूचनाएं\' सुविधा काम करेगी. यह सुविधा आपको कार्रवाइयों और जवाबों के सुझाव दिखाती है. साथ ही, आपके डिवाइस पर मिलने वाली सूचनाओं को व्यवस्थित करती है.\n\n\'बेहतर सूचनाएं\' सुविधा, डिवाइस पर मिलने वाली सभी सूचनाओं का कॉन्टेंट ऐक्सेस कर सकती है. इसमें आपकी निजी जानकारी, जैसे कि संपर्कों के नाम और मैसेज शामिल हैं. यह सुविधा, सूचनाओं को खारिज कर सकती है या उनका जवाब भी दे सकती है, जैसे कि फ़ोन कॉल का जवाब देना और \'परेशान न करें\' को कंट्रोल करना."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"रूटीन मोड जानकारी की सूचना"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"बैटरी आम तौर पर जितने समय चलती है, उससे पहले खत्म हो सकती है"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"बैटरी लाइफ़ बढ़ाने के लिए \'बैटरी सेवर\' चालू हो गया है"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> बैकग्राउंड में चल रहा है और बैटरी खर्च कर रहा है. देखने के लिए टैप करें."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> बैकग्राउंड में बहुत देर से चल रहा है. देखने के लिए टैप करें."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"चालू ऐप्लिकेशन देखें"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"इस डिवाइस से कैमरे का इस्तेमाल नहीं किया जा सकता"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 14139ea..ccbcaaf 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -71,6 +71,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Trostrani poziv"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Odbijanje neželjenih i neugodnih poziva"</string>
     <string name="CndMmi" msgid="185136449405618437">"Isporuka pozivnog broja"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne uznemiravaj"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Zadana postavka ID-a pozivatelja ima ograničenje. Sljedeći poziv: Ograničen"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Zadana postavka ID-a pozivatelja ima ograničenje. Sljedeći poziv: Nije ograničen"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Zadana postavka ID-a pozivatelja nema ograničenje. Sljedeći poziv: Ograničen"</string>
@@ -305,10 +306,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"pristupati kalendaru"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"slati i pregledavati SMS poruke"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Datoteke i dokumenti"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"pristup datotekama i dokumentima na vašem uređaju"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Glazba i druge audiodatoteke"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"pristup audiodatotekama na uređaju"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografije i videozapisi"</string>
@@ -589,12 +588,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrijebite zaključavanje zaslona da biste nastavili"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Otkriven je djelomični otisak prsta"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Obrada otiska prsta nije uspjela. Pokušajte ponovo."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Očistite senzor otiska prsta i pokušajte ponovno"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Očistite senzor i pokušajte ponovno"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Čvrsto pritisnite senzor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Presporo pomicanje prsta. Pokušajte ponovo."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Isprobajte drugi otisak prsta"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Presvijetlo"</string>
@@ -602,10 +598,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Svaki put lagano promijenite položaj prsta"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Otisak prsta nije prepoznat"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Čvrsto pritisnite senzor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Autentificirano otiskom prsta"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Lice je autentificirano"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Lice je autentificirano, pritisnite Potvrdi"</string>
@@ -744,6 +738,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Omogućuje nositelju povezivanje sa sučeljem najviše razine usluge mobilnog operatera za slanje poruka. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"povezivanje s uslugama mobilnog operatera"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Nositelju omogućuje povezivanje s uslugama mobilnog operatera. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"pristupi opciji Ne uznemiravaj"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Omogućuje aplikaciji čitanje i pisanje konfiguracije opcije Ne uznemiravaj."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"pokrenuti upotrebu dopuštenja za pregled"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Dopušta nositelju pokretanje upotrebe dopuštenja za aplikaciju. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"pokrenuti odluke o dopuštenju za pregled"</string>
@@ -1509,8 +1505,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Preskoči"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nema rezultata"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Pronađi na stranici"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# podudaranje}one{# od {total}}few{# od {total}}other{# od {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Gotovo"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Brisanje dijeljene pohrane…"</string>
     <string name="share" msgid="4157615043345227321">"Dijeli"</string>
@@ -1875,8 +1870,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sljedeći alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Dok ne isključite"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dok ne isključite \"Ne uznemiravaj\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Sažmi"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne uznemiravaj"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Prekid rada"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noć radnog dana"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Vikend"</string>
@@ -2041,7 +2038,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Uređaj će vibrirati za pozive i obavijesti"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Zvučni signal poziva i obavijesti bit će isključen"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Promjene sustava"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne uznemiravaj"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: način Ne uznemiravaj sakriva obavijesti"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dodirnite da biste saznali više i promijenili postavke."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Promijenjena je postavka Ne uznemiravaj"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dodirnite da biste provjerili što je blokirano."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sustav"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Postavke"</string>
@@ -2058,6 +2058,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"U redu"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Isključi"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saznajte više"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"U Androidu 12 poboljšane obavijesti zamjenjuju prilagodljive obavijesti za Android. Ta značajka prikazuje predložene radnje i odgovore te organizira vaše obavijesti.\n\nPoboljšane obavijesti mogu pristupiti sadržaju obavijesti, uključujući osobne podatke kao što su imena kontakata i poruke. Ta značajka može i odbacivati obavijesti ili poduzimati radnje u vezi s njima, na primjer može odgovarati na telefonske pozive i upravljati značajkom Ne uznemiravaj."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Obavještavanje o informacijama u Rutinskom načinu rada"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija se može isprazniti prije uobičajenog vremena punjenja"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Štednja baterije aktivirana je kako bi se produljilo trajanje baterije"</string>
@@ -2264,6 +2265,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> izvodi se u pozadini i prazni bateriju. Dodirnite za pregled."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> dugo se izvodi u pozadini. Dodirnite za pregled."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Provjera aktivnih aplikacija"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kameri se ne može pristupiti s ovog uređaja"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f94f063..f901ca6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Háromutas hívás"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"A nem kívánt bosszantó hívások elutasítása"</string>
     <string name="CndMmi" msgid="185136449405618437">"Hívószám-kézbesítés"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne zavarjanak"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"A hívóazonosító alapértelmezett értéke korlátozott. Következő hívás: korlátozott"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"A hívóazonosító alapértelmezett értéke korlátozott. Következő hívás: nem korlátozott"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"A hívóazonosító alapértelmezett értéke nem korlátozott. Következő hívás: korlátozott"</string>
@@ -545,7 +546,7 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Lehetővé teszi az alkalmazás számára, hogy közzétegye jelenlétét a közeli Bluetooth-eszközök számára"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"közeli, ultraszélessávú eszközök közötti relatív pozíció meghatározása"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Az alkalmazás meghatározhatja a közeli, ultraszélessávú eszközök közötti relatív pozíciót"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"műveleteket végezhet a közeli Wi‑Fi-eszközökkel"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"műveletek végrehajtása a közeli Wi‑Fi-eszközökkel"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Engedélyezi az alkalmazás számára, hogy közzétegye és meghatározza a közeli Wi-Fi-eszközök viszonylagos helyzetét, és csatlakozzon hozzájuk."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Preferált NFC fizetési szolgáltatási információk"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lehetővé teszi az alkalmazás számára preferált NFC fizetési szolgáltatási információk (pl. regisztrált alkalmazásazonosítók és útvonali cél) lekérését."</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Lehetővé teszi, hogy a tulajdonos kapcsolódjon egy üzenetszolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"kapcsolódás szolgáltatókhoz"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Lehetővé teszi a tulajdonos számára a szolgáltatókhoz való kapcsolódást. A normál alkalmazások esetében erre nincs szükség."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"hozzáférés a „Ne zavarjanak” funkcióhoz"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Az alkalmazás olvashatja és szerkesztheti a „Ne zavarjanak” funkció beállításait."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"engedélyhasználat megtekintésének elindítása"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Lehetővé teszi a felhasználó számára, hogy elindítsa az alkalmazás engedélyhasználatát. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"engedélyezési döntések megtekintésének elindítása"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Kihagyás"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nincs találat"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Keresés az oldalon"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# egyezés}other{{total}/#}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Kész"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Közös tárhely tartalmának törlése…"</string>
     <string name="share" msgid="4157615043345227321">"Megosztás"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ez a következő ébresztés)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Kikapcsolásig"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Amíg ki nem kapcsolja a „Ne zavarjanak” lehetőséget"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Összecsukás"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne zavarjanak"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Inaktivitás"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Hétköznap éjszaka"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hétvége"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"A hívások és az értesítések rezegnek"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"A hívások és az értesítések némák"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Rendszermódosítások"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne zavarjanak"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Újdonság: A Ne zavarjanak mód elrejti az értesítéseket"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Koppintással további információhoz juthat, és elvégezheti a módosítást."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Módosultak a Ne zavarjanak mód beállításai"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Koppintson a letiltott elemek megtekintéséhez."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Rendszer"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Beállítások"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Kikapcsolás"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"További információ"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"A bővített értesítések felváltják az androidos alkalmazkodó értesítéseket az Android 12-es verziójában. Ez a funkció javasolt műveleteket és válaszokat mutat, és rendszerezi az értesítéseket.\n\nA bővített értesítések minden értesítéstartalmat olvashatnak (így a személyes adatokat, mint például a névjegyek nevét és az üzeneteket is). Ez a funkció emellett elvetheti az értesítéseket, valamint reagálhat rájuk, például felveheti a telefonhívásokat, és vezérelheti a Ne zavarjanak módot."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Információs értesítés a rutinmódról"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Előfordulhat, hogy az akkumulátor lemerül a szokásos töltési időszak előtt"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akkumulátorkímélő mód aktiválva az akkumulátor üzemidejének növelése érdekében"</string>
@@ -2253,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Sikerült lefordítani az üzenetet <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> nyelvről <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> nyelvre."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Háttértevékenység"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Háttértevékenység"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"A(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazás fut a háttérben, és meríti az akkumulátort. Koppintson az áttekintéshez."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"A(z) <xliff:g id="APP">%1$s</xliff:g> fut a háttérben, és meríti az akkumulátort. Koppintson az áttekintéshez."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"A(z) <xliff:g id="APP">%1$s</xliff:g> alkalmazás már hosszú ideje fut a háttérben. Koppintson az áttekintéshez."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Aktív alkalmazások ellenőrzése"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ezen az eszközön nem lehet hozzáférni a kamerához"</string>
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index ea6eddd..136f0ea 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Երեք կողմով զանգ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Անցանկալի վրդովեցնող զանգերի մերժում"</string>
     <string name="CndMmi" msgid="185136449405618437">"Զանգող համարի առաքում"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Չանհանգստացնել"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Զանգողի ID-ն լռելյայն սահմանափակված է: Հաջորդ զանգը` սահմանափակված"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Զանգողի ID-ն լռելյայն սահմանափակված է: Հաջորդ զանգը` չսահմանափակված"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Զանգողի ID-ն լռելյայն չսահմանափակված է: Հաջորդ զանգը` Սահմանափակված"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"օգտագործել օրացույցը"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ուղարկել և դիտել SMS-ները"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Ֆայլեր և փաստաթղթեր"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"սարքի ֆայլերի և փաստաթղթերի օգտագործման թույլտվություն"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Երաժշտություն և այլ աուդիո նյութեր"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"բացել ձեր սարքում պահված աուդիո ֆայլերը"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Լուսանկարներ և տեսանյութեր"</string>
@@ -543,11 +542,11 @@
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Թույլ է տալիս հավելվածին հայտնաբերել և զուգակցել մոտակա Bluetooth սարքերը"</string>
     <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"միանալ զուգակցված Bluetooth սարքերի"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Թույլ է տալիս հավելվածին միանալ զուգակցված Bluetooth սարքերի"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Գովազդ մոտակա Bluetooth սարքերում"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"գովազդել մոտակա Bluetooth սարքերին"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Թույլատրում է հավելվածին գովազդ փոխանցել մոտակա Bluetooth սարքերին"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"որոշել մոտակա UWB սարքերի միջև հարաբերական դիրքավորումը"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Թույլատրել հավելվածին որոշել գերլայնաշերտ կապի տեխնոլոգիան աջակցող մոտակա սարքերի միջև հարաբերական դիրքավորումը"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Փոխազդում մոտակա Wi‑Fi սարքերի հետ"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"փոխներգործել մոտակա Wi‑Fi սարքերի հետ"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Թույլ է տալիս հավելվածին տվյալներ փոխանցել մոտակա Wi‑Fi սարքերին, միանալ դրանց և որոշել դրանց մոտավոր դիրքը։"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Տեղեկություններ NFC վճարային ծառայության մասին"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Թույլ է տալիս հավելվածին ստանալ նախընտրելի NFC վճարային ծառայության մասին տեղեկություններ (օր․՝ գրանցված լրացուցիչ սարքերի և երթուղու նպատակակետի մասին տվյալներ)։"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Շարունակելու համար ապակողպեք էկրանը"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Մատնահետքն ամբողջությամբ չի սկանավորվել"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Չհաջողվեց մշակել մատնահետքը: Նորից փորձեք:"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Մաքրեք մատնահետքերի սկաները և նորից փորձեք"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Մաքրեք սկաները և նորից փորձեք"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Մատը ուժեղ սեղմեք սկաների վրա"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Շատ դանդաղ անցկացրիք մատը: Փորձեք նորից:"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Փորձեք մեկ այլ մատնահետք"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Շատ լուսավոր է"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ամեն անգամ թեթևակի փոխեք մատի դիրքը"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Մատնահետքը չի ճանաչվել"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Մատը ուժեղ սեղմեք սկաների վրա"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Մատնահետքը նույնականացվեց"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Դեմքը ճանաչվեց"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Դեմքը ճանաչվեց: Սեղմեք «Հաստատել»:"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Թույլ է տալիս տիրոջը կապվել օպերատորի հաղորդագրությունների ծառայության վերին մակարդակի միջերեսի հետ: Սա երբեք չի պահանջվում սովորական հավելվածների համար:"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"կապվել օպերատորի ծառայություններին"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Թույլ է տալիս սեփականատիրոջը կապվել օպերատորի ծառայություններին: Սովորական հավելվածների դեպքում չի պահանջվում:"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"հասանելիություն «Չանհանգստացնել» գործառույթին"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Թույլ է տալիս հավելվածին փոփոխել «Չանհանգստացնել» գործառույթի կազմաձևումը:"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"թույլտվությունների մասին տվյալների հասանելիություն"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Հավելվածին հասանելի կդառնան թույլտվությունների մասին տվյալները։ Այս թույլտվությունն անհրաժեշտ չէ սովորական հավելվածներին։"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"սկսել թույլտվությունների հետ գործողությունների դիտումը"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Բաց թողնել"</string>
     <string name="no_matches" msgid="6472699895759164599">"Համընկնում չկա"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Գտեք էջում"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# համընկնում}one{#՝ {total}-ից}other{#՝ {total}-ից}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Պատրաստ է"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Ընդհանուր հիշողությունը ջնջվում է…"</string>
     <string name="share" msgid="4157615043345227321">"Կիսվել"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Մինչև <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Մինչև ժ. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-ը (հաջորդ զարթուցիչը)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Մինչև անջատեք"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Մինչև անջատեք «Չանհանգստացնել» գործառույթը"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Թաքցնել"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Չանհանգստացնել"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Անգործունության ժամանակը"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Աշխատանքային օր"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Շաբաթ-կիրակի"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Զանգերի և ծանուցումների համար թրթռոցը միացված է"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Զանգերի և ծանուցումների համար ձայնն անջատված է"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Համակարգի փոփոխություններ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Չանհանգստացնել"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Այժմ «Չանհանգստացնել» ռեժիմում ծանուցումները թաքցվում են"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Հպեք՝ ավելին իմանալու և կարգավորումները փոխելու համար:"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"«Չանհանգստացնել» ռեժիմի կարգավորումները փոխվել են"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Հպեք՝ տեսնելու, թե ինչ է արգելափակվել:"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Համակարգ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Կարգավորումներ"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Եղավ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Անջատել"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Իմանալ ավելին"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-ում ընդլայնված ծանուցումները փոխարինում են Android-ի հարմարվող ծանուցումներին։ Այս գործառույթը դասավորում է ձեր բոլոր ծանուցումները և առաջարկում գործողություններ և պատասխաններ։\n\nԸնդլայնված ծանուցումներին հասանելի է բոլոր ծանուցումների պարունակությունը, ներառյալ անձնական տվյալները, օրինակ՝ կոնտակտների անուններն ու հաղորդագրությունները։ Այս գործառույթը կարող է նաև փակել ծանուցումները կամ սեղմել դրանցում առկա կոճակները, այդ թվում՝ պատասխանել հեռախոսազանգերի և կառավարել «Չանհանգստացնել» ռեժիմը։"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Ծանուցում լիցքավորման մասին"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Մարտկոցը կարող է սովորականից շուտ սպառվել"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Մարտկոցի կյանքը երկարացնելու համար ակտիվացվել է մարտկոցի տնտեսման ռեժիմը"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Հաղորդագրությունը <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ից թարգմանվել է <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>։"</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Ակտիվ հավելվածներ ֆոնային ռեժիմում"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Ակտիվ հավելվածներ ֆոնային ռեժիմում"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> հավելվածն աշխատում է ֆոնային ռեժիմում և սպառում է մարտկոցի լիցքը։ Հպեք՝ դիտելու համար։"</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g>-ն աշխատում է ֆոնային ռեժիմում և սպառում է մարտկոցը։ Հպեք՝ դիտելու համար։"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> հավելվածը երկար ժամանակ աշխատում է ֆոնային ռեժիմում։ Հպեք՝ դիտելու համար։"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Ստուգել ակտիվ հավելվածները"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Հնարավոր չէ բացել տեսախցիկն այս սարքից"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index de24aa5..d2bad48 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Panggilan bertiga"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Penolakan panggilan yang tidak diinginkan"</string>
     <string name="CndMmi" msgid="185136449405618437">"Pengiriman nomor panggilan"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Jangan ganggu"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Nomor penelepon default \"dibatasi\". Panggilan selanjutnya: Dibatasi"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Nomor pengguna default \"dibatasi\". Panggilan selanjutnya: Tidak dibatasi."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Nomor penelepon default tidak dibatasi. Panggilan selanjutnya: Dibatasi"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"mengirim dan melihat pesan SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"File &amp; dokumen"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"mengakses file dan dokumen di perangkat Anda"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik &amp; audio lainnya"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"mengakses file audio di perangkat Anda"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto &amp; video"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Mengizinkan aplikasi menentukan posisi relatif antar-perangkat Ultra-Wideband di sekitar"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan perangkat Wi-Fi di sekitar"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Mengizinkan aplikasi menampilkan informasi, menghubungkan, dan menentukan posisi relatif perangkat Wi-Fi di sekitar"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Mengizinkan aplikasi menampilkan, menghubungkan, dan menentukan posisi relatif perangkat Wi-Fi di sekitar"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informasi Layanan Pembayaran NFC Pilihan"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Mengizinkan aplikasi untuk mendapatkan informasi layanan pembayaran NFC pilihan seperti bantuan terdaftar dan tujuan rute."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrol NFC"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Masukkan kunci layar untuk melanjutkan"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Sebagian sidik jari terdeteksi"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses sidik jari. Coba lagi."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Bersihkan sensor sidik jari lalu coba lagi"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Bersihkan sensor lalu coba lagi"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tekan sensor dengan kuat"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Jari digerakkan terlalu lambat. Coba lagi."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Coba sidik jari lain"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ubah sedikit posisi jari di setiap percobaan"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Sidik jari tidak dikenali"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Tekan sensor dengan kuat"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Sidik jari diautentikasi"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Wajah diautentikasi"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah diautentikasi, silakan tekan konfirmasi"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Mengizinkan operator untuk mengikat ke antarmuka tingkat tinggi dari suatu layanan perpesanan operator. Fitur ini seharusnya tidak diperlukan oleh aplikasi normal."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"mengikat ke layanan operator"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Memungkinkan pemegang untuk mengikat ke layanan operator. Tidak pernah dibutuhkan untuk aplikasi normal."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Akses status Jangan Ganggu"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Mengizinkan aplikasi membaca dan menulis konfigurasi status Jangan Ganggu."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"mulai melihat penggunaan izin"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Memungkinkan pemegang memulai penggunaan izin untuk aplikasi. Tidak diperlukan untuk aplikasi normal."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"mulai melihat keputusan izin"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Lewati"</string>
     <string name="no_matches" msgid="6472699895759164599">"Tidak ada kecocokan"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Temukan pada halaman"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# kecocokan}other{# dari {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Selesai"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Menghapus penyimpanan bersama…"</string>
     <string name="share" msgid="4157615043345227321">"Bagikan"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarm berikutnya)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Sampai Anda menonaktifkannya"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Hingga status Jangan Ganggu dinonaktifkan"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Ciutkan"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Jangan ganggu"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Waktu non-operasional"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Malam hari kerja"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Akhir pekan"</string>
@@ -1960,7 +1957,7 @@
     <string name="demo_restarting_message" msgid="1160053183701746766">"Mereset perangkat..."</string>
     <string name="suspended_widget_accessibility" msgid="6331451091851326101">"<xliff:g id="LABEL">%1$s</xliff:g> dinonaktifkan"</string>
     <string name="conference_call" msgid="5731633152336490471">"Konferensi Telepon"</string>
-    <string name="tooltip_popup_title" msgid="7863719020269945722">"Keterangan alat"</string>
+    <string name="tooltip_popup_title" msgid="7863719020269945722">"Tooltip"</string>
     <string name="app_category_game" msgid="4534216074910244790">"Game"</string>
     <string name="app_category_audio" msgid="8296029904794676222">"Musik &amp; Audio"</string>
     <string name="app_category_video" msgid="2590183854839565814">"Film &amp; Video"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Panggilan dan notifikasi akan bergetar"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Suara panggilan dan notifikasi akan dinonaktifkan"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Perubahan sistem"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Jangan Ganggu"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Baru: Mode Jangan Ganggu menyembunyikan notifikasi"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Ketuk untuk mempelajari lebih lanjut dan mengubah."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Jangan Ganggu telah berubah"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Ketuk untuk memeriksa item yang diblokir."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Setelan"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Oke"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Nonaktifkan"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pelajari lebih lanjut"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Notifikasi yang ditingkatkan menggantikan Notifikasi Adaptif Android di Android 12. Fitur ini menunjukkan tindakan dan balasan yang disarankan, serta mengatur notifikasi.\n\nNotifikasi yang ditingkatkan dapat mengakses konten notifikasi, termasuk informasi pribadi seperti nama kontak dan pesan. Fitur ini juga dapat menutup atau merespons notifikasi, seperti menjawab panggilan telepon dan mengontrol fitur Jangan Ganggu."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifikasi info Mode Rutinitas"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterai mungkin habis sebelum pengisian daya biasanya"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Penghemat Baterai diaktifkan untuk memperpanjang masa pakai baterai"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Pesan diterjemahkan dari bahasa <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ke <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktivitas Latar Belakang"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktivitas Latar Belakang"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> berjalan di latar belakang dan menghabiskan daya baterai. Ketuk untuk meninjau."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> mengonsumsi banyak daya di latar belakang. Ketuk untuk meninjau."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> berjalan di latar belakang dalam waktu yang lama. Ketuk untuk meninjau."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Periksa aplikasi aktif"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Tidak dapat mengakses kamera dari perangkat ini"</string>
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 4b2f371..d49a777 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Þriggja manna símafundur"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Óæskilegum símtölum hafnað"</string>
     <string name="CndMmi" msgid="185136449405618437">"Númerabirting"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ónáðið ekki"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Númerabirting er sjálfgefið með takmörkunum. Næsta símtal: Með takmörkunum"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Númerabirting er sjálfgefið með takmörkunum. Næsta símtal: Án takmarkana"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Númerabirting er sjálfgefið án takmarkana. Næsta símtal: Með takmörkunum"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"fá aðgang að dagatalinu þínu"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"senda og skoða SMS-skilaboð"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Skrár og skjöl"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"fá aðgang að skrám og skjölum í tækinu þínu"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Tónlist og annað hljóð"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"fá aðgang að hljóðskrám í tækinu þínu"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Myndir og myndskeið"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Sláðu inn skjálásinn þinn til að halda áfram"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Hluti fingrafars greindist"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Ekki var hægt að vinna úr fingrafarinu. Reyndu aftur."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hreinsaðu fingrafaralesarann og reyndu aftur"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Hreinsaðu lesarann og reyndu aftur"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Ýttu ákveðið á lesarann"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Fingurinn hreyfðist of hægt. Reyndu aftur."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prófaðu annað fingrafar"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Of bjart"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Breyttu stöðu fingursins örlítið í hvert skipti"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Ekki þekkt fingrafar"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Ýttu ákveðið á lesarann"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingrafar staðfest"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Andlit staðfest"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Andlit staðfest, ýttu til að staðfesta"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Leyfir forriti að bindast efsta viðmótslagi skilaboðaþjónustu símafyrirtækis. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bindast þjónustu símafyrirtækis"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Leyfir handhafa að bindast þjónustu símafyrirtækis. Ætti aldrei að vera nauðsynlegt fyrir venjuleg forrit."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"aðgangur að „Ónáðið ekki“"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Leyfir forriti að lesa og skrifa í grunnstillingu „Ónáðið ekki“."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"heimildanotkun upphafsyfirlits"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Leyfir handhafa að byrja heimildanotkun fyrir forrit. Ætti aldrei að þurfa fyrir venjuleg forrit."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"opna ákvarðanir um skoðunarheimildir"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Sleppa"</string>
     <string name="no_matches" msgid="6472699895759164599">"Engar samsvaranir"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Finna á síðu"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# samsvörun}one{# af {total}}other{# af {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Lokið"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Eyðir samnýttri geymslu…"</string>
     <string name="share" msgid="4157615043345227321">"Deila"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Þangað til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (næsta viðvörun)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Þar til þú slekkur"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Þar til þú slekkur á „Ónáðið ekki“"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Minnka"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ónáðið ekki"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Hvíldartími"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Virkt kvöld"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Helgi"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Titringur er virkur fyrir símtöl og tilkynningar"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Slökkt verður á hljóði símtala og tilkynninga"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Breytingar á kerfi"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ónáðið ekki"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nýtt: „Ónáðið ekki“ er að fela tilkynningar"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Ýttu til að fá frekari upplýsingar og breyta."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„Ónáðið ekki“ var breytt"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Ýttu til að skoða hvað lokað hefur verið á."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Kerfi"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Stillingar"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Í lagi"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Slökkva"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Nánar"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Auknar tilkynningar hafa leyst breytilegar tilkynningar í Android af hólmi í Android 12. Eiginleikinn birtir tillögur að aðgerðum og svörum og flokkar tilkynningar.\n\nAuknar tilkynningar hafa aðgang að efni tilkynninga, þ. á m. persónuupplýsingum á borð við nöfn tengiliða og skilaboð. Eiginleikinn getur einnig hunsað eða svarað tilkynningum, til dæmis svarað símtölum og stjórnað „Ónáðið ekki“."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Upplýsingatilkynning aðgerðastillingar"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Rafhlaðan kann að tæmast áður en hún kemst í hleðslu"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Kveikt á rafhlöðusparnaði til að lengja endingu rafhlöðunnar"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> keyrir í bakgrunni og eyðir rafhlöðuorku. Ýttu til að skoða."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> hefur keyrt lengi í bakgrunni. Ýttu til að skoða."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skoða virk forrit"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Aðgangur að myndavél er ekki tiltækur í þessu tæki"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index b246d79..1ef2619 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Chiamata a tre"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rifiuto di chiamate fastidiose non desiderate"</string>
     <string name="CndMmi" msgid="185136449405618437">"Recapito numero chiamante"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Non disturbare"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID chiamante generalmente limitato. Prossima chiamata: limitato"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID chiamante generalmente limitato. Prossima chiamata: non limitato"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID chiamante generalmente non limitato. Prossima chiamata: limitato"</string>
@@ -537,11 +538,11 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Consente all\'applicazione di visualizzare la configurazione del Bluetooth sul tablet e di stabilire e accettare connessioni con dispositivi accoppiati."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Consente all\'app di visualizzare la configurazione del Bluetooth del dispositivo Android TV, nonché di stabilire e accettare connessioni con dispositivi accoppiati."</string>
     <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Consente all\'applicazione di visualizzare la configurazione del Bluetooth sul telefono e di stabilire e accettare connessioni con dispositivi accoppiati."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"Rilevamento/accopp. dispositivi Bluetooth vicini"</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"Rilevamento e accoppiamento di dispositivi Bluetooth vicini"</string>
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Consente all\'app di rilevare e accoppiare dispositivi Bluetooth nelle vicinanze"</string>
     <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Connessione a dispositivi Bluetooth accoppiati"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Consente all\'app di connettersi ai dispositivi Bluetooth accoppiati"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"trasmettere annunci a dispositivi Bluetooth vicini"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Trasmissione di annunci a dispositivi Bluetooth vicini"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Consente all\'app di trasmettere annunci ai dispositivi Bluetooth nelle vicinanze"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Possibilità di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Consenti all\'app di stabilire la posizione relativa tra dispositivi a banda ultralarga nelle vicinanze"</string>
@@ -682,7 +683,7 @@
     <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"Consente a un\'applicazione di modificare le impostazioni di sincronizzazione per un account. Ad esempio, può servire per attivare la sincronizzazione dell\'applicazione Persone con un account."</string>
     <string name="permlab_readSyncStats" msgid="3747407238320105332">"lettura statistiche di sincronizz."</string>
     <string name="permdesc_readSyncStats" msgid="3867809926567379434">"Consente a un\'applicazione di leggere le statistiche di sincronizzazione per un account, incluse la cronologia degli eventi di sincronizzazione e la quantità di dati sincronizzati."</string>
-    <string name="permlab_sdcardRead" msgid="5791467020950064920">"lettura dei contenuti dell\'archivio condiviso"</string>
+    <string name="permlab_sdcardRead" msgid="5791467020950064920">"Lettura dei contenuti dell\'archivio condiviso"</string>
     <string name="permdesc_sdcardRead" msgid="6872973242228240382">"Consente all\'app di leggere i contenuti del tuo archivio condiviso."</string>
     <string name="permlab_readMediaAudio" msgid="8723513075731763810">"Lettura dei file audio dallo spazio di archiviazione condiviso"</string>
     <string name="permdesc_readMediaAudio" msgid="5299772574434619399">"Consente all\'app di leggere i file audio dal tuo spazio di archiviazione condiviso."</string>
@@ -690,7 +691,7 @@
     <string name="permdesc_readMediaVideo" msgid="3846400073770403528">"Consente all\'app di leggere i file video dal tuo spazio di archiviazione condiviso."</string>
     <string name="permlab_readMediaImage" msgid="1507059005825769856">"Lettura dei file immagine dallo spazio di archiviazione condiviso"</string>
     <string name="permdesc_readMediaImage" msgid="8328052622292457588">"Consente all\'app di leggere i file immagine dal tuo spazio di archiviazione condiviso."</string>
-    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"modifica/eliminazione dei contenuti dell\'archivio condiviso"</string>
+    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"Modifica/eliminazione dei contenuti dell\'archivio condiviso"</string>
     <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"Consente all\'app di modificare i contenuti del tuo archivio condiviso."</string>
     <string name="permlab_use_sip" msgid="8250774565189337477">"invio/ricezione di chiamate SIP"</string>
     <string name="permdesc_use_sip" msgid="3590270893253204451">"Consente all\'app di effettuare e ricevere chiamate SIP."</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Consente l\'associazione di un servizio di messaggi dell\'operatore all\'interfaccia principale. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"associazione a servizi dell\'operatore"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Consente al titolare di collegarsi a servizi dell\'operatore. Non dovrebbe mai essere necessaria per le normali app."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"accesso alla funzione Non disturbare"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Consente all\'app di leggere e modificare la configurazione della funzione Non disturbare."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"avvio dell\'uso dell\'autorizzazione di visualizzazione"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Consente al titolare di avviare l\'uso delle autorizzazioni per un\'app. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"Inizio della visualizzazione delle decisioni relative all\'autorizzazione"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Salta"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nessuna corrispondenza"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Trova nella pagina"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# corrispondenza}one{# di {total}}other{# di {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Fine"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Cancellazione archivio condiviso…"</string>
     <string name="share" msgid="4157615043345227321">"Condividi"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Fino a <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Fino a <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (prossima sveglia)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Fino alla disattivazione"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Fino alla disattivazione di Non disturbare"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Comprimi"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Non disturbare"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Tempo di riposo"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Notte di un giorno feriale"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fine settimana"</string>
@@ -2023,22 +2027,20 @@
     <string name="harmful_app_warning_uninstall" msgid="6472912975664191772">"DISINSTALLA"</string>
     <string name="harmful_app_warning_open_anyway" msgid="5963657791740211807">"APRI COMUNQUE"</string>
     <string name="harmful_app_warning_title" msgid="8794823880881113856">"App dannosa rilevata"</string>
-    <!-- no translation found for log_access_confirmation_title (3143035474800851565) -->
-    <skip />
-    <!-- no translation found for log_access_confirmation_allow (143157286283302512) -->
-    <skip />
-    <!-- no translation found for log_access_confirmation_deny (7685790957455099845) -->
-    <skip />
-    <!-- no translation found for log_access_confirmation_body (7599059550906238538) -->
-    <skip />
-    <!-- no translation found for log_access_do_not_show_again (1058690599083091552) -->
-    <skip />
+    <string name="log_access_confirmation_title" msgid="3143035474800851565">"Richiesta di accesso al log di sistema"</string>
+    <string name="log_access_confirmation_allow" msgid="143157286283302512">"Solo questa volta"</string>
+    <string name="log_access_confirmation_deny" msgid="7685790957455099845">"Non consentire"</string>
+    <string name="log_access_confirmation_body" msgid="7599059550906238538">"<xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> richiede i log di sistema per eseguire debug funzionali. Questi log potrebbero contenere informazioni scritte dalle app e dai servizi sul tuo dispositivo."</string>
+    <string name="log_access_do_not_show_again" msgid="1058690599083091552">"Non mostrare più"</string>
     <string name="slices_permission_request" msgid="3677129866636153406">"L\'app <xliff:g id="APP_0">%1$s</xliff:g> vuole mostrare porzioni dell\'app <xliff:g id="APP_2">%2$s</xliff:g>"</string>
     <string name="screenshot_edit" msgid="7408934887203689207">"Modifica"</string>
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"La vibrazione sarà attiva per chiamate e notifiche"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"L\'audio di chiamate e notifiche sarà disattivato"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Modifiche al sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Non disturbare"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novità: la modalità Non disturbare nasconde le notifiche"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tocca per avere ulteriori informazioni e modificare."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"L\'impostazione Non disturbare è cambiata"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tocca per controllare le notifiche bloccate."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Impostazioni"</string>
@@ -2055,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Disattiva"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Scopri di più"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Le notifiche adattive Android sono state sostituite dalle notifiche avanzate in Android 12. Questa funzionalità mostra risposte e azioni suggerite e organizza le tue notifiche.\n\nLe notifiche avanzate possono accedere ai contenuti di una notifica, incluse le informazioni personali, come i nomi dei contatti e i messaggi. Questa funzionalità può anche ignorare le notifiche o rispondervi, ad esempio accettando le telefonate, e controllare la modalità Non disturbare."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notifica di informazioni sulla modalità Routine"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"La batteria potrebbe esaurirsi prima della ricarica abituale"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Risparmio energetico attivo per far durare di più la batteria"</string>
@@ -2125,10 +2128,8 @@
     <string name="resolver_switch_on_work" msgid="463709043650610420">"Tocca per attivare"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Nessuna app di lavoro"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Nessuna app personale"</string>
-    <!-- no translation found for miniresolver_open_in_personal (3874522693661065566) -->
-    <skip />
-    <!-- no translation found for miniresolver_open_in_work (4415223793669536559) -->
-    <skip />
+    <string name="miniresolver_open_in_personal" msgid="3874522693661065566">"Aprire <xliff:g id="APP">%s</xliff:g> nel tuo profilo personale?"</string>
+    <string name="miniresolver_open_in_work" msgid="4415223793669536559">"Aprire <xliff:g id="APP">%s</xliff:g> nel tuo profilo di lavoro?"</string>
     <string name="miniresolver_use_personal_browser" msgid="776072682871133308">"Usa il browser personale"</string>
     <string name="miniresolver_use_work_browser" msgid="543575306251952994">"Usa il browser di lavoro"</string>
     <string name="PERSOSUBSTATE_SIM_NETWORK_ENTRY" msgid="8050953231914637819">"PIN di sblocco rete SIM"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Messaggio tradotto dalla lingua <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> alla lingua <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Attività in background"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Attività in background"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> è in esecuzione in background e sta consumando la batteria. Tocca per controllare."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> è in esecuzione in background e consuma batteria. Tocca per controllare."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> è in esecuzione in background da molto tempo. Tocca per controllare."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verifica le app attive"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Impossibile accedere alla fotocamera da questo dispositivo"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 7cd023f..17f455d 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"שיחה עם שלושה משתתפים"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"דחיית שיחות מטרידות ולא רצויות"</string>
     <string name="CndMmi" msgid="185136449405618437">"שליחת מספר מתקשר"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"נא לא להפריע"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"השירות \'שיחה מזוהה\' עובר כברירת מחדל למצב מוגבל. השיחה הבאה: מוגבלת"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"שירות השיחה המזוהה עובר כברירת מחדל למצב מוגבל. השיחה הבאה: לא מוגבלת"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"שירות \'שיחה מזוהה\' עובר כברירת מחדל למצב לא מוגבל. השיחה הבאה: מוגבלת"</string>
@@ -306,10 +307,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"גישה אל היומן"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏שליחה והצגה של הודעות SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"קבצים ומסמכים"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"גישה לקבצים ולמסמכים במכשיר"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"מוזיקה וסוגי אודיו אחרים"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"גישה לקובצי אודיו במכשיר"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"תמונות וסרטונים"</string>
@@ -590,12 +589,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"יש לבטל את נעילת המסך כדי להמשיך"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"זוהתה טביעת אצבע חלקית"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"לא ניתן היה לעבד את טביעת האצבע. אפשר לנסות שוב."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"עליך לנקות את חיישן טביעות האצבע ולנסות שוב"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"עליך לנקות את החיישן ולנסות שוב"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"צריך ללחוץ חזק על החיישן"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"הזזת את האצבע לאט מדי. יש לנסות שוב."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"יש להשתמש בטביעת אצבע אחרת"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"בהיר מדי"</string>
@@ -603,10 +599,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"צריך לשנות מעט את תנוחת האצבע בכל פעם"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"טביעת האצבע לא זוהתה"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"צריך ללחוץ חזק על החיישן"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"טביעת האצבע אומתה"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"זיהוי הפנים בוצע"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"זיהוי הפנים בוצע. יש ללחוץ על אישור"</string>
@@ -745,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"מאפשרת לבעלים לאגד לממשק ברמה העליונה של שירות העברת הודעות של ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"איגוד לשירותי ספק"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"מאפשרת לבעלים לאגד לשירות ספק. לא נחוצה לאפליקציות רגילות בדרך כלל."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"גישה אל \'נא לא להפריע\'"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"מאפשרת לאפליקציה לקרוא ולכתוב את התצורה של התכונה \'נא לא להפריע\'."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"התחלת צפייה בהרשאות השימוש"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"מאפשרת לבעלים להפעיל את השימוש בהרשאות עבור אפליקציה מסוימת. הרשאה זו אף פעם לא נדרשת עבור אפליקציות רגילות."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ההחלטות לגבי ההרשאות להפעלת התצוגה"</string>
@@ -1510,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"דילוג"</string>
     <string name="no_matches" msgid="6472699895759164599">"אין התאמות"</string>
     <string name="find_on_page" msgid="5400537367077438198">"חיפוש בדף"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{התאמה אחת}two{# מתוך {total}}many{# מתוך {total}}other{# מתוך {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"סיום"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"בתהליך מחיקה של אחסון משותף…"</string>
     <string name="share" msgid="4157615043345227321">"שיתוף"</string>
@@ -1876,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ההתראה הבאה)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"עד הכיבוי"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"עד להשבתת התכונה \'נא לא להפריע\'"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"כיווץ"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"נא לא להפריע"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"זמן השבתה"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ערב ביום חול"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"סוף השבוע"</string>
@@ -2042,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"שיחות והודעות ירטטו"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"שיחות והתראות יושתקו"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"שינויים במערכת"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"נא לא להפריע"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"חדש: מצב \'נא לא להפריע\' מסתיר התראות"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"אפשר להקיש כדי לקבל מידע נוסף ולבצע שינויים."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ההגדרה \'נא לא להפריע\' השתנתה"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"יש להקיש כדי לבדוק מה חסום."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"מערכת"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"הגדרות"</string>
@@ -2059,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"אישור"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"השבתה"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"מידע נוסף"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏התכונה \'התראות משופרות\' החליפה את \'התראות מותאמות ל-Android\' ב-‏Android 12. התכונה הזו מציגה הצעות לפעולות ולתשובות ומארגנת את ההתראות שלך.\n\nל\'התראות משופרות\' יש גישה לתוכן של התראות, כולל מידע אישי כמו שמות אנשי קשר והודעות. התכונה הזו יכולה גם לסגור התראות או להגיב עליהן (למשל לענות לשיחות טלפון) ולשלוט בתכונה \'נא לא להפריע\'."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"התראת מידע לגבי מצב שגרתי"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"הסוללה עלולה להתרוקן לפני המועד הרגיל של הטעינה"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"תכונת החיסכון בסוללה הופעלה כדי להאריך את חיי הסוללה"</string>
@@ -2265,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> פועלת ברקע ומרוקנת את הסוללה. יש להקיש כדי לבדוק."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"האפליקציה <xliff:g id="APP">%1$s</xliff:g> פועלת ברקע במשך הרבה זמן. יש להקיש כדי לבדוק."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"כדאי לבדוק את האפליקציות הפעילות"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"לא ניתן לגשת למצלמה מהמכשיר הזה"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 0c70187..0862df1 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"三者間通話"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"迷惑な着信を拒否"</string>
     <string name="CndMmi" msgid="185136449405618437">"発呼者番号を配信"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"着信拒否"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"既定: 発信者番号非通知、次の発信: 非通知"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"既定: 発信者番号非通知、次の発信: 通知"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"既定: 発信者番号通知、次の発信: 非通知"</string>
@@ -545,7 +546,7 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"付近の Bluetooth デバイスへの広告の配信をアプリに許可します"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"付近の Ultra Wideband デバイス間の相対位置の特定"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"付近の Ultra Wideband デバイス間の相対位置の特定をアプリに許可します"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"付近の Wi-Fi デバイスとのやり取り"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"付近の Wi-Fi デバイスとの通信"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"付近の Wi-Fi デバイスについて、情報の表示、接続、相対位置の確認をアプリに許可します"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"優先される NFC お支払いサービスの情報"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"登録されている支援やルートの目的地など、優先される NFC お支払いサービスの情報を取得することをアプリに許可します。"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"携帯通信会社のSMSサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"携帯通信会社のサービスへのバインド"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"携帯通信会社のサービスにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"サイレント モードの利用"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"サイレント モード設定の読み取りと書き込みをアプリに許可します。"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"表示権限の使用の開始"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"アプリの権限使用の開始を所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"閲覧権限の許可 / 拒否の開始"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"スキップ"</string>
     <string name="no_matches" msgid="6472699895759164599">"該当なし"</string>
     <string name="find_on_page" msgid="5400537367077438198">"ページ内を検索"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{一致: # 件}other{#/{total} 件}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"完了"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"共有ストレージを消去しています…"</string>
     <string name="share" msgid="4157615043345227321">"共有"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(次のアラーム)まで"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"自分が OFF にするまで"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"サイレント モードを OFF にするまで"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"折りたたむ"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"サイレント モード"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ダウンタイム"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"平日の夜"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"着信や通知をバイブレーションで知らせます"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"着信音と通知音が鳴りません"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"システムの変更"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"サイレント モード"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"新機能: サイレント モードでは通知が非表示になります"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"タップすると、詳細を確認して設定を変更できます。"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"サイレント モードが変わりました"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"タップしてブロック対象をご確認ください。"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"システム"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"設定"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"OFF にする"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"詳細"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 では Android 通知の自動調整が拡張通知に切り替えられました。この機能により、操作や返信の候補が提示され、通知が整理されます。\n\n拡張通知は通知コンテンツにアクセスできます。これには、連絡先の名前などの個人情報やメッセージも含まれます。また、この機能は、通知を非表示にしたり通知に応答したりすることもできます。たとえば、電話に出ることやサイレント モードを管理することができます。"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ルーティン モード情報の通知"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"通常の充電を行う前に電池が切れる可能性があります"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"電池を長持ちさせるため、バッテリー セーバーが有効になりました"</string>
@@ -2253,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"メッセージを<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>から<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>に翻訳しました。"</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"バックグラウンド アクティビティ"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"バックグラウンド アクティビティ"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドで実行され、バッテリーを消費しています。タップしてご確認ください。"</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドでバッテリーを消費しています。タップして確認。"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> がバックグラウンドで長時間実行されています。タップしてご確認ください。"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"有効なアプリをチェック"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"このデバイスからはカメラにアクセスできません"</string>
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index ae3f31c..f0b2f34 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"დარეკვის სამი გზა"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"არასასურველი მომაბეზრებელი ზარების უარყოფა"</string>
     <string name="CndMmi" msgid="185136449405618437">"დამრეკავი ნომრის მოწოდება"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"არ შემაწუხოთ"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ნაგულისხმებად დაყენებულია ნომრის დაფარვა. შემდეგი ზარი: დაფარულია."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ნაგულისხმებად დაყენებულია ნომრის დაფარვა. შემდეგი ზარი: არ არის დაფარული."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ნაგულისხმებად დაყენებულია ნომრის დაფარვის გამორთვა. შემდეგი ზარი: დაფარულია."</string>
@@ -541,7 +542,7 @@
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"საშუალებას აძლევს აპს, აღმოაჩინოს ახლომახლო Bluetooth მოწყობილობები დასაწყვილებლად"</string>
     <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"დაწყვილებულ Bluetooth მოწყობილობებთან დაკავშირება"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"საშუალებას აძლევს აპს, დაუკავშირდეს დაწყვილებულ Bluetooth მოწყობილობებს"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ახლ. Bluetooth მოწყობილობებზე რეკლამის განთავსება"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"ახლ. Bluetooth მოწყობილობებზე მონაცემების მაუწყებლობა"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"საშუალებას აძლევს აპს, რეკლამა განათავსოს ახლომახლო Bluetooth მოწყობილობებზე"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"შედარებითი პოზიციის დადგენა ახლომახლო ულტრაფართო სიხშირის მოწყობილობების შესახებ"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"ნებას რთავს აპს, დაადგინოს შედარებითი პოზიცია ახლომახლო ულტრაფართო სიხშირის მოწყობილობების შესახებ"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"საშუალებას აძლევს მფლობელს შექმნას შეტყობინების გაცვლის მომსახურების უმახლესი დონის ინტერფეისი. არასდროს იქნება საჭირო ნორმალური აპლიკაციებისათვის."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"ოპერატორის სერვისებთან დაკავშირება"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"მფლობელს აძლევს ოპერატორის სერვისებთან დაკავშირების საშუალებას. ჩვეულებრივი აპებისთვის არასოდეს იქნება საჭირო."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"ფუნქციაზე „არ შემაწუხოთ“ წვდომა"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"საშუალებას აძლევს აპს, წაიკითხოს და დაწეროს კონფიგურაცია „არ შემაწუხოთ“."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ნახვის ნებართვის გამოყენების დაწყება"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"მფლობელს საშუალებას აძლევს, დაიწყოს აპის ნებართვის გამოყენება. ჩვეულებრივი აპებისთვის არასოდეს უნდა იყოს საჭირო."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ნებართვის შესახებ გადაწყვეტილებების ნახვის დაწყება"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"გამოტოვება"</string>
     <string name="no_matches" msgid="6472699895759164599">"შესატყვისები არ არის."</string>
     <string name="find_on_page" msgid="5400537367077438198">"გვერდზე ძებნა"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# დამთხვევა}other{{total}-დან #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"დასრულდა"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"მიმდინარეობს ზიარი მეხსიერების ამოშლა…"</string>
     <string name="share" msgid="4157615043345227321">"გაზიარება"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-მდე"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-მდე (შემდეგი მაღვიძარა)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"გამორთვამდე"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"სანამ გამორთავთ „არ შემაწუხოთ“ ფუნქციას"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"აკეცვა"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"არ შემაწუხოთ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ავარიული პაუზა"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"სამუშაო კვირის ღამე"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"შაბათ-კვირა"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ზარების და შეტყობინებების მიღებისას ვიბრაცია ჩაირთვება"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ზარები და შეტყობინებები დადუმებული იქნება"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"სისტემის ცვლილებები"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"არ შემაწუხოთ"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"ახალი: „არ შემაწუხოთ“ რეჟიმი მალავს შეტყობინებებს"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"შეეხეთ მეტის გასაგებად და შესაცვლელად."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"„არ შემაწუხოთ“ რეჟიმი შეცვლილია"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"შეეხეთ იმის სანახავად, თუ რა არის დაბლოკილი."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"სისტემა"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"პარამეტრები"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"კარგი"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"გამორთვა"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"შეიტყვეთ მეტი"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"გაფართოებულმა შეტყობინებებმა ჩაანაცვლა Android-ის ადაპტაციური შეტყობინებების ფუნქცია Android 12-ში. ეს ფუნქცია გაჩვენებთ შემოთავაზებულ მოქმედებებს და პასუხებს, ამასთანავე კი ახდენს თქვენი შეტყობინებების ორგანიზებას.\n\nგაფართოებულ შეტყობინებებს შეუძლია ყველა შეტყობინების კონტენტზე, მათ შორის, ისეთ პერსონალურ ინფორმაციაზე წვდომა, როგორიცაა კონტაქტების სახელები და შეტყობინებები. ამ ფუნქციას ასევე შეუძლია შეტყობინებათა დახურვა ან მათზე პასუხის გაცემა, მაგალითად, სატელეფონო ზარებზე პასუხი და „არ შემაწუხოთ“ რეჟიმის მართვა."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"რუტინის რეჟიმის საინფორმაციო შეტყობინება"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ბატარეა შეიძლება დაჯდეს დატენის ჩვეულ დრომდე"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ბატარეის დამზოგი გააქტიურდა ბატარეის მუშაობის გასახანგრძლივლებლად"</string>
@@ -2253,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"შეტყობინება ნათარგმნია <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>-დან შემდეგ ენაზე: <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"აქტივობა ფონურ რეჟიმში"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"აქტივობა ფონურ რეჟიმში"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> გაშვებულია ფონურ რეჟიმში და იყენებს ბატარეას. შეეხეთ გადასახედად."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> გაშვებულია ფონში და იყენებს ბატარეას. შეეხეთ გადასახედად."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ფონურ რეჟიმში დიდი ხანია გაშვებულია. შეეხეთ გადასახედად."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"აქტიური აპების შემოწმება"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"კამერაზე წვდომა ამ მოწყობილობიდან ვერ მოხერხდება"</string>
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 439060f..6f4b66a 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Қоңырау шалудың үш жолы"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Мазаны алатын, қалаусыз қоңыраулардан бас тарту"</string>
     <string name="CndMmi" msgid="185136449405618437">"Қоңырау шалған нөмірді жеткізу"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Мазаламау"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Қоңырау шалушының жеке анықтағышы бастапқы бойынша шектелген. Келесі қоңырау: Шектелген"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Қоңырау шалушының жеке анықтағышы бастапқы бойынша шектелген. Келесі қоңырау: Шектелмеген"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Қоңырау шалушының жеке анықтағышы бастапқы бойынша шектелмеген. Келесі қоңырау: Шектелген"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"күнтізбеге кіру"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS хабарларын жіберу және көру"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлдар мен құжаттар"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"құрылғыдағы файлдар мен құжаттарды пайдалану"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка және басқа аудио"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"құрылғыдағы аудиофайлдарды пайдалану"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фотосуреттер және бейнелер"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Жалғастыру үшін экран құлпын енгізіңіз."</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Саусақ ізі жартылай анықталды."</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Саусақ ізін өңдеу мүмкін емес. Әрекетті қайталаңыз."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Саусақ ізін оқу сканерін тазалап, әрекетті қайталаңыз."</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сканерді тазалап, әрекетті қайталаңыз."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сканерге қатты басыңыз."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Саусағыңызды тым баяу қозғалттыңыз. Әрекетті қайталап көріңіз."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Басқа саусақ ізін байқап көріңіз."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Тым жарық."</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Саусағыңыздың қалпын аздап өзгертіп тұрыңыз."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Саусақ ізі танылмады."</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Сканерге қатты басыңыз."</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Саусақ ізі аутентификацияланды"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Бет танылды"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Бет танылды, \"Растау\" түймесін басыңыз"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Иесіне оператордың хабар алмасу қызметінің жоғарғы деңгейлі интерфейсіне байластыруға рұқсат етеді. Қалыпты қолданбалар үшін ешқашан қажет болмайды."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"оператор қызметтеріне қосылу"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Иесіне оператор қызметтеріне қосылуға мүмкіндік береді. Қалыпты қолданбалар үшін қажет болмайды."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Мазаламау режиміне кіру"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Қолданбаға «Мазаламау» конфигурациясын оқу және жазу мүмкіндігін береді."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"рұқсаттарды пайдалану туралы деректерді көру"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Пайдаланушы қолданбаға берілетін рұқсаттарды басқара алады. Ондай рұқсаттар әдеттегі қолданбаларға керек емес."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"Рұқсаттары бар әрекеттерді көру"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Өткізіп жіберу"</string>
     <string name="no_matches" msgid="6472699895759164599">"Сәйкес табылмады"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Беттен табу"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# сәйкестік}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Дайын"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Ортақ жад тазартылуда…"</string>
     <string name="share" msgid="4157615043345227321">"Бөлісу"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін (келесі дабыл)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Өшірілгенге дейін"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Мазаламау режимін өшіргенше"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Тасалау"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Мазаламау"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Бос тұру уақыты"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Жұмыс күндері кешке"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Демалыс күндері"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Қоңыраулар мен хабарландырулардың вибрациясы болады"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Қоңыраулар мен хабарландырулардың дыбыстық сигналы өшіріледі"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Жүйе өзгерістері"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Мазаламау режимі"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Жаңа: Мазаламау режимі хабарландыруларды жасыруда"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Толығырақ ақпарат алу және өзгерту үшін түртіңіз."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Мазаламау режимі өзгерді"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Түймені түртіп, неге тыйым салынатынын көріңіз."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Жүйе"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Параметрлер"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Жарайды"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Өшіру"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Толығырақ"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 жүйесінде кеңейтілген хабарландырулар функциясы бейімделетін хабарландырулар функциясын алмастырды. Бұл функция ұсынылған әрекеттер мен жауаптарды көрсетіп, хабарландыруларыңызды ретке келтіреді.\n\nОл хабарландыру мазмұнын, соның ішінде жеке ақпаратыңызды (мысалы, контакт аттары мен хабарлар) пайдалана алады. Сондай-ақ бұл функция арқылы хабарландыруларды жабуға немесе оларға жауап беруге (мысалы, телефон қоңырауларына жауап беру және Мазаламау режимін басқару) болады."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режим туралы хабарландыру"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея заряды азаюы мүмкін"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарея ұзаққа жетуі үшін, Батареяны үнемдеу режимі іске қосылды"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> қолданбасы фондық режимде жұмыс істеуде және батарея жұмсауда. Көру үшін түртіңіз."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> қолданбасы ұзақ уақыт бойы фондық режимде жұмыс істеуде. Көру үшін түртіңіз."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Белсенді қолданбаларды тексеру"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Бұл құрылғыдан камераны пайдалану мүмкін емес."</string>
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 49f2255..162b0f6 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"ការ​ហៅ​បី​ផ្លូវ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"បដិសេធ​ការ​ហៅ​រំខាន​ដែល​មិន​ចង់បាន"</string>
     <string name="CndMmi" msgid="185136449405618437">"ការ​បញ្ជូន​លេខ​ហៅ"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"កុំ​រំខាន"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"បាន​ដាក់​កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។​​​ ការ​ហៅ​បន្ទាប់៖​ បាន​ដាក់កម្រិត"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"មិន​បាន​ដាក់កម្រិត​លំនាំដើម​លេខ​សម្គាល់​អ្នក​ហៅ។ ការ​ហៅ​បន្ទាប់៖ មិន​បាន​ដាក់​កម្រិត។"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"មិន​បាន​ដាក់​កម្រិត​លេខ​សម្គាល់​អ្នក​ហៅ​លំនាំ​ដើម។ ការ​ហៅ​បន្ទាប់៖​ បាន​ដាក់កម្រិត"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"សារ SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ផ្ញើ និងមើលសារ SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"ឯកសារ"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"ចូលប្រើ​ឯកសារ​នៅលើ​ឧបករណ៍​របស់អ្នក"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"តន្ត្រី និងសំឡេងផ្សេងទៀត"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ចូលប្រើឯកសារសំឡេងនៅលើឧបករណ៍របស់អ្នក"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"រូបថត និងវីដេអូ"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"បញ្ចូលការចាក់សោអេក្រង់របស់អ្នក ដើម្បីបន្ត"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"បានសម្គាល់​ស្នាមម្រាមដៃដោយផ្នែក"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"មិនអាចដំណើរការស្នាមម្រាមដៃបានទេ។ សូមព្យាយាមម្តងទៀត។"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"សម្អាត​ឧបករណ៍​ចាប់ស្នាមម្រាមដៃ រួចព្យាយាម​ម្ដងទៀត"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"សម្អាត​ឧបករណ៍​ចាប់សញ្ញា រួចព្យាយាម​ម្ដងទៀត"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"សង្កត់លើ​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យណែន"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ចលនាម្រាមដៃយឺតពេកហើយ។ សូមព្យាយាមម្តងទៀត។"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"សាកល្បងប្រើ​ស្នាមម្រាមដៃផ្សេងទៀត"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ភ្លឺពេក"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ប្ដូរទីតាំងម្រាមដៃ​របស់អ្នកតិចៗ​គ្រប់ពេល"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"មិនស្គាល់ស្នាមម្រាមដៃទេ"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"សង្កត់លើ​ឧបករណ៍​ចាប់សញ្ញា​ឱ្យណែន"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"បាន​ផ្ទៀង​ផ្ទាត់​ស្នាម​ម្រាមដៃ"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"បានផ្ទៀងផ្ទាត់​មុខ"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"បានផ្ទៀងផ្ទាត់​មុខ សូម​ចុច​បញ្ជាក់"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"អនុញ្ញាតឲ្យអ្នកប្រើភ្ជាប់ទៅអ៊ីនធឺហ្វេសកម្រិតខ្ពស់នៃសេវាកម្មសារអ្នកផ្តល់សេវាកម្មទូរស័ព្ទ។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"ភ្ជាប់ទៅក្រុមហ៊ុនផ្តល់សេវាកម្ម"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"អនុញ្ញាតឲ្យម្ចាស់ភ្ជាប់ទៅសេវាកម្មក្រុមហ៊ុនផ្តល់សេវាកម្ម។ មិនគួរចាំបាច់សម្រាប់កម្មវិធីធម្មតាទេ។"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"ចូលដំណើរការ កុំរំខាន"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"អនុញ្ញាតឲ្យកម្មវិធីអាន និងសរសេរការកំណត់រចនាសម្ព័ន្ធមុខងារ កុំរំខាន។"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ចាប់ផ្ដើម​មើល​ការប្រើប្រាស់​ការអនុញ្ញាត"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"អនុញ្ញាត​ឱ្យម្ចាស់​ចាប់ផ្ដើម​ការប្រើប្រាស់​ការអនុញ្ញាត​សម្រាប់កម្មវិធី។ មិនគួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ចាប់ផ្ដើមមើលការសម្រេចលើការអនុញ្ញាត"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"រំលង"</string>
     <string name="no_matches" msgid="6472699895759164599">"គ្មាន​ការ​ផ្គូផ្គង"</string>
     <string name="find_on_page" msgid="5400537367077438198">"រក​ក្នុង​ទំព័រ"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{ត្រូវគ្នា #}other{# នៃ {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"រួចរាល់"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"កំពុងលុបទំហំផ្ទុករួម…"</string>
     <string name="share" msgid="4157615043345227321">"ចែក​រំលែក​"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"រហូត​ដល់ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"រហូតដល់ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ម៉ោងរោទិ៍បន្ទាប់)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"រហូតទាល់តែ​អ្នកបិទ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"រហូតទាល់តែអ្នកបិទ កុំរំខាន"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"បង្រួម"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"កុំរំខាន"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ពេលមិនដំណើរការ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"យប់ថ្ងៃធម្មតា"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ចុងសប្ដាហ៍"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ការហៅ​ទូរសព្ទ និងការជូន​ដំណឹងនឹងញ័រ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ការហៅ​ទូរសព្ទ និងការជូន​ដំណឹងនឹង​បិទសំឡេង"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"ការផ្លាស់ប្ដូរ​ប្រព័ន្ធ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"កុំ​រំខាន"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"ថ្មី៖ មុខងារ​កុំរំខាន​កំពុងលាក់​ការជូនដំណឹង"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ចុចដើម្បីស្វែងយល់បន្ថែម និងផ្លាស់ប្ដូរ។"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"មុខងារ​កុំ​រំខាន​ត្រូវ​បាន​ប្ដូរ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"សូមចុច​ដើម្បី​មើល​ថា​​បានទប់ស្កាត់អ្វីខ្លះ។"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ប្រព័ន្ធ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ការកំណត់"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"យល់ព្រម"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"បិទ"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ស្វែងយល់បន្ថែម"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ការជូនដំណឹងប្រសើរជាងមុន​បានជំនួស​ការជូនដំណឹងដែលមានភាពបត់បែន Android នៅក្នុង Android 12។ មុខងារនេះបង្ហាញការឆ្លើយតប និងសកម្មភាពដែលបានណែនាំ ព្រមទាំងរៀបចំការជូនដំណឹងរបស់អ្នក។\n\nការជូនដំណឹងប្រសើរជាងមុនអាចចូលប្រើខ្លឹមសារនៃការជូនដំណឹង រួមទាំងព័ត៌មានផ្ទាល់ខ្លួនដូចជា ឈ្មោះទំនាក់ទំនង និងសារជាដើម។ មុខងារនេះក៏អាចច្រានចោល ឬឆ្លើយតបនឹងការជូនដំណឹងដូចជា ការទទួល​ការហៅទូរសព្ទ និងគ្រប់គ្រង​មុខងារកុំរំខានផងដែរ។"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ការ​ជូនដំណឹង​ព័ត៌មាន​របស់​មុខងារ​ទម្លាប់"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ថ្ម​អាច​នឹង​អស់ មុនពេល​សាកថ្មធម្មតា"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"បាន​បើក​ដំណើរការមុខងារ​សន្សំ​ថ្ម ដើម្បីបង្កើនកម្រិត​ថាមពល​​ថ្ម"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ និងធ្វើឱ្យអស់ថ្មលឿន។ សូមចុច ដើម្បី​ពិនិត្យមើល។"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយអស់រយៈពេលយូរហើយ។ សូមចុច ដើម្បី​ពិនិត្យមើល។"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ពិនិត្យមើលកម្មវិធីសកម្ម"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"មិនអាចចូលប្រើកាមេរ៉ាពីឧបករណ៍នេះបានទេ"</string>
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index b73b96f..d9b1fab 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"ಮೂರು ಮಾರ್ಗದಲ್ಲಿ ಕರೆ ಮಾಡುವಿಕೆ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"ಅನಪೇಕ್ಷಿತ ಕಿರಿಕಿರಿ ಮಾಡುವ ಕರೆಗಳ ತಿರಸ್ಕಾರ"</string>
     <string name="CndMmi" msgid="185136449405618437">"ಕರೆ ಮಾಡುವ ಸಂಖ್ಯೆಯ ವಿತರಣೆ"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ಅಡಚಣೆ ಮಾಡಬೇಡ"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಿಲ್ಲ"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ಕರೆಮಾಡುವವರ ID ಅನ್ನು ನಿರ್ಬಂಧಿಸದಿರುವಂತೆ ಡಿಫಾಲ್ಟ್ ಮಾಡಲಾಗಿದೆ. ಮುಂದಿನ ಕರೆ: ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ವಾಹಕ ಸಂದೇಶ ಕಳುಹಿಸುವಿಕೆ ಸೇವೆಯ ಮೇಲ್ಮಟ್ಟದ ಇಂಟರ್ಫೇಸ್‌ಗೆ ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗಾಗಿ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"ವಾಹಕ ಸೇವೆಗಳಿಗೆ ಪ್ರತಿಬಂಧಿಸಿ"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"ವಾಹಕ ಸೇವೆಗಳನ್ನು ಪ್ರತಿಬಂಧಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"ಅಡಚಣೆ ಮಾಡಬೇಡಿಯನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಓದಲು ಮತ್ತು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ವೀಕ್ಷಣಾ ಅನುಮತಿಯ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ಆ್ಯಪ್‌ಗಾಗಿ ಅನುಮತಿ ಬಳಕೆಯನ್ನು ಪ್ರಾರಂಭಿಸಲು ಹೊಂದಿರುವವರಿಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯ ಆ್ಯಪ್‌ಗಳಿಗೆ ಎಂದಿಗೂ ಅಗತ್ಯವಿರುವುದಿಲ್ಲ."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ಅನುಮತಿಯ ನಿರ್ಧಾರಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ಸ್ಕಿಪ್‌"</string>
     <string name="no_matches" msgid="6472699895759164599">"ಯಾವುದೇ ಹೊಂದಿಕೆಗಳಿಲ್ಲ"</string>
     <string name="find_on_page" msgid="5400537367077438198">"ಪುಟದಲ್ಲಿ ಹುಡುಕಿ"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# ಹೊಂದಾಣಿಕೆ}one{{total} ರಲ್ಲಿ #}other{{total} ರಲ್ಲಿ #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"ಮುಗಿದಿದೆ"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"ಹಂಚಲಾದ ಸಂಗ್ರಹಣೆಯನ್ನು ಅಳಿಸಲಾಗುತ್ತಿದೆ…"</string>
     <string name="share" msgid="4157615043345227321">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ (ಮುಂದಿನ ಅಲಾರಮ್)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"ನೀವು ಆಫ್ ಮಾಡುವವರೆಗೆ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"ನೀವು ಆಫ್ ಮಾಡುವವರೆಗೂ ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ಸಂಕುಚಿಸು"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ಸ್ಥಗಿತಕಾಲ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ವಾರದ ರಾತ್ರಿ"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ವಾರಾಂತ್ಯ"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ಕರೆಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಗಳು ವೈಬ್ರೇಟ್‌ ಆಗುತ್ತವೆ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ಕರೆಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಲಾಗುತ್ತದೆ"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"ಸಿಸ್ಟಂ ಬದಲಾವಣೆಗಳು"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಮೋಡ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಮರೆಮಾಡುತ್ತಿದೆ"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಮತ್ತು ಬದಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಬದಲಾಗಿದೆ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ಏನನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ ಎಂಬುದನ್ನು ಪರೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ಸಿಸ್ಟಂ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ಸರಿ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ಆಫ್ ಮಾಡಿ"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ಇನ್ನಷ್ಟು ತಿಳಿಯಿರಿ"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ವರ್ಧಿತ ಅಧಿಸೂಚನೆಗಳು Android 12 ರಲ್ಲಿ Android ಅಡಾಪ್ಟಿವ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ಬದಲಾಯಿಸಿವೆ. ಈ ವೈಶಿಷ್ಟ್ಯವು ಸೂಚಿಸಿದ ಕ್ರಿಯೆಗಳು ಮತ್ತು ಪ್ರತ್ಯುತ್ತರಗಳನ್ನು ತೋರಿಸುತ್ತದೆ ಮತ್ತು ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಯೋಜಿಸುತ್ತದೆ.\n\nವರ್ಧಿತ ಅಧಿಸೂಚನೆಗಳು ಸಂಪರ್ಕ ಹೆಸರುಗಳು ಮತ್ತು ಸಂದೇಶಗಳಂತಹ ವೈಯಕ್ತಿಕ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆ ವಿಷಯವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು. ಈ ವೈಶಿಷ್ಟ್ಯವು ಫೋನ್ ಕರೆಗಳಿಗೆ ಉತ್ತರಿಸುವುದು ಮತ್ತು \'ಅಡಚಣೆ ಮಾಡಬೇಡಿ\' ಅನ್ನು ನಿಯಂತ್ರಿಸುವಂತಹ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಜಾಗೊಳಿಸಬಹುದು ಅಥವಾ ಪ್ರತಿಕ್ರಿಯಿಸಬಹುದು."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ದೈನಂದಿನ ಸ್ಥಿತಿಯ ಮಾಹಿತಿಯ ಅಧಿಸೂಚನೆ"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ಚಾರ್ಜ್‌ಗೆ ಮೊದಲೆ ಬ್ಯಾಟರಿ ಮುಗಿದು ಬಿಡಬಹುದು"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ಬ್ಯಾಟರಿ ಅವಧಿ ಹೆಚ್ಚಿಸಲು ಬ್ಯಾಟರಿ ಸೇವರ್ ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -2253,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ಭಾಷೆಯಿಂದ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ಭಾಷೆಗೆ ಸಂದೇಶವನ್ನು ಅನುವಾದಿಸಲಾಗಿದೆ."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ಹಿನ್ನೆಲೆ ಚಟುವಟಿಕೆ"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ ಹಾಗೂ ಬ್ಯಾಟರಿಯನ್ನು ಹೆಚ್ಚು ಬಳಸುತ್ತಿದೆ. ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದ್ದು ಬ್ಯಾಟರಿ ಖಾಲಿ ಮಾಡುತ್ತಿದೆ. ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ಬಹಳ ಸಮಯದಿಂದ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ. ಪರಿಶೀಲಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ಸಕ್ರಿಯ ಆ್ಯಪ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ಈ ಸಾಧನದಿಂದ ಕ್ಯಾಮರಾ ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index a7f8cb4..07d62b5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"3자 통화"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"원하지 않는 통화 수신 거부"</string>
     <string name="CndMmi" msgid="185136449405618437">"통화 번호 전달"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"방해 금지 모드"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"발신자 번호가 기본적으로 제한됨으로 설정됩니다. 다음 통화: 제한됨"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"발신자 번호가 기본적으로 제한됨으로 설정됩니다. 다음 통화: 제한되지 않음"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"발신자 번호가 기본적으로 제한되지 않음으로 설정됩니다. 다음 통화: 제한됨"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"캘린더에 액세스"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS 메시지 전송 및 보기"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"파일 및 문서"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"기기의 파일 및 문서에 액세스"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"음악 및 기타 오디오"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"기기에 있는 오디오 파일에 액세스"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"사진 및 동영상"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"계속하려면 화면 잠금용 사용자 인증 정보를 입력하세요"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"지문의 일부만 감지됨"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"지문을 인식할 수 없습니다. 다시 시도해 주세요."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"지문 센서를 닦은 후 다시 시도해 보세요."</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"센서를 닦은 후 다시 시도해 보세요."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"센서 위에 손가락을 좀 더 오래 올려놓으세요."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"손가락을 너무 느리게 움직였습니다. 다시 시도해 주세요."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"다른 지문으로 시도"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"너무 밝음"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"지문을 등록할 때마다 손가락을 조금씩 이동하세요."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"지문이 인식되지 않습니다."</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"센서 위에 손가락을 좀 더 오래 올려놓으세요."</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"지문이 인증됨"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"얼굴이 인증되었습니다"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"얼굴이 인증되었습니다. 확인을 누르세요"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"보유자가 이동통신사 메시지 서비스의 최상위 인터페이스에 고정할 수 있습니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"이동통신사 서비스 사용"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"권한을 가진 애플리케이션에서 이동통신사 서비스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"방해 금지 모드에 접근"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"앱에서 방해 금지 모드 설정을 읽고 작성하도록 허용합니다."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"권한 사용 보기 시작"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"앱의 권한 사용을 시작하려면 보유자를 허용하세요. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"권한 결정 보기 시작"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"건너뛰기"</string>
     <string name="no_matches" msgid="6472699895759164599">"검색결과 없음"</string>
     <string name="find_on_page" msgid="5400537367077438198">"페이지에서 찾기"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{#개 일치}other{총 {total}개 중 #번째}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"완료"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"공유 저장공간 지우는 중…"</string>
     <string name="share" msgid="4157615043345227321">"공유"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>까지"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(다음 알람)까지"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"사용 중지할 때까지"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"방해 금지 모드를 사용 중지할 때까지"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"접기"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"방해 금지 모드"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"다운타임"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"평일 밤"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"주말"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"전화 및 알림이 오면 진동이 사용됩니다."</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"전화 및 알림 소리가 음소거됩니다."</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"시스템 변경사항"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"방해 금지 모드"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"새로운 기능: 방해 금지 모드로 알림 숨기기"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"자세히 알아보고 변경하려면 탭하세요."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"방해 금지 모드 변경"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"차단된 항목을 확인하려면 탭하세요."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"시스템"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"설정"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"확인"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"사용 중지"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"자세히 알아보기"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12에서는 Android 적응형 알림이 개선된 알림으로 대체됩니다. 이 기능은 추천 작업과 답장을 표시하고 알림을 정리해 줍니다.\n\n개선된 알림은 연락처 이름과 메시지 등 개인 정보가 포함된 알림 내용에 액세스할 수 있습니다. 또한 전화를 받고 방해 금지 모드를 제어하는 등 알림을 닫거나 처리하는 것도 가능합니다."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"루틴 모드 정보 알림"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"평소에 충전하는 시간 전에 배터리가 소진될 수 있습니다."</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"배터리 수명을 연장하기 위해 절전 모드가 활성화되었습니다."</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> 앱이 백그라운드에서 실행 중이며 배터리를 소모하고 있습니다. 확인하려면 탭하세요."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> 앱이 백그라운드에서 오랫동안 실행 중입니다. 확인하려면 탭하세요."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"활성 상태의 앱 확인"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"이 기기에서 카메라에 액세스할 수 없습니다."</string>
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 577626d..1111975 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Үч тараптуу чалуу"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Жагымсыз, тажатма чалууларды четке кагуу"</string>
     <string name="CndMmi" msgid="185136449405618437">"Чалуучу номерди жеткирүү"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Тынчымды алба"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Номурду аныктоонун демейки абалы \"чектелген\" деп коюлган. Кийинки чалуу: Чектелген"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Номурду аныктоонун демейки абалы \"чектелген\" деп коюлган. Кийинки чалуу: Чектелбейт"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Номурду аныктоонун демейки абалы \"чектелбейт\" деп коюлган. Кийинки чалуу: Чектелген"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"жылнаамаңызды пайдалануу"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS билдирүүлөрдү жиберүү жана көрсөтүү"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлдар жана документтер"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"түзмөгүңүздөгү файлдары жана документтерди колдонуу"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка жана башка аудио"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"түзмөгүңүздөгү аудио файлдарга мүмкүнчүлүк алуу"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Сүрөттөр жана видеолор"</string>
@@ -454,9 +453,9 @@
     <string name="permdesc_recordBackgroundAudio" msgid="1992623135737407516">"Бул колдонмо каалаган убакта микрофон менен аудио файлдарды жаздыра алат."</string>
     <string name="permlab_sim_communication" msgid="176788115994050692">"SIM-картага буйруктарды жөнөтүү"</string>
     <string name="permdesc_sim_communication" msgid="4179799296415957960">"Колдонмого SIM-картага буйруктарды жөнөтүү мүмкүнчүлүгүн берет. Бул абдан кооптуу."</string>
-    <string name="permlab_activityRecognition" msgid="1782303296053990884">"кыймыл-аракетти аныктоо"</string>
+    <string name="permlab_activityRecognition" msgid="1782303296053990884">"Кыймыл-аракетти аныктоо"</string>
     <string name="permdesc_activityRecognition" msgid="8667484762991357519">"Бул колдонмо кыймыл-аракетиңизди аныктап турат."</string>
-    <string name="permlab_camera" msgid="6320282492904119413">"сүрөт жана видео тартуу"</string>
+    <string name="permlab_camera" msgid="6320282492904119413">"Сүрөт жана видео тартуу"</string>
     <string name="permdesc_camera" msgid="5240801376168647151">"Бул колдонмо иштеп жатканда камера менен сүрөт же видеолорду тарта алат."</string>
     <string name="permlab_backgroundCamera" msgid="7549917926079731681">"Фондо сүрөткө жана видеого тартат"</string>
     <string name="permdesc_backgroundCamera" msgid="1615291686191138250">"Бул колдонмо каалаган убакта камера менен сүрөт же видеолорду тарта алат."</string>
@@ -539,16 +538,16 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Колдонмого планшеттин Bluetooth конфигурацияларын көрүү, жупталган түзмөктөр менен байланыш түзүү жана кабыл алуу уруксатын берет."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Android TV түзмөгүңүздөгү Bluetooth конфигурациясын көрүп, жупташтырылган түзмөктөргө туташууга жана туташуу сурамын кабыл алууга колдонмого уруксат берет."</string>
     <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Колдонмого телефондун Bluetooth конфигурацияларын көрүү, жупташкан түзмөктөр менен туташуу түзүү жана кабыл алуу уруксатын берет."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"жакын жердеги Bluetooth түзмөктөрүн аныктоо жана жупташтыруу"</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"Жакын жердеги Bluetooth түзмөктөрүн таап, туташуу"</string>
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Колдонмого жакын жердеги Bluetooth түзмөктөрүн аныктап, жупташтырууга уруксат берет"</string>
-    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"жупташтырылган Bluetooth түзмөктөрү"</string>
-    <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Колдонмого жупташтырылган Bluetooth түзмөктөрү менен байланышууга уруксат берет"</string>
+    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Туташып турган Bluetooth түзмөктөрүнө байланышуу"</string>
+    <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Колдонмого туташкан Bluetooth түзмөктөрүнө байланышканга уруксат берет"</string>
     <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"жакын жердеги Bluetooth түзмөктөрүнө жарнамалоо"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Колдонмого жакын жердеги Bluetooth түзмөктөрүнө жарнама көрсөтүүгө мүмкүндүк берет"</string>
-    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктоо"</string>
+    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктоо"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Колдонмо кең тилкелүү тармак аркылуу туташа турган жакын жердеги түзмөктөрдү аныктай алат"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"жакын жердеги Wi‑Fi түзмөктөрү менен байланышуу"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Колдонмого жарнама көрсөтүүгө, байланышууга жана жакын жердеги Wi‑Fi түзмөктөрүн аныктоого мүмкүндүк берет"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Жакын жердеги Wi‑Fi түзмөктөрүнө байланышуу"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Колдонмо жакын жердеги Wi-Fi түзмөктөргө туташып, алардын жайгашкан жерин аныктап, ар кандай нерселерди өткөрө алат."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Тандалган NFC төлөм кызматы жөнүндө маалымат"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Колдонмого катталган жардам же көздөлгөн жерге маршрут сыяктуу тандалган nfc төлөм кызматы жөнүндө маалыматты алууга уруксат берүү."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication көзөмөлү"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Улантуу үчүн экрандын кулпусун киргизиңиз"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Манжа изи жарым-жартылай аныкталды"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Манжа изи иштелбей койду. Кайталап көрүңүз."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Манжа изинин сенсорун тазалап, кайра аракет кылыңыз"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Сенсорду тазалап, кайра аракет кылыңыз"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Сенсорду катуу басыңыз"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Манжа өтө жай жылды. Кайталап көрүңүз."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Башка манжа изин байкап көрүңүз"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Өтө жарык"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Манжаңыздын абалын ар жолкусунда бир аз өзгөртүп туруңуз"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Манжа изи таанылган жок"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Сенсорду катуу басыңыз"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Манжа изи текшерилди"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Жүздүн аныктыгы текшерилди"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Жүздүн аныктыгы текшерилди, эми \"Ырастоону\" басыңыз"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Кармоочуга оператордун билдирүү кызматынын жогорку деңгээлдеги интерфейсине байланышуу мүмкүнчүлүгүн берет. Кадимки колдонмолорго эч качан талап кылынбашы мүмкүн."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"байланыш операторунун кызматтарына туташуу"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Колдонмо байланыш операторлорунун кызматтарына туташа алат. Бул мүмкүнчүлүктү кадимки колдонмолор пайдалана алышпайт."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"\"Тынчымды алба\" режимин пайдалануу мүмкүнчүлүгүнө ээ болуу"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Колдонмого \"Тынчымды алба\" режиминин конфигурациясын окуу жана жазуу мүмкүнчүлүгүн берет."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"уруксаттын колдонулушун көрүп баштоо"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Колдонмонун пайдаланылышына уруксат берүүгө мүмкүнчүлүк берет. Кадимки колдонмолорго эч качан талап кылынбашы керек."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"уруксаттар боюнча кабыл алынган чечимдерди карап чыгуу"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Өткөрүп жиберүү"</string>
     <string name="no_matches" msgid="6472699895759164599">"Дал келүүлөр жок"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Барактан табуу"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# дал келди}other{{total} ичинен # дал келди}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Даяр"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Жалпы сактагыч тазаланууда…"</string>
     <string name="share" msgid="4157615043345227321">"Бөлүшүү"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин (кийинки ойготкуч)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Бул функция өчүрүлгөнгө чейин"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"\"Тынчымды алба\" режими өчүрүлгөнгө чейин"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Жыйнап коюу"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Тынчымды алба"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Аракетсиз убакыт"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Иш күндөрүнүн кечтери"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Дем алыш"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Чалуулар менен билдирмелер дирилдөө режиминде иштейт"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Чалуулар менен эскертмелердин үнү өчүрүлөт"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Тутум өзгөрүүлөрү"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Тынчымды алба"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Жаңы: \"Тынчымды алба\" режими билдирмелерди жашырууда"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Көбүрөөк маалымат алып, өзгөртүү үчүн таптаңыз."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Тынчымды алба\" режими өзгөрдү"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Бөгөттөлгөн нерселерди көрүү үчүн таптаңыз."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Тутум"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Жөндөөлөр"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Макул"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Өчүрүү"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Кененирээк"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 версиясында ыңгайлаштырылуучу билдирмелер жакшыртылган билдирмелерге алмаштырылды. Бул функция ыкчам аракеттерди жана жоопторду көрсөтүп, билдирмелериңизди иреттейт.\n\nЖакшыртылган билдирмелер бардык билдирмелердин мазмунун, ошондой эле байланыштардын аты-жөнү жана билдирүүлөрү сыяктуу жеке маалыматты көрө алат. Ошондой эле, бул функция билдирмелерди жаап, баскычтарын басып, телефон чалууларга жооп берип жана \"Тынчымды алба\" функциясын башкара алат."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Режимдин адаттагы билдирмеси"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея кубаттоого чейин отуруп калышы мүмкүн"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батареянын отуруп калбашы үчүн Батареяны үнөмдөгүч режими иштетилди"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> фондо иштеп, батареяны отургузуп жатат. Көрүү үчүн таптап коюңуз."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> колдонмосу көп убакыттан бери фондо иштеп жатат. Көрүү үчүн таптап коюңуз."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Жигердүү колдонмолорду карап чыгуу"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Бул түзмөктөгү камераны колдонууга болбойт"</string>
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 090bde9..0e5a781 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"ການໂທສາມສາຍ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"ປະຕິເສດສາຍທີ່ບໍ່ຕ້ອງການຮັບ"</string>
     <string name="CndMmi" msgid="185136449405618437">"ການສົ່ງໝາຍເລກທີ່ໂທ"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ຫ້າມລົບກວນ"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ໝາຍເລກຜູ່ໂທຖືກຕັ້ງຄ່າເລີ່ມຕົ້ນໃຫ້ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ຖືກຈຳກັດ"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ໝາຍເລກຜູ່ໂທ ໄດ້ຮັບການຕັ້ງຄ່າເລີ່ມຕົ້ນເປັນ ຖືກຈຳກັດ. ການໂທຄັ້ງຕໍ່ໄປ: ບໍ່ຖືກຈຳກັດ."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Caller ID ໂດຍເລີ່ມຕົ້ນຖືກປັບໃຫ້ບໍ່ມີການປິດກັ້ນ. ການໂທຕໍ່ໄປ:ປິດກັ້ນ"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ອະນຸຍາດໃຫ້ຜູ້ຖືຜູກ​ພັນ​ກັບຕົວ​ປະ​ສານລະດັບສູງສຸດຂອງບໍລິການສົ່ງ​ຂໍ້​ຄວາມ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"ປະ​ຕິ​ບັດ​ຕາມ​ການ​ບໍ​ລິ​ການ​​ຂອງ​ບໍ​ລິ​ສັດ​ເຄືອ​ຂ່າຍ​ມື​ຖື"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"ອະ​ນຸ​ຍາດ​ໃຫ້​ເຈົ້າ​ຂອງ​ປະ​ຕິ​ບັດ​ຕາມ​ການ​ບໍ​ລິ​ການ​​ຂອງ​ບໍ​ລິ​ສັດ​ເຄືອ​ຂ່າຍ​ມື​ຖື. ບໍ່​ຄວນ​ຈະໃຊ້​ໃນ​ແອັບ​ທົ່ວ​ໄປ."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"​ເຂົ້າ​ເຖິງ  ບໍ່​ລົບ​ກວນ"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ອະນຸຍາດ​​ໃຫ້​ແອັບ​ອ່ານ​ ​ແລະ​ຂຽນການກນຳ​ດຄ່າ ບໍ່​ລົບ​ກວນ."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ເລີ່ມການໃຊ້ສິດອະນຸຍາດການເບິ່ງ"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ອະນຸຍາດໃຫ້ຜູ້ຖືເລີ່ມການໃຊ້ສິດອະນຸຍາດສຳລັບແອັບໃດໜຶ່ງໄດ້. ແອັບປົກກະຕິບໍ່ຄວນຕ້ອງໃຊ້."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ເລີ່ມເບິ່ງການຕັດສິນໃຈການອະນຸຍາດ"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ຂ້າມ"</string>
     <string name="no_matches" msgid="6472699895759164599">"ບໍ່ພົບຜົນການຊອກຫາ"</string>
     <string name="find_on_page" msgid="5400537367077438198">"ຊອກໃນໜ້າ"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{ກົງກັນ # ລາຍການ}other{# ຈາກທັງໝົດ {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"ແລ້ວໆ"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"ກຳລັງລຶບບ່ອນຈັດເກັບຂໍ້ມູນທີ່ແບ່ງປັນ…"</string>
     <string name="share" msgid="4157615043345227321">"ແບ່ງປັນ"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"ຈົນ​ຮອດ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"ຈົນ​ກ​່​ວາ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ສັນ​ຍານ​ເຕືອນ​ຕໍ່ໄປ​)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"ຈົນກວ່າທ່ານຈະປິດ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"ຈົນ​ກ່​ວາ​ທ່ານ​ປິດ​ຫ້າມ​ລົບ​ກວນ"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ຫຍໍ້"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ຫ້າມ​ລົບ​ກວນ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"​ເວ​ລາ​ປິດ​ເຮັດ​ວຽກ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ຄ່ຳ​ຄືນ​ໃນ​ອາ​ທິດ"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ທ້າຍອາທິດ"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ການໂທ ແລະ ການແຈ້ງເຕືອນຈະສັ່ນ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ການໂທ ແລະ ການແຈ້ງເຕືອນຈະບໍ່ມີສຽງ"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"ການປ່ຽນແປງລະບົບ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ຫ້າມລົບກວນ"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"ໃໝ່: ໂໝດຫ້າມລົບກວນຈະເຊື່ອງການແຈ້ງເຕືອນໄວ້"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ ແລະ ປ່ຽນແປງ."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"ປ່ຽນໂໝດຫ້າມລົບກວນແລ້ວ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ແຕະເພື່ອກວດສອບວ່າມີຫຍັງຖືກບລັອກໄວ້ແດ່."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ລະບົບ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ການຕັ້ງຄ່າ"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ຕົກລົງ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ປິດໄວ້"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ສຶກສາເພີ່ມເຕີມ"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"ການແຈ້ງເຕືອນແບບປັບຕົວໄດ້ຂອງ Android ຖືກແທນທີ່ດ້ວຍການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນໃນ Android 12 ແລ້ວ. ຄຸນສົມບັດນີ້ສະແດງຄຳສັ່ງ ແລະ ການຕອບກັບທີ່ແນະນຳ ແລະ ຈັດລະບຽບການແຈ້ງເຕືອນຂອງທ່ານ.\n\nການແຈ້ງເຕືອນທີ່ປັບປຸງໃຫ້ດີຂຶ້ນສາມາດເຂົ້າເຖິງເນື້ອຫາການແຈ້ງເຕືອນໄດ້, ຮວມທັງຂໍ້ມູນສ່ວນຕົວ ເຊັ່ນ: ຊື່ຜູ້ຕິດຕໍ່ ແລະ ຂໍ້ຄວາມ. ຄຸນສົມບັດນີ້ສາມາດປິດ ຫຼື ຕອບກັບຫາການແຈ້ງເຕືອນໄດ້ນຳ ເຊັ່ນ: ການຮັບສາຍໂທລະສັບ ແລະ ຄວບຄຸມໂໝດຫ້າມລົບກວນ."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ການແຈ້ງເຕືອນຂໍ້ມູນໂໝດກິດຈະວັດປະຈຳວັນ"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ແບັດເຕີຣີອາດໝົດກ່ອນການສາກຕາມປົກກະຕິ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ເປີດຕົວປະຢັດແບັດເຕີຣີເພື່ອຂະຫຍາຍອາຍຸແບັດເຕີຣີ"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ ແລະ ໃຊ້ແບັດເຕີຣີຫຼາຍ. ແຕະເພື່ອກວດສອບ."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງເປັນເວລາດົນແລ້ວ. ແຕະເພື່ອກວດສອບ."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ກວດສອບແອັບທີ່ເຄື່ອນໄຫວ"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ບໍ່ສາມາດເຂົ້າເຖິງກ້ອງຖ່າຍຮູບຈາກອຸປະກອນນີ້ໄດ້"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f89c429..57efdc7 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Skambinimas trimis būdais"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Nepageidaujamų įkyrių skambučių atmetimas"</string>
     <string name="CndMmi" msgid="185136449405618437">"Skambinimo numerio pristatymas"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Netrukdyti"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Skambintojo ID numatytieji nustatymai apriboti. Kitas skambutis: apribotas"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Skambintojo ID pagal numatytuosius nustatymus yra apribotas. Kitas skambutis: neapribotas"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Skambintojo ID pagal numatytuosius nustatymus nustatomas į neapribotą. Kitas skambutis: apribotas"</string>
@@ -539,9 +540,9 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Leidžiama programai peržiūrėti „Bluetooth“ konfigūraciją planšetiniame kompiuteryje ir užmegzti bei priimti ryšius iš susietų įrenginių."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Programai leidžiama peržiūrėti „Bluetooth“ konfigūraciją „Android TV“ įrenginyje ir užmegzti bei priimti ryšius iš susietų įrenginių."</string>
     <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Leidžiama programai peržiūrėti „Bluetooth“ konfigūraciją telefone ir užmegzti bei priimti ryšius iš susietų įrenginių."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"„Bluetooth“ įr. netoliese aptikimas ir susiejimas"</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"aptikti „Bluetooth“ įr. netoliese ir susieti"</string>
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Leidžiama programai aptikti ir susieti „Bluetooth“ įrenginius netoliese"</string>
-    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"prisijungimas prie susietų „Bluetooth“ įrenginių"</string>
+    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"prisijungti prie susietų „Bluetooth“ įrenginių"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Leidžiama programai prisijungti prie susietų „Bluetooth“ įrenginių"</string>
     <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"reklamuoti netoliese es. „Bluetooth“ įrenginiuose"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Programai leidžiama reklamuoti netoliese esančiuose „Bluetooth“ įrenginiuose"</string>
@@ -738,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Leidžiama savininkui susisaistyti su aukščiausio lygio operatoriaus susirašinėjimo paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"susaistyti su operatoriaus paslaugomis"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Savininkui leidžiama susisaistyti su operatoriaus paslaugomis. To niekada neturėtų prireikti naudojant įprastas programas."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"pasiekti „Do Not Disturb“"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Leidžiama programai skaityti ir rašyti „Do Not Disturb“ konfigūraciją."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"pradėti peržiūrėti leidimo naudojimą"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Leidžia savininkui pradėti naudoti programos leidimą. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"pradėti sprendimų dėl leidimų peržiūrą"</string>
@@ -1503,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Praleisti"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nėra atitikčių"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Ieškoti puslapyje"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# atitiktis}one{# iš {total}}few{# iš {total}}many{# iš {total}}other{# iš {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Atlikta"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Ištrinama bendrinama saugykla…"</string>
     <string name="share" msgid="4157615043345227321">"Bendrinti"</string>
@@ -1869,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (kitas signalas)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Kol išjungsite"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Kol neišjungsite režimo „Netrukdyti“"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Sutraukti"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Netrukdyti"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Prastova"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Darbo dienos vakarą"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Savaitgalį"</string>
@@ -2035,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Skambučiai ir pranešimai vibruos"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Skambučiai ir pranešimai bus nutildyti"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistemos pakeitimai"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Netrukdymo režimas"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Naujiena: naudojant netrukdymo režimą pranešimai slepiami"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Palieskite, kad sužinotumėte daugiau ir pakeistumėte."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Netrukdymo režimas pakeistas"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Palieskite, kad patikrintumėte, kas blokuojama."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Nustatymai"</string>
@@ -2052,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Gerai"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Išjungti"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Sužinokite daugiau"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"12 versijos „Android“ patobulinti pranešimai pakeitė „Android“ prisitaikančius pranešimus. Ši funkcija rodo siūlomus veiksmus bei atsakymus ir tvarko jūsų pranešimus.\n\nPatobulintų pranešimų funkcija gali pasiekti pranešimų turinį, įskaitant asmens informaciją (pvz., kontaktų vardus ir pranešimus). Ši funkcija taip pat gali atsisakyti pranešimų arba į juos atsakyti, pvz., atsakyti į telefono skambučius ir valdyti netrukdymo režimą."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Veiksmų sekos režimo informacijos pranešimas"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akumuliatoriaus energija gali išsekti prieš įprastą įkrovimą"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Akumuliatoriaus tausojimo priemonė suaktyvinta, kad akumuliatorius veiktų ilgiau"</string>
@@ -2258,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"„<xliff:g id="APP">%1$s</xliff:g>“ veikia fone ir eikvoja akumuliatoriaus energiją. Palieskite ir peržiūrėkite."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"„<xliff:g id="APP">%1$s</xliff:g>“ ilgą laiką veikia fone. Palieskite ir peržiūrėkite."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Peržiūrėkite aktyvias programas"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nepavyksta pasiekti fotoaparato iš šio įrenginio"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 030144b..11e6cfa 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -71,6 +71,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Trīsvirzienu zvanīšana"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Nevēlamu traucējošu zvanu noraidīšana"</string>
     <string name="CndMmi" msgid="185136449405618437">"Zvanīšanas numuru piegāde"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Netraucēt"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Zvanītāja ID noklusējuma vērtība ir Ierobežots. Nākamais zvans: ierobežots."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Zvanītāja ID noklusējumi ir iestatīti uz Ierobežots. Nākamais zvans: nav ierobežots"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Zvanītāja ID noklusējumi ir iestatīti uz Nav ierobežots. Nākamais zvans: ierobežots"</string>
@@ -305,10 +306,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"piekļūt jūsu kalendāram"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Īsziņas"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sūtīt un skatīt īsziņas"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Faili un dokumenti"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"piekļuve failiem un dokumentiem jūsu ierīcē"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Mūzika un cits audio saturs"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"piekļūt audio failiem jūsu ierīcē"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotoattēli un videoklipi"</string>
@@ -589,12 +588,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Lai turpinātu, ievadiet ekrāna bloķēšanas informāciju"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Tika konstatēts nepilnīgs pilna nospiedums"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nevarēja apstrādāt pirksta nospiedumu. Lūdzu, mēģiniet vēlreiz."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Notīriet pirkstu nospiedumu sensoru un mēģiniet vēlreiz"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Notīriet sensoru un mēģiniet vēlreiz"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Stingri spiediet pirkstu pie sensora"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Pārāk lēna pirksta kustība. Lūdzu, mēģiniet vēlreiz."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Izmēģiniet citu pirksta nospiedumu"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Pārāk spilgts"</string>
@@ -602,10 +598,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Katru reizi mazliet mainiet pirksta pozīciju."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Pirksta nospiedums netika atpazīts"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Stingri spiediet pirkstu pie sensora"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Pirksta nospiedums tika autentificēts."</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Seja autentificēta"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Seja ir autentificēta. Nospiediet pogu Apstiprināt."</string>
@@ -744,6 +738,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Ļauj īpašniekam izveidot savienojumu ar mobilo sakaru operatora ziņojumapmaiņas pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"saistīšana ar mobilo sakaru operatoru pakalpojumiem"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Atļauj īpašniekam izveidot savienojumu ar mobilo sakaru operatoru pakalpojumiem. Parastām lietotnēm šīs atļauja nekad nav nepieciešama."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"piekļūt režīmam “Netraucēt”"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ļauj lietotnei lasīt un rakstīt režīma “Netraucēt” konfigurāciju."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Datu skatīšana par izmantojamajām atļaujām"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ļauj atļaujas īpašniekam sākt lietotnes atļauju izmantošanu. Parastām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"Skatīt darbības ar atļaujām"</string>
@@ -1509,8 +1505,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Izlaist"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nav atbilstību"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Atrast lapā"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# atbilstība}zero{# no {total}}one{# no {total}}other{# no {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Gatavs"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Notiek koplietotās krātuves dzēšana…"</string>
     <string name="share" msgid="4157615043345227321">"Kopīgot"</string>
@@ -1875,8 +1870,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Līdz <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Līdz plkst. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nākamais signāls)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Līdz brīdim, kad izslēgsiet"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Līdz izslēgsiet statusu “Netraucēt”"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Sakļaut"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Netraucēt"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Dīkstāve"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Darbadienas vakarā"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Nedēļas nogalē"</string>
@@ -2041,7 +2038,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Zvaniem un paziņojumiem tiks aktivizēta vibrācija."</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Zvanu un paziņojumu signāla skaņa būs izslēgta."</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistēmas izmaiņas"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Netraucēt"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Jaunums: režīmā “Netraucēt” paziņojumi tiek paslēpti"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Pieskarieties, lai uzzinātu vairāk un veiktu izmaiņas."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režīms “Netraucēt” ir mainīts"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Pieskarieties, lai uzzinātu, kas tiek bloķēts."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistēma"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Iestatījumi"</string>
@@ -2058,6 +2058,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Labi"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Izslēgt"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Uzzināt vairāk"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android adaptīvie paziņojumi ir aizstāti ar funkciju “Uzlabotie paziņojumi” operētājsistēmā Android 12. Šī funkcija parāda ieteiktās darbības un atbildes, kā arī kārto jūsu paziņojumus.\n\nFunkcija “Uzlabotie paziņojumi” var piekļūt paziņojumu saturam, tostarp personas informācijai, piemēram, kontaktpersonu vārdiem un ziņojumiem. Šī funkcija var arī noraidīt paziņojumus vai atbildēt uz tiem, piemēram, atbildēt uz tālruņa zvaniem vai pārvaldīt funkciju “Netraucēt”."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informatīvs paziņojums par akumulatoru"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Akumulators var izlādēties pirms parastā uzlādes laika"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Aktivizēts akumulatora enerģijas taupīšanas režīms, lai palielinātu akumulatora darbības ilgumu"</string>
@@ -2264,6 +2265,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> darbojas fonā un patērē akumulatora enerģiju. Pieskarieties, lai to pārskatītu."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ilgi darbojas fonā. Pieskarieties, lai to pārskatītu."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Pārbaudiet aktīvās lietotnes"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nevar piekļūt kamerai no šīs ierīces"</string>
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index a67a522..2f00cc7 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Повикување на три начини"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Одбивање несакани вознемирувачки повици"</string>
     <string name="CndMmi" msgid="185136449405618437">"Испорака на повикувачки број"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Не вознемирувај"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Стандардно, ID на повикувач е скриен. Следен повик: скриен"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Стандардно, ID на повикувач е скриен. Следен повик: не е скриен"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Стандардно, ID на повикувач не е скриен. Следен повик: скриен"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"пристапува до календарот"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"испраќа и прикажува SMS-пораки"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Датотеки и документи"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"да пристапува до датотеки и документи на уредот"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и друго аудио"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"да пристапува до аудиодатотеки на вашиот уред"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фотографии и видеа"</string>
@@ -391,7 +390,7 @@
     <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"Апликацијава може да се појави врз други апликации"</string>
     <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"Апликацијава може да се појави врз други апликации или делови од екранот. Тоа може да го попречи нормалното користење на апликацијата и да го смени начинот на кој се појавуваат другите апликации."</string>
     <string name="permlab_runInBackground" msgid="541863968571682785">"извршување во заднина"</string>
-    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Апликацијава може да се извршува во заднина. Тоа може побрзо да ја троши батеријата."</string>
+    <string name="permdesc_runInBackground" msgid="4344539472115495141">"Апликацијава може да работи во заднина. Тоа може побрзо да ја троши батеријата."</string>
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"користење мобилен интернет во заднина"</string>
     <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"Апликацијава може да користи мобилен интернет во заднина. Тоа може да го зголеми користењето мобилен интернет."</string>
     <string name="permlab_persistentActivity" msgid="464970041740567970">"направи апликацијата постојано да биде активна"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"да ја одреди релативната положба помеѓу уредите со ултраширок појас во близина"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Дозволува апликацијата да ја одреди релативната положба помеѓу уредите со ултраширок појас во близина"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"да има интеракција со уредите со Wi‑Fi во близина"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозволува апликацијата да рекламира, да се поврзува и да ја одредува релативната положба уредите со Wi‑Fi во близина"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Дозволува апликацијата да рекламира, да се поврзува и да ја одредува релативната положба на уреди со Wi‑Fi во близина"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Информации за претпочитаната услуга за плаќање преку NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Дозволува апликацијата да добие информации за претпочитаната услуга за плаќање преку NFC, како регистрирани помагала и дестинација на маршрутата."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"контролирај комуникација на блиско поле"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Внесете го заклучувањето на екранот за да продолжите"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Откриен е делумен отпечаток"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Отпечатокот не може да се обработи. Обидете се повторно."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Исчистете го сензорот за отпечатоци и обидете се повторно"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Исчистете го сензорот и обидете се повторно"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Цврсто притиснете на сензорот"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Прстот се движеше премногу бавно. Обидете се повторно."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте со друг отпечаток"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Премногу светло"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Менувајте ја положбата на прстот по малку секој пат"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отпечатокот не е препознаен"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Цврсто притиснете на сензорот"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечатокот е проверен"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицето е проверено"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицето е проверено, притиснете го копчето „Потврди“"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Дозволува сопственикот да се сврзе со интерфејсот од највисоко ниво на давателот на услугата за пораки. Не треба да се користи за стандардни апликации."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"поврзи се со услуги на операторот"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Дозволува сопственикот да се поврзе со услуги на операторот. Не треба да се користи за стандардни апликации."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"пристапи до Не вознемирувај"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Дозволува апликацијата да чита и пишува конфигурација Не вознемирувај."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"започнете со користење на дозволата за приказ"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Дозволува сопственикот да почне со користење на дозволата за апликација. Не треба да се користи за стандардни апликации."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"да го стартува приказот за одлуки за дозволи"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Прескокни"</string>
     <string name="no_matches" msgid="6472699895759164599">"Нема совпаѓања"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Пронајди на страница"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# совпаѓање}one{# од {total}}other{# од {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Готово"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Бришење споделена меморија…"</string>
     <string name="share" msgid="4157615043345227321">"Сподели"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (следниот аларм)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Додека не го исклучите"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Додека не го исклучите Не вознемирувај"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Собери"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не вознемирувај"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Пауза"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Вечер од седмицата"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Повиците и известувањата ќе вибрираат"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Повиците и известувањата нема да имаат звук"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Системски промени"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не вознемирувај"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Ново: режимот „Не вознемирувај“ ги крие известувањата"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Допрете за да дознаете повеќе и да ги промените поставките."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Поставките за „Не вознемирувај“ се изменија"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Допрете за да проверите што е блокирано."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Поставки"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Во ред"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Исклучи"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Дознајте повеќе"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"„Подобрените известувања“ ги заменија „Адаптивните известувања на Android“ во Android 12. Оваа функција прикажува предложени дејства и одговори и ги организира вашите известувања. \n\n„Подобрените известувања“ може да пристапуваат до содржините од известувањата, вклучително и личните податоци, како што се имињата на контактите и пораките. Функцијава може и да ги отфрла или да одговара на известувањата, како на пример, да одговара на телефонски повици и да го контролира режимот „Не вознемирувај“."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Известување за информации за режимот за рутини"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батеријата може да се потроши пред вообичаеното време за полнење"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Активиран е „Штедачот на батерија“ за да се продолжи траењето на батеријата"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Пораката е преведена од <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност во заднина"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Активност во заднина"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> се извршува во заднина и ја троши батеријата. Допрете за да прегледате."</string>
-    <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> се извршува во заднина веќе долго време. Допрете за да прегледате."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> работи во заднина и ја троши батеријата. Допрете за да прегледате."</string>
+    <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> работи во заднина веќе долго време. Допрете за да прегледате."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверете ги активните апликации"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не може да се пристапи до камерата од уредов"</string>
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index ec027b9..7e95a70 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"മൂന്നുവിധത്തിൽ കോൾ ചെയ്യൽ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"ആവശ്യമില്ലാത്ത ശല്യപ്പെടുത്തൽ കോളുകൾ നിരസിക്കൽ"</string>
     <string name="CndMmi" msgid="185136449405618437">"കോൾ ചെയ്യാനുള്ള നമ്പർ ഡെലിവറി"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ശല്യം ചെയ്യരുത്"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"നിയന്ത്രിക്കേണ്ട സ്ഥിര കോളർ ഐഡികൾ. അടുത്ത കോൾ: നിയന്ത്രിച്ചിട്ടുണ്ട്"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"നിയന്ത്രിക്കേണ്ട സ്ഥിര കോളർ ഐഡികൾ. അടുത്ത കോൾ: നിയന്ത്രിച്ചിട്ടില്ല"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"നിയന്ത്രിക്കേണ്ടതല്ലാത്ത സ്ഥിര കോളർ ഐഡികൾ. അടുത്ത കോൾ: നിയന്ത്രിച്ചിട്ടുണ്ട്"</string>
@@ -546,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കൂ"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"സമീപമുള്ള അൾട്രാ-വെെഡ്ബാൻഡ് ഉപകരണങ്ങൾ തമ്മിലുള്ള ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാൻ ആപ്പിനെ അനുവദിക്കുക"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"സമീപമുള്ള വൈഫൈ ഉപകരണങ്ങളുമായി ഇടപഴകുക"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"സമീപമുള്ള വൈഫൈ ഉപകരണത്തെ കാണിക്കാനും അവയിലേക്ക് കണക്റ്റ് ചെയ്യാനും അവയുടെ ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാനും ആപ്പിനെ അനുവദിക്കൂ"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"സമീപമുള്ള വൈഫൈ ഉപകരണങ്ങൾ കാണിക്കാനും അവയിലേക്ക് കണക്റ്റ് ചെയ്യാനും അവയുടെ ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാനും ആപ്പിനെ അനുവദിക്കൂ"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"റൂട്ട് ലക്ഷ്യസ്ഥാനം, രജിസ്‌റ്റർ ചെയ്തിരിക്കുന്ന സഹായങ്ങൾ എന്നിവ പോലുള്ള, തിരഞ്ഞെടുത്ത NFC പേയ്‌മെന്റ് സേവനത്തെ സംബന്ധിച്ച വിവരങ്ങൾ ലഭിക്കാൻ ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"സമീപ ഫീൽഡുമായുള്ള ആശയവിനിമയം നിയന്ത്രിക്കുക"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ഒരു കാരിയർ സന്ദേശമയയ്‌ക്കൽ സേവനത്തിന്റെ ഉയർന്ന നിലയിലുള്ള ഇന്റർഫേസിലേക്ക് ബന്ധിപ്പിക്കാൻ ദാതാവിനെ അനുവദിക്കുന്നു. സാധാരണ അപ്ലിക്കേഷനുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"കാരിയർ സേവനങ്ങളിലേക്ക് ബന്ധിപ്പിക്കുക"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"കാരിയർ സേവനങ്ങളെ ബന്ധിപ്പിക്കാൻ ഉടമയെ അനുവദിക്കുന്നു. സാധാരണ ആപ്പ്‌സിന് ഒരിക്കലും ആവശ്യമില്ല."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"\'ശല്യപ്പെടുത്തരുത്\' ആക്സസ് ചെയ്യുക"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"\'ശല്യപ്പെടുത്തരുത്\' കോൺഫിഗറേഷൻ വായിക്കുന്നതിനും എഴുതുന്നതിനും ആപ്പിനെ അനുവദിക്കുന്നു."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"അനുമതി ഉപയോഗം കാണാൻ ആരംഭിക്കുക"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ഒരു ആപ്പിനുള്ള അനുമതി ഉപയോഗം ആരംഭിക്കാൻ ഹോൾഡറിനെ അനുവദിക്കുന്നു. സാധാരണ ആപ്പുകൾക്ക് ഒരിക്കലും ആവശ്യമില്ല."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"അനുമതിയുമായി ബന്ധപ്പെട്ട തീരുമാനങ്ങൾ കാണാൻ ആരംഭിക്കുക"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ഒഴിവാക്കുക"</string>
     <string name="no_matches" msgid="6472699895759164599">"പൊരുത്തപ്പെടലുകൾ ഒന്നുമില്ല"</string>
     <string name="find_on_page" msgid="5400537367077438198">"പേജിൽ കണ്ടെത്തുക"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# പൊരുത്തം}other{{total}-ൽ #-ാമത്തേത്}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"പൂർത്തിയായി"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"പങ്കിടുന്ന സ്‌റ്റോറേജ് മായ്‌ക്കുന്നു…"</string>
     <string name="share" msgid="4157615043345227321">"പങ്കിടുക"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ (അടുത്ത അലാറം)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"നിങ്ങൾ ഓഫാക്കുന്നത് വരെ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"\'ശല്ല്യപ്പെടുത്തരുത്\' ഓഫാക്കുന്നതുവരെ"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ചുരുക്കുക"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ശല്യപ്പെടുത്തരുത്"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"പ്രവർത്തനരഹിതമായ സമയം"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"പ്രവൃത്തിദിനരാവ്"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"വാരാന്ത്യം"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"കോളുകളും അറിയിപ്പുകളും വൈബ്രേറ്റ് ചെയ്യും"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"കോളുകളും അറിയിപ്പുകളും മ്യൂട്ട് ചെയ്യപ്പെടും"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"സിസ്‌റ്റത്തിലെ മാറ്റങ്ങൾ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ശല്യപ്പെടുത്തരുത്"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"പുതിയത്: അറിയിപ്പുകളെ \'ശല്യപ്പെടുത്തരുത്\' അദൃശ്യമാക്കുന്നു"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"കൂടുതലറിയാനും മാറ്റാനും ടാപ്പ് ചെയ്യുക."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ശല്യപ്പെടുത്തരുത്\' മാറ്റി"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"എന്തിനെയാണ് ബ്ലോക്ക് ചെയ്‌തതെന്ന് പരിശോധിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"സിസ്റ്റം"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ക്രമീകരണം"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ശരി"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ഓഫാക്കുക"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"കൂടുതലറിയുക"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12-ൽ Android അഡാപ്റ്റീവ് അറിയിപ്പുകൾക്ക് പകരം മെച്ചപ്പെടുത്തിയ അറിയിപ്പുകൾ ഉൾപ്പെടുത്തിയിരിക്കുന്നു. നിർദ്ദേശിക്കുന്ന പ്രവർത്തനങ്ങളും മറുപടികളും കാണിക്കുന്നതിനൊപ്പം ഈ ഫീച്ചർ നിങ്ങളുടെ അറിയിപ്പുകൾ ഓർഗനൈസ് ചെയ്യുന്നു.\n\nമെച്ചപ്പെടുത്തിയ അറിയിപ്പുകൾക്ക്, കോൺടാക്റ്റ് പേരുകളും സന്ദേശങ്ങളും പോലുള്ള വ്യക്തിപരമായ വിവരങ്ങൾ ഉൾപ്പെടെയുള്ള അറിയിപ്പ് ഉള്ളടക്കം ആക്‌സസ് ചെയ്യാനാകും. ഫോൺ കോളുകൾക്ക് മറുപടി നൽകുക, \'ശല്യപ്പെടുത്തരുത്\' നിയന്ത്രിക്കുക എന്നിവ പോലെ, അറിയിപ്പുകൾ ഡിസ്‌മിസ് ചെയ്യാനും അവയ്‌ക്ക് മറുപടി നൽകാനും ഈ ഫീച്ചറിന് കഴിയും."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ദിനചര്യ മോഡ് വിവരത്തെ കുറിച്ചുള്ള അറിയിപ്പ്"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"സാധാരണയുള്ളതിലും നേരത്തെ ബാറ്ററിയുടെ ചാർജ് തീർന്നേക്കാം"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ബാറ്ററി ലൈഫ് വര്‍ദ്ധിപ്പിക്കാൻ, ബാറ്ററി ലാഭിക്കൽ സജീവമാക്കി"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ആപ്പ് പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു, ഇത് ബാറ്ററി ഉപയോഗിച്ചുതീർക്കുന്നു. അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"പശ്ചാത്തലത്തിൽ <xliff:g id="APP">%1$s</xliff:g> ആപ്പ് ഒരുപാട് നേരമായി റൺ ചെയ്യുന്നു. അവലോകനം ചെയ്യാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"സജീവമായ ആപ്പുകൾ പരിശോധിക്കുക"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ഈ ഉപകരണത്തിൽ നിന്ന് ക്യാമറ ആക്‌സസ് ചെയ്യാനാകില്ല"</string>
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 5681de0..98c7ef5 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Гурван чиглэлт дуудлага"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Хүсээгүй тааламжгүй дуудлагаас татгалзах"</string>
     <string name="CndMmi" msgid="185136449405618437">"Дуудлага хийгчийн дугаарыг дамжуулах"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Бүү саад бол"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Дуудлага хийгчийн ID хязгаарлагдсан. Дараагийн дуудлага: Хязгаарлагдсан"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Дуудлага хийгчийн ID хязгаарлагдсан. Дараагийн дуудлага: Хязгаарлагдаагүй"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Дуудлага хийгчийн ID хязгаарлагдаагүй. Дараагийн дуудлага: Хязгаарлагдсан"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Эзэмшигчид зөөгч мессежийн үйлчилгээний түвшний интерфэйст холбогдохыг зөвшөөрдөг. Энгийн апп-д шаардлагагүй."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"Үүрэн холбооны үйлчилгээ үзүүлэгчтэй холбогдох"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Аливаа эзэмшигчийг үүрэн холбооны үйлчилгээ үзүүлэгчтэй холбодог. Энгийн аппд шаардлагагүй."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Бүү саад бол тохируулгад хандалт хийх"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Апп-д Бүү саад бол тохируулгыг уншиж, бичихийг зөвшөөрөх"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"зөвшөөрлийн ашиглалтыг харж эхлэх"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Эзэмшигчид аппын зөвшөөрлөө ашиглаж эхлэхийг зөвшөөрдөг. Энгийн аппуудад шаардлагагүй."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"зөвшөөрлийн шийдвэрийг хянах дэлгэцийг эхлүүлэх"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Алгасах"</string>
     <string name="no_matches" msgid="6472699895759164599">"Илэрц алга"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Хуудаснаас олох"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# тааруулах}other{{total}-н #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Дуусгах"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Хуваалцсан хадгалах санг устгаж байна…"</string>
     <string name="share" msgid="4157615043345227321">"Хуваалцах"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> хүртэл"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> хүртэл (дараагийн сэрүүлэг)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Таныг унтраах хүртэл"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"\"Бүү саад бол\"-ыг унтраах хүртэл"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Хумих"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Бүү саад бол"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Сул зогсолт"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Ажлын өдрийн шөнө"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Амралтын өдөр"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Дуудлага болон мэдэгдэл чичирнэ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Дуудлага болон мэдэгдлийн дууг хаана"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Системийн өөрчлөлт"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Бүү саад бол"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Шинэ: Бүү саад бол горим мэдэгдлийг нууж байна"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Илүү ихийг мэдэж, өөрчлөхийн тулд товшино уу."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Бүү саад бол горимыг өөрчилсөн"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Блоклосон зүйлийг шалгахын тулд товшино уу."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Тохиргоо"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Унтраах"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Нэмэлт мэдээлэл авах"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Сайжруулсан мэдэгдэл нь Android 12 дахь Android-н Орчинтой тохирсон мэдэгдлийг орлосон. Энэ онцлог нь санал болгосон үйлдлүүд болон хариунуудыг харуулж, таны мэдэгдлийг цэгцэлнэ.\n\nСайжруулсан мэдэгдэл нь харилцагчийн нэр, мессеж зэрэг хувийн мэдээллийг оруулаад мэдэгдлийн контентод хандах боломжтой. Энэ онцлог мөн утасны дуудлагад хариулах болон Бүү саад бол горимыг хянах зэргээр мэдэгдлийг хаах эсвэл түүнд хариулах боломжтой."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Хэвшлийн горимын мэдээллийн мэдэгдэл"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарей ихэвчлэн цэнэглэдэг хугацаанаас өмнө дуусаж болзошгүй"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Батарейн ажиллах хугацааг уртасгахын тулд Батарей хэмнэгчийг идэвхжүүллээ"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> дэвсгэрт ажиллаж байгаа бөгөөд батарейг дуусгаж байна. Хянахын тулд товшино уу."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> дэвсгэрт удаан хугацааны турш ажиллаж байна. Хянахын тулд товшино уу."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Идэвхтэй аппуудыг шалгах"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Энэ төхөөрөмжөөс камер луу нэвтрэх боломжгүй байна"</string>
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 1c434bb..df8cbc0 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"तीन मार्गांनी कॉल करणे"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"अवांछित त्रासदायक कॉल ला नकार"</string>
     <string name="CndMmi" msgid="185136449405618437">"कॉल करणार्‍या नंबरचे वितरण"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"व्यत्यय आणू नका"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"कॉलर आयडी डीफॉल्‍ट रूपात प्रतिबंधित वर सेट असतो. पुढील कॉल: प्रतिबंधित"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"कॉलर आयडी डीफॉल्‍ट रूपात प्रतिबंधित वर सेट असतो. पुढील कॉल: प्रतिबंधित नाही"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"कॉलर आयडी डीफॉल्‍ट रूपात प्रतिबंधित नाही वर सेट असतो. पुढील कॉल: प्रतिबंधित"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"वाहक मेसेजिंग सेवेचा शीर्ष-स्तर इंटरफेस बाइंड करण्यासाठी होल्डरला अनुमती देतो. सामान्‍य अ‍ॅप्‍सकरिता हे कधीही आवश्‍यक नसते."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"वाहक सेवांवर प्रतिबद्ध करा"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"वाहक सेवांवर प्रतिबद्ध करण्यासाठी होल्डरला अनुमती देते. सामान्य ॲप्ससाठी कधीही आवश्यकता नसावी."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"व्यत्यय आणू नका अ‍ॅक्सेस करा"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"व्यत्यय आणू नका कॉंफिगरेशन वाचण्यासाठी आणि लिहिण्यासाठी ॲपला अनुमती देते."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"व्ह्यू परवानगी वापर सुरू करा"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"धारकास अ‍ॅपसाठी परवानगी वापरणे सुरू करण्याची अनुमती देते. सामान्य अ‍ॅप्ससाठी कधीही आवश्यकता नसते."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"परवानगीशी संबंधित निर्णय पाहणे सुरू करा"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"वगळा"</string>
     <string name="no_matches" msgid="6472699895759164599">"कोणत्याही जुळण्या नाहीत"</string>
     <string name="find_on_page" msgid="5400537367077438198">"पेजवर शोधा"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# जुळणी}other{{total} पैकी #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"पूर्ण केले"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"शेअर केलेले स्टोरेज मिटवत आहे…"</string>
     <string name="share" msgid="4157615043345227321">"शेअर करा"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत (पुढील अलार्म)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"तुम्ही बंद करेपर्यंत"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"तुम्ही बंद करेपर्यंत व्यत्यय आणू नका"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"संक्षिप्त करा"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"व्यत्यय आणू नका"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"डाउनटाइम"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"आठवड्याची शेवटची रात्र"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"आठवड्याच्या शेवटी"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"कॉल आणि सूचनांवर व्हायब्रेट होईल"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"कॉल आणि सूचना म्यूट केल्या जातील"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"सिस्टम बदल"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"व्यत्यय आणू नका"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"व्यत्यय आणू नका सूचना लपवत आहे"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"अधिक जाणून घेण्‍यासाठी आणि बदलण्‍यासाठी टॅप करा."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"व्यत्यय आणू नका बदलले आहे"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"काय ब्लॉक केले आहे हे तपासण्यासाठी टॅप करा."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"सिस्टम"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"सेटिंग्ज"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ओके"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"बंद करा"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"अधिक जाणून घ्या"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 मधील Android ॲडॅप्टिव्ह सूचना हे वैशिष्ट्य बदलून आता वर्धित सूचना झाले आहे. हे वैशिष्ट्य सुचवलेल्या कृती आणि उत्तरे दाखवते व तुमच्या सूचना व्यवस्थापित करते. \n\nवर्धित सूचना हे वैशिष्ट्य संपर्कांची नावे आणि मेसेज यांसारख्या वैयक्तिक माहितीसह सर्व सूचनांचा आशय ॲक्सेस करू शकते. हे वैशिष्ट्य फोन कॉलना उत्तर देणे आणि व्यत्यय आणू नका नियंत्रित करणे यांसारख्या कृती करून सूचना डिसमिस करू शकते किंवा त्यांना प्रतिसाद देऊ शकते."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"दिनक्रम मोडची माहिती सूचना"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"चार्जिंगची सामान्य पातळी गाठेपर्यंत कदाचित बॅटरी संपू शकते"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"बॅटरी लाइफ वाढवण्यासाठी बॅटरी सेव्हर सुरू केला आहे"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> हे बॅकग्राउंडमध्ये रन होत आहे आणि बॅटरी संपवत आहे. पुनरावलोकनासाठी टॅप करा."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> हे बऱ्याच कालावधीपासून बॅकग्राउंडमध्ये रन होत आहे. पुनरावलोकनासाठी टॅप करा."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ॲक्टिव्ह ॲप्स पहा"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"या डिव्हाइसवरून कॅमेरा अ‍ॅक्सेस करू शकत नाही"</string>
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index b4ce57c..b35f61a 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Panggilan tiga hala"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Penolakan panggilan mengganggu yang tidak diingini"</string>
     <string name="CndMmi" msgid="185136449405618437">"Penghantaran nombor panggilan"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Jangan ganggu"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID pemanggil secara lalainya ditetapkan kepada terhad. Panggilan seterusnya: Terhad"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID pemanggil secara lalainya ditetapkan kepada terhad. Panggilan seterusnya: Tidak terhad"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID pemanggil secara lalainya ditetapkan kepada tidak terhad. Panggilan seterusnya: Terhad"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"mengakses kalendar"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"menghantar dan melihat mesej SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fail &amp; dokumen"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"akses fail dan dokumen pada peranti anda"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzik &amp; audio lain"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"berikan akses fail audio pada peranti anda"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto &amp; video"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"tentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Benarkan apl menentukan kedudukan relatif antara peranti Ultrajalur Lebar berdekatan"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"berinteraksi dengan peranti Wi-Fi berdekatan"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Membenarkan apl mengiklankan, menyambung dan menentukan penempatan relatif peranti Wi-Fi berdekatan"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Membenarkan apl mengiklankan, menyambung dan menentukan kedudukan relatif peranti Wi-Fi berdekatan"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Maklumat Perkhidmatan Pembayaran NFC Pilihan"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Membenarkan apl mendapatkan maklumat perkhidmatan pembayaran nfc pilihan seperti bantuan berdaftar dan destinasi laluan."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"mengawal Komunikasi Medan Dekat"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Masukkan kunci skrin untuk teruskan"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Cap jari separa dikesan"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Tidak dapat memproses cap jari. Sila cuba lagi."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Bersihkan penderia cap jari dan cuba lagi"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Bersihkan penderia dan cuba lagi"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tekan dengan kuat pada penderia"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Jari digerakkan terlalu perlahan. Sila cuba lagi."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Cuba cap jari lain"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Terlalu terang"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Tukar sedikit kedudukan jari anda setiap kali pergerakan dilakukan"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Cap jari tidak dikenali"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Tekan dengan kuat pada penderia"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Cap jari disahkan"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Wajah disahkan"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Wajah disahkan, sila tekan sahkan"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi perkhidmatan pemesejan pembawa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"terikat kepada perkhidmatan pembawa"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Membenarkan pemegang terikat kepada perkhidmatan pembawa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"akses Jangan ganggu"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Membenarkan apl membaca dan menulis konfigurasi Jangan Ganggu."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"mulakan lihat penggunaan kebenaran"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Membenarkan pemegang memulakan penggunaan kebenaran untuk apl. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"mula melihat keputusan kebenaran"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Langkau"</string>
     <string name="no_matches" msgid="6472699895759164599">"Tiada padanan"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Cari di halaman"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# padanan}other{# daripada {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Selesai"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Memadamkan storan kongsi…"</string>
     <string name="share" msgid="4157615043345227321">"Kongsi"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Sehingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Sehingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (penggera akan datang)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Sehingga anda matikan"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Hingga anda mematikan Jangan Ganggu"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Runtuhkan"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Jangan ganggu"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Waktu gendala"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Malam selain hujung minggu"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hujung minggu"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Panggilan dan pemberitahuan akan bergetar"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Panggilan dan pemberitahuan akan diredamkan"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Perubahan sistem"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Jangan Ganggu"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Baharu: Jangan Ganggu menyembunyikan pemberitahuan"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Ketik untuk mengetahui lebih lanjut dan menukar tetapan."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Jangan Ganggu telah berubah"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Ketik untuk menyemak item yang disekat."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Tetapan"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Matikan"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ketahui lebih lanjut"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Pemberitahuan yang dipertingkatkan menggantikan Pemberitahuan Boleh Suai Android dalam Android 12. Ciri ini menunjukkan cadangan tindakan dan balasan, serta mengatur pemberitahuan anda.\n\nPemberitahuan yang dipertingkatkan dapat mengakses kandungan pemberitahuan, termasuk maklumat peribadi seperti nama kenalan dan mesej. Ciri ini juga dapat mengetepikan atau membalas pemberitahuan, seperti menjawab panggilan telefon dan mengawal Jangan Ganggu."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Pemberitahuan maklumat Mod Rutin"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateri mungkin habis sebelum pengecasan biasa"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Penjimat Bateri diaktifkan untuk memanjangkan hayat bateri"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mesej diterjemahkan daripada <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> kepada <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Aktiviti Latar Belakang"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Aktiviti Latar Belakang"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> sedang berjalan di latar belakang dan menghabiskan bateri. Ketik untuk menyemak."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> dijalankan di latar belakang dan melemahkan bateri. Ketik untuk semak."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g>sedang berjalan di latar belakang untuk masa yang lama. Ketik untuk menyemak."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Semak apl aktif"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Tidak dapat mengakses kamera daripada peranti ini"</string>
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index acbd498..bcd11a2 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"(၃)ယောက်ဆိုင်ပြောဆိုခြင်း"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"စိတ်အနှောက်အယှက်ဖြစ်သော မလိုလားသည့်ခေါ်ဆိုမှုများအား ငြင်းဖယ်ခြင်း"</string>
     <string name="CndMmi" msgid="185136449405618437">"ခေါ်ဆိုသောနံပါတ် ပေးပို့မှု"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"မနှောင့်ယှက်ရ"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်ထားသည်။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်ထားသည်။"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်ထားသည်။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်မထားပါ။"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ပုံသေအားဖြင့် ခေါ်ဆိုသူအိုင်ဒီ(Caller ID)အား ကန့်သတ်မထားပါ။ နောက်ထပ်အဝင်ခေါ်ဆိုမှု-ကန့်သတ်ထားသည်။"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS စာတိုစနစ်"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS စာများကို ပို့ကာ ကြည့်မည်"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"ဖိုင်နှင့် မှတ်တမ်းများ"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"သင့်စက်ရှိ ဖိုင်နှင့် မှတ်တမ်းများ သုံးခွင့်"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"သီချင်းနှင့် အခြားအသံဖိုင်"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"သင့်စက်ပေါ်ရှိ အသံဖိုင်များကို သုံးနိုင်သည်"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ဓာတ်ပုံနှင့် ဗီဒီယိုများ"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"အနီးတစ်ဝိုက်ရှိ ‘အလွန်ကျယ်ပြန့်သော လှိုင်းအလျားသုံးစက်များ’ ကြား ဆက်စပ်နေရာကို သတ်မှတ်ခြင်း"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"အနီးတစ်ဝိုက်ရှိ ‘အလွန်ကျယ်ပြန့်သော လှိုင်းအလျားသုံးစက်များ’ ကြား ဆက်စပ်နေရာကို သတ်မှတ်ရန် အက်ပ်ကို ခွင့်ပြုမည်"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"အနီးရှိ Wi-Fi စက်များနှင့် ပြန်လှန်တုံ့ပြန်ခြင်း"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"အက်ပ်ကို ကြော်ငြာရန်၊ ချိတ်ဆက်ရန်နှင့် အနီးတစ်ဝိုက်ရှိ Wi-Fi စက်များ၏ ဆက်စပ်နေရာကို သတ်မှတ်ရန် ခွင့်ပြုနိုင်သည်"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"ကြော်ငြာရန်၊ ချိတ်ဆက်ရန်နှင့် အနီးတစ်ဝိုက်ရှိ Wi-Fi စက်များ၏ နေရာကို သတ်မှတ်ရန် အက်ပ်ကို ခွင့်ပြုသည်"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"ဦးစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များ"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"အက်ပ်အား ဦစားပေး NFC ငွေပေးချေမှုဆိုင်ရာ ဝန်ဆောင်မှု အချက်အလက်များဖြစ်သည့် မှတ်ပုံတင်ထားသော အကူအညီများနှင့် သွားလာရာ လမ်းကြောင်းတို့ကို ရယူရန် ခွင့်ပြုသည်။"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communicationအား ထိန်းချုပ်ရန်"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ရှေ့ဆက်ရန် သင်၏ဖန်သားပြင် လော့ခ်ချခြင်းကို ထည့်ပါ"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"လက်ဗွေတစ်စိတ်တစ်ပိုင်းကို ရှာတွေ့သည်"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"လက်ဗွေယူ၍ မရပါ။ ထပ်စမ်းကြည့်ပါ။"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"လက်ဗွေ အာရုံခံကိရိယာကို သန့်ရှင်းပြီး ထပ်စမ်းကြည့်ပါ"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"အာရုံခံကိရိယာကို သန့်ရှင်းပြီး ထပ်စမ်းကြည့်ပါ"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"အာရုံခံကိရိယာပေါ်တွင် သေချာဖိပါ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"လက်ညှိုးအလွန်နှေးကွေးစွာ ရွေ့ခဲ့သည်။ ကျေးဇူးပြု၍ ထပ်မံကြိုးစားပါ။"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"အခြားလက်ဗွေဖြင့် စမ်းကြည့်ပါ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"အလွန် လင်းသည်"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"အကြိမ်တိုင်း သင့်လက်ချောင်း၏တည်နေရာကို အနည်းငယ်ပြောင်းပါ"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"လက်ဗွေကို မသိရှိပါ"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"အာရုံခံကိရိယာပေါ်တွင် သေချာဖိပါ"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"လက်ဗွေကို အထောက်အထား စိစစ်ပြီးပါပြီ"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"မျက်နှာ အထောက်အထားစိစစ်ပြီးပြီ၊ အတည်ပြုရန်ကို နှိပ်ပါ"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"စာပို့စာယူဆက်သွယ်ရေးဝန်ဆောင်မှုတစ်ခု၏ ထိပ်ဆုံးရှိအင်တာဖေ့စ်ဖြင့် ပူးပေါင်းရန် ပိုင်ရှင်အားခွင့်ပြုပါ။ ပုံမှန် အက်ပ်များအတွက် ဘယ်တော့မှ မလိုအပ်ပါ။"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"မိုဘိုင်းဖုန်းဝန်ဆောင်မှုပေးသူများနှင့် ပူးပေါင်းခွင့်ပြုရန်"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"မိုဘိုင်းဖုန်းဝန်ဆောင်မှုစနစ်တစ်ခုအား ပူးပေါင်းခွင့်ပြုရန် ကိုင်ဆောင်ထားသူအား ခွင့်ပြုပါ။ သာမန် အက်ပ်များ အတွက် ဘယ်တော့မှ မလိုအပ်ပါ။"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"မနှောင့်ယှက်ရန်ကို အသုံးပြုမည်"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"မနှောင့်ယှက်ရန် ချိန်ညှိမှုကို အပ်ဖ်များ ဖတ်ခြင်း ပြင်ခြင်းပြုလုပ်နိုင်ရန် ခွင့်ပြုမည်။"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"အစမြင်ကွင်း ခွင့်ပြုချက် အသုံးပြုမှု"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"အက်ပ်တစ်ခုအတွက် ခွင့်ပြုချက်စတင်အသုံးပြုမှုကို ကိုင်ဆောင်သူအား ခွင့်ပြုသည်။ ပုံမှန်အက်ပ်များအတွက် ဘယ်သောအခါမျှ မလိုအပ်ပါ။"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ခွင့်ပြုသည့် ဆုံးဖြတ်ချက်များကို စတင်ကြည့်ခြင်း"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ကျော်ရန်"</string>
     <string name="no_matches" msgid="6472699895759164599">"ထပ်တူမတွေ့ရှိပါ"</string>
     <string name="find_on_page" msgid="5400537367077438198">"စာမျက်နှာတွင်ရှာဖွေရန်"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{ကိုက်ညီမှု # ခု}other{{total} ခု အနက် # ခု}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"ပြီးပါပြီ"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"မျှဝေထားသည့် သိုလှောင်ခန်းကို ဖျက်နေသည်…"</string>
     <string name="share" msgid="4157615043345227321">"မျှဝေရန်"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> အထိ (လာမည့် နှိုးစက်)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"သင်ပိတ်လိုက်သည် အထိ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"မနှောင့်ယှက်ရန် ကိုသင်ပိတ်သည်အထိ"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ခေါက်ရန်"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"မနှောင့်ယှက်ရ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ကျချိန်"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ကြားရက်ည"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"စနေ၊ တနင်္ဂနွေ"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ခေါ်ဆိုမှုများနှင့် အကြောင်းကြားချက်များ တုန်ခါပါမည်"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ခေါ်ဆိုမှုများနှင့် အကြောင်းကြားချက်များကို အသံပိတ်ထားပါမည်"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"စနစ် အပြောင်းအလဲများ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"မနှောင့်ယှက်ရ"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"အသစ်− \'မနှောင့်ယှက်ရ\' က အကြောင်းကြားချက်များကို ဖျောက်ထားသည်"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ပိုမိုလေ့လာရန်နှင့် ပြောင်းလဲရန် တို့ပါ။"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'မနှောင့်ယှက်ရ\' ပြောင်းလဲသွားပါပြီ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ပိတ်ထားသည့်အရာများကို ကြည့်ရန် တို့ပါ။"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"စနစ်"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ဆက်တင်များ"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ပိတ်ရန်"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ပိုမိုလေ့လာရန်"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 တွင် ‘Android အလိုက်သင့် အကြောင်းကြားချက်များ’ ကို အဆင့်မြင့် အကြောင်းကြားချက်များဖြင့် အစားထိုးထားသည်။ ဤဝန်ဆောင်မှုက အကြံပြုထားသော လုပ်ဆောင်ချက်နှင့် ပြန်စာများကို ပြပေးပြီး သင်၏အကြောင်းကြားချက်များကို စီစဉ်ပေးသည်။\n\nအဆင့်မြင့် အကြောင်းကြားချက်များက အဆက်အသွယ်အမည်နှင့် မက်ဆေ့ဂျ်များကဲ့သို့ ကိုယ်ရေးကိုယ်တာအချက်လက်များ အပါအဝင် အကြောင်းကြားချက် အကြောင်းအရာကို သုံးနိုင်သည်။ ဤဝန်ဆောင်မှုက ဖုန်းခေါ်ဆိုမှုများ ဖြေခြင်းနှင့် ‘မနှောင့်ယှက်ရ’ ကို ထိန်းချုပ်ခြင်းကဲ့သို့ အကြောင်းကြားချက်များကို ပယ်နိုင်သည် (သို့) တုံ့ပြန်နိုင်သည်။"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ပုံမှန်မုဒ်အတွက် အချက်အလက်ပြသည့် အကြောင်းကြားချက်"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ပုံမှန်အားသွင်းမှုမပြုလုပ်မီ ဘက်ထရီကုန်သွားနိုင်သည်"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ဘက်ထရီသက်တမ်းကို တိုးမြှင့်ရန် \'ဘက်ထရီအားထိန်း\' စတင်ပြီးပါပြီ"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> သည် နောက်ခံတွင်ပွင့်နေပြီး ဘက်ထရီအားကုန်စေသည်။ ပြန်ကြည့်ရန် တို့ပါ။"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> သည် နောက်ခံတွင် အချိန်အတော်ကြာပွင့်နေသည်။ ပြန်ကြည့်ရန် တို့ပါ။"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ပွင့်နေသည့်အက်ပ်များ စစ်ဆေးရန်"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ကင်မရာကို ဤစက်မှ အသုံးမပြုနိုင်ပါ"</string>
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 234ead8..b6e2121 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Telefonkonferanse"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Avvisning av uønskede samtaler"</string>
     <string name="CndMmi" msgid="185136449405618437">"Levering av nummervisning"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ikke forstyrr"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Nummervisning er begrenset som standard. Neste anrop: Begrenset"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Nummervisning er begrenset som standard. Neste anrop: Ikke begrenset"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Nummervisning er ikke begrenset som standard. Neste anrop: Begrenset"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"åpne kalenderen din"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sende og lese SMS-meldinger"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer og dokumenter"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"åpne filer og dokumenter på enheten din"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musikk og annen lyd"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"få tilgang til lydfiler på enheten"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Bilder og videoer"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Skriv inn skjermlåsen for å fortsette"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Et delvis fingeravtrykk er registrert"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kunne ikke registrere fingeravtrykket. Prøv på nytt."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengjør fingeravtrykkssensoren og prøv igjen"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengjør sensoren og prøv igjen"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Trykk godt på sensoren"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du flyttet fingeren for sakte. Prøv på nytt."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Prøv et annet fingeravtrykk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"For lyst"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Endre posisjonen til fingeren litt hver gang"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Gjenkjenner ikke fingeravtrykket"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Trykk godt på sensoren"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrykket er godkjent"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansiktet er autentisert"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet er autentisert. Trykk på Bekreft"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Tillater at innehaveren binder seg til det øverste nivået av grensesnittet til en operatørtjeneste. Dette skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bind til operatørtjenester"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Lar innehaveren binde seg til operatørtjenester. Det skal aldri være nødvendig for vanlige apper."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"tilgang til Ikke forstyrr"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Lar appen lese og skrive konfigurasjon av Ikke forstyrr."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"start visning av bruk av tillatelser"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Lar innehaveren starte bruk av tillatelser for en app. Dette skal aldri være nødvendig for vanlige apper."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"starte visning av avgjørelser om tillatelser"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Hopp over"</string>
     <string name="no_matches" msgid="6472699895759164599">"Ingen treff"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Finn på side"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# treff}other{# av {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Ferdig"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Sletter delt lagring …"</string>
     <string name="share" msgid="4157615043345227321">"Del"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (neste alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Til du slår av"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Inntil du slår av Ikke forstyrr"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Skjul"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"«Ikke forstyrr»"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Pause"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Hverdagskveld"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Helg"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Anrop og varsler vibrerer"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Anrop og varsler er lydløse"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Systemendringer"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ikke forstyrr"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nytt: «Ikke forstyrr» skjuler varsler"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Trykk for å finne ut mer og endre."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ikke forstyrr er endret"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Trykk for å sjekke hva som er blokkert."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Innstillinger"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Slå av"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Finn ut mer"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Forbedrede varsler erstatter tilpassede Android-varsler i Android 12. Denne funksjonen viser foreslåtte handlinger og svar og organiserer varslene dine.\n\nForbedrede varsler har tilgang til varselinnhold, inkludert personopplysninger som kontaktnavn og meldinger. Funksjonen kan også avvise og svare på varsler, for eksempel svare på anrop og kontrollere «Ikke forstyrr»."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Varsel med informasjon om rutinemodus"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batteriet kan gå tomt før den vanlige ladingen"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparing er aktivert for å forlenge batterilevetiden"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> kjører i bakgrunnen og bruker batteri. Trykk for å gjennomgå."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> kjører lenge i bakgrunnen. Trykk for å gjennomgå."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Sjekk aktive apper"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Du har ikke tilgang til kameraet fra denne enheten"</string>
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 77257b1..0ecf8a7 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"कल गर्ने तिन तरिका"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"नचाहिएका रिसउठ्दा कलहरूको अस्वीकार"</string>
     <string name="CndMmi" msgid="185136449405618437">"कलिङ नम्बर प्रदान गर्ने"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"बाधा नगर्नुहोस्"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"सीमति गर्न डिफल्ट कलर ID, अर्को कल: सीमति गरिएको"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"कलर ID पूर्वनिर्धारितको लागि रोकावट छ। अर्को कल: रोकावट छैन"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"कलर ID पूर्वनिर्धारितदेखि प्रतिबन्धित छैन। अर्को कल: प्रतिबन्धित छ"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"धारकलाई वाहक मेसेजिङ सेवाको उच्च-स्तरको इन्टरफेसमा आबद्ध हुन अनुमति दिनुहोस्। सामान्य एपहरूको लागि कहिल्यै आवश्यकता पर्दैन।"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"वाहक सेवाहरु बाँध्न"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"होल्डरलाई वाहक सेवाहरु बाँध्न अनुमति दिनुहोस्। सामान्य अनुप्रयोगहरूको लागि यो कहिल्यै आवश्यक पर्दैन।"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"बाधा नपुर्याउँनुहोस् पहुँच गर्नुहोस्"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"बाधा नपुर्याउँनुहोस् कन्फिगरेसन पढ्न र लेख्‍नको लागि एपलाई अनुमति दिनुहोस्।"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"हेर्ने अनुमतिको प्रयोग सुरु गर्नुहोस्"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"वाहकलाई कुनै एपसम्बन्धी अनुमतिको प्रयोग सुरु गर्न दिन्छ। साधारण एपहरूलाई कहिल्यै आवश्यक नपर्नु पर्ने हो।"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"अनुमतिसम्बन्धी निर्णयहरू हेर्न सुरु गर्नुहोस्"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"छोड्नुहोस्"</string>
     <string name="no_matches" msgid="6472699895759164599">"कुनै मिलेन"</string>
     <string name="find_on_page" msgid="5400537367077438198">"पृष्ठमा फेला पार्नुहोस्"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# वटा मिल्दोजुल्दो परिणाम}other{{total} मध्ये # वटा मिल्दाजुल्दा परिणाम}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"भयो"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"साझेदारी गरिएको भण्डारण मेट्दै…"</string>
     <string name="share" msgid="4157615043345227321">"सेयर गर्नुहोस्"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> सम्म"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (अर्को अलार्म) सम्म"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"तपाईंले निष्क्रिय नपार्नुभएसम्म"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"तपाईँले बन्द नगरे सम्म बाधा नपुर्याउँनुहोस्"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"संक्षिप्त पार्नुहोस्"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"अवरोध नपुर्याउँनुहोस्"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"डाउनटाइम"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"हरेक हप्तादिनको राति"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"शनिबार"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"कल तथा सूचनाहरू आउँदा कम्पन हुने छ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"कल तथा सूचनाहरूलाई म्युट गरिने छ"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"प्रणालीसम्बन्धी परिवर्तनहरू"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"बाधा नपुऱ्याउनुहोस्"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"नयाँ: बाधा नपुर्‍याउनुहोस् नामक मोडले सूचनाहरू लुकाइरहेको छ"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"थप जान्न र परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"बाधा नपुर्‍याउनुहोस् मोड परिवर्तन भएको छ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"रोक लगाइएका कुराहरू जाँच गर्न ट्याप गर्नुहोस्‌।"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"प्रणाली"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"सेटिङहरू"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ठिक छ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"अफ गर्नुहोस्"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"थप जान्नुहोस्"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android १२ मा Android को अनुकूल पार्न मिल्ने सूचनाहरू नामक सुविधालाई परिष्कृत सूचनाहरू नामक सुविधाले प्रतिस्थापन गरेको छ। यो सुविधाले कारबाही तथा जवाफसम्बन्धी सुझाव देखाउँछ र तपाईंका सूचनाहरू व्यवस्थित गर्छ।\n\nपरिष्कृत सूचनाहरू नामक सुविधाले सूचनामा उल्लिखित सम्पर्क व्यक्तिको नाम र म्यासेज जस्ता व्यक्तिगत जानकारीलगायतका सामग्री हेर्न तथा प्रयोग गर्न सक्छ। यो सुविधाले फोन उठाउने तथा \'बाधा नपुऱ्याउनुहोस्\' मोड नियन्त्रण गर्ने कार्यसहित सूचनाहरू हटाउने वा सूचनाहरूको जवाफ दिने कार्य पनि गर्न सक्छ।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"दिनचर्या मोडको जानकारीमूलक सूचना"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"प्रायः चार्ज गर्ने समय हुनुभन्दा पहिले नै ब्याट्री सकिन सक्छ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ब्याट्रीको आयु बढाउन ब्याट्री सेभर सक्रिय गरियो"</string>
@@ -2253,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"म्यासेज <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> भाषाबाट <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> भाषामा अनुवाद गरिएको छ।"</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ब्याकग्राउन्डमा गरिएको क्रियाकलाप"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ब्याकग्राउन्डमा गरिएको क्रियाकलाप"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ब्याकग्राउन्डमा चलिरहेको हुनाले ब्याट्री खपत भइरहेको छ। तपाईं यसका सम्बन्धमा समीक्षा गर्न चाहनुहुन्छ भने ट्याप गर्नुहोस्।"</string>
-    <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> लामो समयदेखि ब्याकग्राउन्डमा चलिरहेको छ। तपाईं यसका सम्बन्धमा समीक्षा गर्न चाहनुहुन्छ भने ट्याप गर्नुहोस्।"</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ब्याकग्राउन्डमा चलिरहेको हुनाले ब्याट्री खपत भइरहेको छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string>
+    <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> लामो समयदेखि ब्याकग्राउन्डमा चलिरहेको छ। समीक्षा गर्न ट्याप गर्नुहोस्।"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"कुन कुन एप सक्रिय छ भन्ने कुरा जाँच्नुहोस्"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"यो डिभाइसमा भएको क्यामेरा प्रयोग गर्न सकिएन"</string>
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index f85f5f6..508200f 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Driewegs bellen"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Ongewenste, vervelende gesprekken weigeren"</string>
     <string name="CndMmi" msgid="185136449405618437">"Weergave van nummer van beller"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Niet storen"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Beller-ID standaard ingesteld op \'beperkt\'. Volgend gesprek: beperkt."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Beller-ID standaard ingesteld op \'beperkt\'. Volgend gesprek: onbeperkt."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Beller-ID standaard ingesteld op \'onbeperkt\'. Volgend gesprek: beperkt."</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"toegang krijgen tot je agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"sms\'jes verzenden en bekijken"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Bestanden en documenten"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"bestanden en documenten op je apparaat openen"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muziek en andere audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"toegang krijgen tot audiobestanden op je apparaat"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foto\'s en video\'s"</string>
@@ -543,12 +542,12 @@
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Hiermee kan de app bluetooth-apparaten in de buurt vinden en koppelen"</string>
     <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"verbinding maken met gekoppelde bluetooth-apparaten"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Hiermee kan de app verbinding maken met gekoppelde bluetooth-apparaten"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"adverteren op bluetooth-apparaten in de buurt"</string>
-    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Hiermee kan de app adverteren op bluetooth-apparaten in de buurt"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"uitzenden naar bluetooth-apparaten in de buurt"</string>
+    <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Hiermee kan de app uitzenden naar bluetooth-apparaten in de buurt"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"relatieve positie tussen ultrabreedbandapparaten in de buurt bepalen"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"De app toestaan om de relatieve positie tussen ultrabreedbandapparaten in de buurt te bepalen"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interactie met wifi-apparaten in de buurt"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Hiermee kan de app adverteren op, verbinding maken met en de relatieve positie bepalen van wifi-apparaten in de buurt"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Hiermee kan de app uitzenden, verbindingen maken en de relatieve positie bepalen van wifi-apparaten in de buurt"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informatie over voorkeursservice voor NFC-betaling"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Hiermee kun je zorgen dat de app informatie krijgt over de voorkeursservice voor NFC-betaling, zoals geregistreerde hulpmiddelen en routebestemmingen."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"Near Field Communication regelen"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Voer je schermvergrendeling in om door te gaan"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Gedeeltelijke vingerafdruk gedetecteerd"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Kan vingerafdruk niet verwerken. Probeer het opnieuw."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Reinig de vingerafdruksensor en probeer het opnieuw"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Reinig de sensor en probeer het opnieuw"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Druk stevig op de sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Vinger te langzaam bewogen. Probeer het opnieuw."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Probeer een andere vingerafdruk"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Te veel licht"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Verander de positie van je vinger steeds een beetje"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Vingerafdruk niet herkend"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Druk stevig op de sensor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Vingerafdruk geverifieerd"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Gezicht geverifieerd"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Gezicht geverifieerd. Druk op Bevestigen."</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Hiermee wordt de houder toegestaan te binden aan de berichteninterface van een provider. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"binden aan providerservices"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Hiermee kan de houder binden aan providerservices. Nooit gebruikt voor normale apps."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"toegang tot Niet storen"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Hiermee kan de app configuratie voor Niet storen lezen en schrijven."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"rechtengebruik starten"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Hiermee kan de houder het rechtengebruik voor een app starten. Nooit vereist voor normale apps."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"bekijken van rechtenbeslissingen starten"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Overslaan"</string>
     <string name="no_matches" msgid="6472699895759164599">"Geen overeenkomsten"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Zoeken op pagina"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# overeenkomst}other{# van {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Klaar"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Gedeelde opslag wissen…"</string>
     <string name="share" msgid="4157615043345227321">"Delen"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (volgende wekker)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Totdat je uitzet"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Totdat je Niet storen uitzet"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Samenvouwen"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Niet storen"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Downtime"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Doordeweekse avond"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Trillen bij gesprekken en meldingen"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Telefoon- en meldingsgeluid wordt uitgezet"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Systeemwijzigingen"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Niet storen"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nieuw: \'Niet storen\' verbergt meldingen"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tik voor meer informatie en om te wijzigen."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'Niet storen\' is gewijzigd"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tik om te controleren wat er is geblokkeerd."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Systeem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Instellingen"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Uitzetten"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Meer informatie"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"In Android 12 hebben verbeterde meldingen aanpasbare Android-meldingen vervangen. Deze functie laat voorgestelde acties en antwoorden zien en ordent je meldingen.\n\nVerbeterde meldingen hebben toegang tot meldingscontent, waaronder persoonlijke informatie zoals contactnamen en berichten. Deze functie kan ook meldingen sluiten of erop reageren, zoals telefoongesprekken aannemen, en Niet storen beheren."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Informatiemelding voor routinemodus"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"De batterij raakt mogelijk leeg voordat deze normaal gesproken wordt opgeladen"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterijbesparing is geactiveerd om de batterijduur te verlengen"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> wordt uitgevoerd op de achtergrond en verbruikt veel batterijlading. Tik om te bekijken."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> wordt al lange tijd uitgevoerd op de achtergrond. Tik om te bekijken."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Actieve apps checken"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kan geen toegang krijgen tot de camera vanaf dit apparaat"</string>
 </resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 0a945e0..5a684a85 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"ତିନି ପ୍ରକାରରେ କଲିଙ୍ଗ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"ଅବାଞ୍ଛିତ ଅଜଣା କଲ୍‌ଗୁଡ଼ିକର ପ୍ରତ୍ୟାଖ୍ୟାନ"</string>
     <string name="CndMmi" msgid="185136449405618437">"କଲିଙ୍ଗ ନମ୍ବର୍ ଡେଲିଭରୀ"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"କଲର୍ ଆଇଡି ଡିଫଲ୍ଟ ଭାବରେ ପ୍ରତିବନ୍ଧିତ। ପରବର୍ତ୍ତୀ କଲ୍: ପ୍ରତିବନ୍ଧିତ"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"କଲର୍ ଆଇଡି ଡିଫଲ୍ଟ ଭାବରେ ପ୍ରତିବନ୍ଧିତ। ପରବର୍ତ୍ତୀ କଲ୍: ପ୍ରତିବନ୍ଧିତ ନୁହେଁ"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"କଲର୍ ଆଇଡି ଡିଫଲ୍ଟ ଭାବରେ ପ୍ରତିବନ୍ଧିତ ନୁହେଁ। ପରବର୍ତ୍ତୀ କଲ୍: ପ୍ରତିବନ୍ଧିତ"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ଏକ କେରିଅର୍‍ ମେସେଜିଙ୍ଗ ସେବାର ଶୀର୍ଷ-ସ୍ତରୀୟ ଇଣ୍ଟରଫେସ୍‍ ବାନ୍ଧିରଖିବାକୁ ହୋଲ୍ଡରଙ୍କୁ ଅନୁମତି ଦିଏ। ସାମାନ୍ୟ ଆପ୍‍ ପାଇଁ ଆବଶ୍ୟକ କରାଯିବା ଉଚିତ ନୁହେଁ।"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"କେରିଅର୍‍ ସେବାଗୁଡ଼ିକ ସହ ଯୋଡ଼ି ହୁଅନ୍ତୁ"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"କେରିଅର୍‌ ସେବାଗୁଡ଼ିକ ସହିତ ଧାରକଙ୍କୁ ଯୋଡ଼ିଥାଏ। ସାମାନ୍ୟ ଆପ୍‍ ପାଇଁ କଦାପି ଆବଶ୍ୟକ ହୁଏନାହିଁ।"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଆକ୍ସେସ୍‍ କରନ୍ତୁ"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" କନଫିଗରେଶନ୍‍ ପଢ଼ିବା ତଥା ଲେଖିବା ପାଇଁ ଆପକୁ ଅନୁମତି ଦେଇଥାଏ।"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ଅନୁମତି ବ୍ୟବହାର ଦେଖିବା ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ଏକ ଆପ୍ ପାଇଁ ଅନୁମତିର ବ୍ୟବହାର ଆରମ୍ଭ କରିବାକୁ ଧାରକକୁ ଅନୁମତି ଦେଇଥାଏ। ସାଧାରଣ ଆପ୍‌ଗୁଡ଼ିକ ପାଇଁ ଏହା ଆବଶ୍ୟକ ନୁହେଁ।"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ଅନୁମତି ନିଷ୍ପତ୍ତିଗୁଡ଼ିକ ଦେଖିବା ଆରମ୍ଭ କରନ୍ତୁ"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ଛାଡ଼ିଦିଅନ୍ତୁ"</string>
     <string name="no_matches" msgid="6472699895759164599">"କୌଣସି ମେଳକ ନାହିଁ"</string>
     <string name="find_on_page" msgid="5400537367077438198">"ପୃଷ୍ଠାରେ ଖୋଜନ୍ତୁ"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{#ଟି ମେଳ}other{{total}ଟିରୁ #ଟି ମେଳ}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"ହୋଇଗଲା"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"ସେୟାର୍‍ ହୋଇଥିବା ଷ୍ଟୋରେଜ୍‍ ଲିଭାଉଛି…"</string>
     <string name="share" msgid="4157615043345227321">"ସେୟାର୍‍"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ପର୍ଯ୍ୟନ୍ତ"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ପରବର୍ତ୍ତୀ ଆଲାର୍ମ) ପର୍ଯ୍ୟନ୍ତ"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"ବନ୍ଦ ନକରିବା ପର୍ଯ୍ୟନ୍ତ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"ଆପଣ \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍‍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ଛୋଟ କରନ୍ତୁ"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ବନ୍ଦ ରହିବାର ସମୟ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ସପ୍ତାହରାତି"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ସପ୍ତାହାନ୍ତ"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଭାଇବ୍ରେଟ୍ ହେବ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"କଲ୍ ଓ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ନିଃଶବ୍ଦ କରିଦିଆଯିବ"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"ସିଷ୍ଟମ୍‌ରେ ପରିବର୍ତ୍ତନ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"ନୂଆ: \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ମୋଡ୍‌ ଅନ୍‌ ଥିବା ଯୋଗୁଁ ବିଜ୍ଞପ୍ତି ଲୁଚାଇ ଦିଆଯାଉଛି"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ଅଧିକ ଜାଣିବାକୁ ଟ୍ୟାପ୍‌ କରନ୍ତୁ ଏବଂ ବଦଳାନ୍ତୁ।"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"’ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ’ ବଦଳିଯାଇଛି"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"କ’ଣ ଅବରୋଧ ହୋଇଛି ଯାଞ୍ଚ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ସିଷ୍ଟମ୍‌"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ସେଟିଂସ୍"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ଠିକ୍ ଅଛି"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ଅଧିକ ଜାଣନ୍ତୁ"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12ରେ Android ଆଡେପ୍ଟିଭ୍ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଉନ୍ନତ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକରେ ପରିବର୍ତ୍ତନ କରାଯାଇଛି। ଏହି ଫିଚର୍ ପ୍ରସ୍ତାବିତ କାର୍ଯ୍ୟ ଏବଂ ପ୍ରତ୍ୟୁତ୍ତରଗୁଡ଼ିକୁ ଦେଖାଏ ଏବଂ ଆପଣଙ୍କ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ବ୍ୟବସ୍ଥିତ କରେ।\n\nଉନ୍ନତ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଯୋଗାଯୋଗ ନାମ ଏବଂ ମେସେଜଗୁଡ଼ିକ ପରି ବ୍ୟକ୍ତିଗତ ସୂଚନା ସମେତ ବିଜ୍ଞପ୍ତିର ବିଷୟବସ୍ତୁକୁ ଆକ୍ସେସ୍ କରିପାରିବ। ଏହି ଫିଚର୍ ଫୋନ୍ କଲଗୁଡ଼ିକର ଉତ୍ତର ଦେବା ଏବଂ \'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\'କୁ ନିୟନ୍ତ୍ରଣ କରିବା ପରି, ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ମଧ୍ୟ ଖାରଜ କରିପାରିବ କିମ୍ବା ସେଗୁଡ଼ିକର ଉତ୍ତର ଦେଇପାରିବ।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ନିୟମିତ ମୋଡ୍‍ ସୂଚନା ବିଜ୍ଞପ୍ତି"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ସାଧାରଣ ଭାବରେ ଚାର୍ଜ୍ କରିବା ପୂର୍ବରୁ ବ୍ୟାଟେରୀ ସରିଯାଇପାରେ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ବ୍ୟାଟେରୀର ସମୟକୁ ବଢ଼ାଇବା ପାଇଁ ବ୍ୟଟେରୀ ସେଭର୍‍କୁ କାର୍ଯ୍ୟକାରୀ କରାଯାଇଛି"</string>
@@ -2253,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ମେସେଜ୍, <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ରୁ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>କୁ ଅନୁବାଦ କରାଯାଇଛି।"</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ପୃଷ୍ଠପଟରେ ଚାଲୁଛି ଏବଂ ବ୍ୟାଟେରୀର ଚାର୍ଜ ସମାପ୍ତ ହେଉଛି। ସମୀକ୍ଷା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g>ଟି ପୃଷ୍ଠପଟରେ ଚାଲୁଥିବା ଯୋଗୁଁ ବ୍ୟାଟେରୀର ଚାର୍ଜ ସରିଯାଉଛି। ସମୀକ୍ଷା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ଦୀର୍ଘ ସମୟ ଧରି ପୃଷ୍ଠପଟରେ ଚାଲୁଛି। ସମୀକ୍ଷା କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ସକ୍ରିୟ ଆପଗୁଡ଼ିକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ଏହି ଡିଭାଇସରୁ କ୍ୟାମେରାକୁ ଆକ୍ସେସ କରାଯାଇପାରିବ ନାହିଁ"</string>
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 294dd3c..5ee2088 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"ਥ੍ਰੀ ਵੇ ਕਾਲਿੰਗ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"ਅਣਇੱਛਿਤ ਪਰੇਸ਼ਾਨ ਕਰਨ ਵਾਲੀਆਂ ਕਾਲਾਂ ਦੀ ਅਸਵੀਕ੍ਰਿਤੀ"</string>
     <string name="CndMmi" msgid="185136449405618437">"ਕਾਲਿੰਗ ਨੰਬਰ ਡਿਲੀਵਰੀ"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ਪ੍ਰਤਿਬੰਧਿਤ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ਪ੍ਰਤਿਬੰਧਿਤ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ ਨਹੀਂ"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ਪ੍ਰਤਿਬੰਧਿਤ ਨਾ ਕਰਨ ਲਈ ਕਾਲਰ ਆਈ.ਡੀ. ਪੂਰਵ-ਨਿਰਧਾਰਤ। ਅਗਲੀ ਕਾਲ: ਪ੍ਰਤਿਬੰਧਿਤ"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ਤੁਹਾਡੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS ਸੁਨੇਹੇ ਭੇਜੋ ਅਤੇ ਦੇਖੋ"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"ਫ਼ਾਈਲਾਂ ਅਤੇ ਦਸਤਾਵੇਜ਼"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਫ਼ਾਈਲਾਂ ਅਤੇ ਦਸਤਾਵੇਜ਼ਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"ਸੰਗੀਤ ਅਤੇ ਹੋਰ ਆਡੀਓ"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਆਡੀਓ ਫ਼ਾਈਲਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ਜਾਰੀ ਰੱਖਣ ਲਈ ਆਪਣਾ ਸਕ੍ਰੀਨ ਲਾਕ ਦਾਖਲ ਕਰੋ"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ਅੰਸ਼ਕ ਫਿੰਗਰਪ੍ਰਿੰਟ ਦਾ ਪਤਾ ਲੱਗਿਆ"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ਫਿੰਗਰਪ੍ਰਿੰਟ \'ਤੇ ਪ੍ਰਕਿਰਿਆ ਨਹੀਂ ਹੋ ਸਕੀ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ਸੈਂਸਰ ਨੂੰ ਸਾਫ਼ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"ਸੈਂਸਰ ਨੂੰ ਜ਼ੋਰ ਨਾਲ ਦਬਾਓ"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ਉਂਗਲ ਕਾਫ਼ੀ ਹੌਲੀ ਮੂਵ ਹੋਈ। ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ਕੋਈ ਹੋਰ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤ ਕੇ ਦੇਖੋ"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਚਮਕ"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"ਹਰ ਵਾਰ ਆਪਣੀ ਉਂਗਲ ਨੂੰ ਥੋੜ੍ਹਾ ਹਿਲਾਓ"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਦੀ ਪਛਾਣ ਨਹੀਂ ਹੋਈ"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"ਸੈਂਸਰ ਨੂੰ ਜ਼ੋਰ ਨਾਲ ਦਬਾਓ"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ਚਿਹਰਾ ਪੁਸ਼ਟੀਕਰਨ, ਕਿਰਪਾ ਕਰਕੇ \'ਪੁਸ਼ਟੀ ਕਰੋ\' ਦਬਾਓ"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"ਹੋਲਡਰ ਨੂੰ ਇੱਕ ਕੈਰੀਅਰ ਮੈਸੇਜਿੰਗ ਸੇਵਾ ਦੇ ਉੱਚ-ਪੱਧਰ ਦੇ ਇੰਟਰਫੇਸ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"ਕੈਰੀਅਰ ਸੇਵਾਵਾਂ ਨਾਲ ਜੋੜੋ"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"ਹੋਲਡਰ ਨੂੰ ਕੈਰੀਅਰ ਸੇਵਾਵਾਂ ਨਾਲ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਸ ਲਈ ਕਦੇ ਵੀ ਲੁੜੀਂਦਾ ਨਹੀਂ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ।"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ਐਪ ਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਕੌਂਫਿਗਰੇਸ਼ਨ ਨੂੰ ਪੜ੍ਹਨ ਅਤੇ ਲਿਖਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਦੇਖਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ਧਾਰਕ ਨੂੰ ਕਿਸੇ ਹੋਰ ਐਪ ਲਈ ਇਜਾਜ਼ਤ ਵਰਤੋਂ ਨੂੰ ਸ਼ੁਰੂ ਕਰਨ ਦਿੰਦਾ ਹੈ। ਸਧਾਰਨ ਐਪਾਂ ਲਈ ਕਦੇ ਵੀ ਲੋੜੀਂਦਾ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ਇਜਾਜ਼ਤ ਸੰਬੰਧੀ ਫ਼ੈਸਲਿਆਂ ਨੂੰ ਦੇਖਣਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ਛੱਡੋ"</string>
     <string name="no_matches" msgid="6472699895759164599">"ਕੋਈ ਮੇਲ ਨਹੀਂ"</string>
     <string name="find_on_page" msgid="5400537367077438198">"ਸਫ਼ੇ ਤੇ ਲੱਭੋ"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# ਮਿਲਾਨ}one{{total} ਵਿੱਚੋਂ #}other{{total} ਵਿੱਚੋਂ #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"ਹੋ ਗਿਆ"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"ਸਾਂਝੀ ਕੀਤੀ ਸਟੋਰੇਜ ਮਿਟਾਈ ਜਾ ਰਹੀ ਹੈ…"</string>
     <string name="share" msgid="4157615043345227321">"ਸਾਂਝਾ ਕਰੋ"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ (ਅਗਲਾ ਅਲਾਰਮ)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ਸਮੇਟੋ"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ਡਾਊਨਟਾਈਮ"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ਵੀਕਨਾਈਟ"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ਹਫ਼ਤੇ ਦਾ ਅੰਤਲਾ ਦਿਨ"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ਕਾਲਾਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਦੀ ਥਰਥਰਾਹਟ ਹੋਵੇਗੀ"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ਕਾਲਾਂ ਅਤੇ ਸੂਚਨਾਵਾਂ ਨੂੰ ਮਿਊਟ ਕੀਤਾ ਜਾਵੇਗਾ"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"ਸਿਸਟਮ ਬਦਲਾਅ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"ਨਵਾਂ: \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਮੋਡ ਸੂਚਨਾਵਾਂ ਨੂੰ ਲੁਕਾ ਰਿਹਾ ਹੈ"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"ਹੋਰ ਜਾਣਨ ਲਈ ਅਤੇ ਬਦਲਾਅ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵਿਕਲਪ ਬਦਲ ਗਿਆ ਹੈ"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"ਟੈਪ ਕਰਕੇ ਦੋਖੋ ਕਿ ਕਿਹੜੀਆਂ ਚੀਜ਼ਾਂ ਬਲਾਕ ਕੀਤੀਆਂ ਗਈਆਂ ਹਨ।"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ਸਿਸਟਮ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ਸੈਟਿੰਗਾਂ"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ਠੀਕ ਹੈ"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ਬੰਦ ਕਰੋ"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ਹੋਰ ਜਾਣੋ"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 ਵਿੱਚ ਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਨੂੰ Android ਅਡੈਪਟਿਵ ਸੂਚਨਾਵਾਂ ਨਾਲ ਬਦਲ ਦਿੱਤਾ ਗਿਆ ਹੈ। ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਕਾਰਵਾਈਆਂ ਅਤੇ ਜਵਾਬਾਂ ਵਾਲੇ ਸੁਝਾਅ ਦਿਖਾਉਂਦੀ ਹੈ ਅਤੇ ਤੁਹਾਡੀਆਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰਦੀ ਹੈ।\n\nਵਿਸਤ੍ਰਿਤ ਸੂਚਨਾਵਾਂ ਸੂਚਨਾ ਸਮੱਗਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀਆਂ ਹਨ, ਜਿਸ ਵਿੱਚ ਸੰਪਰਕ ਦੇ ਨਾਮ ਅਤੇ ਸੁਨੇਹੇ ਵਰਗੀ ਨਿੱਜੀ ਜਾਣਕਾਰੀ ਵੀ ਸ਼ਾਮਲ ਹੈ। ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਸੂਚਨਾਵਾਂ ਨੂੰ ਖਾਰਜ ਵੀ ਕਰ ਸਕਦੀ ਹੈ ਜਾਂ ਸੂਚਨਾਵਾਂ ਦਾ ਜਵਾਬ ਵੀ ਦੇ ਸਕਦੀ ਹੈ, ਜਿਵੇਂ ਕਿ ਫ਼ੋਨ ਕਾਲਾਂ ਦਾ ਜਵਾਬ ਦੇਣਾ ਅਤੇ \'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਕੰਟਰੋਲ ਕਰਨਾ।"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"ਨਿਯਮਬੱਧ ਮੋਡ ਦੀ ਜਾਣਕਾਰੀ ਵਾਲੀ ਸੂਚਨਾ"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"ਬੈਟਰੀ ਚਾਰਜ ਕਰਨ ਦੇ ਮਿੱਥੇ ਸਮੇਂ ਤੋਂ ਪਹਿਲਾਂ ਸ਼ਾਇਦ ਬੈਟਰੀ ਖਤਮ ਹੋ ਜਾਵੇ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ਬੈਟਰੀ ਲਾਈਫ਼ ਵਧਾਉਣ ਲਈ ਬੈਟਰੀ ਸੇਵਰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ ਅਤੇ ਬੈਟਰੀ ਦੀ ਖਪਤ ਕਰ ਰਹੀ ਹੈ। ਸਮੀਖਿਆ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ਲੰਮੇ ਸਮੇਂ ਤੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ। ਸਮੀਖਿਆ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ਕਿਰਿਆਸ਼ੀਲ ਐਪਾਂ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ਇਸ ਡੀਵਾਈਸ ਤੋਂ ਕੈਮਰੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index a316127..0244fe0 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Połączenie dla trzech abonentów"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Odrzucanie niepożądanych, irytujących połączeń"</string>
     <string name="CndMmi" msgid="185136449405618437">"Dostarczanie numeru telefonującego"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Nie przeszkadzać"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: zastrzeżony"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID rozmówcy ustawiony jest domyślnie na „zastrzeżony”. Następne połączenie: nie zastrzeżony"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID rozmówcy ustawiony jest domyślnie na „nie zastrzeżony”. Następne połączenie: zastrzeżony"</string>
@@ -306,10 +307,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"dostęp do kalendarza"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"wysyłanie i wyświetlanie SMS‑ów"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Pliki i dokumenty"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"dostęp do plików i dokumentów na urządzeniu"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzyka i inne dźwięki"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"dostęp do plików audio na urządzeniu"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Zdjęcia i filmy"</string>
@@ -590,12 +589,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Użyj blokady ekranu, aby kontynuować"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Wykryto częściowy odcisk palca"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Nie udało się przetworzyć odcisku palca. Spróbuj ponownie."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Wyczyść czytnik linii papilarnych i spróbuj ponownie"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Wyczyść czujnik i spróbuj ponownie"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Mocno naciśnij czujnik"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Palec został obrócony zbyt wolno. Spróbuj ponownie."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Użyj odcisku innego palca"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Zbyt jasno"</string>
@@ -603,10 +599,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Za każdym razem lekko zmieniaj ułożenie palca"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Nie rozpoznano odcisku palca"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Mocno naciśnij czujnik"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Uwierzytelniono odciskiem palca"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Twarz rozpoznana"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Twarz rozpoznana, kliknij Potwierdź"</string>
@@ -745,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Zezwala posiadaczowi na tworzenie powiązania z interfejsem najwyższego poziomu w usłudze przesyłania wiadomości przez operatora. Nie powinno być nigdy potrzebne dla zwykłych aplikacji."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"powiązanie z usługami operatora"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Umożliwia właścicielowi powiązanie z usługami operatora. Nie powinno być nigdy potrzebne w normalnych aplikacjach."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"dostęp do trybu Nie przeszkadzać"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Pozwala aplikacji na odczyt i zmianę konfiguracji trybu Nie przeszkadzać."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"rozpocząć wyświetlanie użycia uprawnień"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Umożliwia rozpoczęcie korzystania z uprawnienia dotyczącego danej aplikacji jego posiadaczowi. Zwykłe aplikacje nie powinny potrzebować tego uprawnienia."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"rozpoczęcie wyświetlania decyzji dotyczących uprawnień"</string>
@@ -1510,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Pomiń"</string>
     <string name="no_matches" msgid="6472699895759164599">"Brak wyników"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Znajdź na stronie"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# dopasowanie}few{# z {total}}many{# z {total}}other{# z {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Gotowe"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Kasuję dane z pamięci współdzielonej…"</string>
     <string name="share" msgid="4157615043345227321">"Udostępnij"</string>
@@ -1876,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (następny alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Dopóki nie wyłączysz"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Do wyłączenia Nie przeszkadzać"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Zwiń"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Nie przeszkadzać"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Powiadomienia wyłączone"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noc poza weekendem"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2042,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Wibracje przy połączeniach i powiadomieniach"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Wyciszenie połączeń i powiadomień"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Zmiany w systemie"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Nie przeszkadzać"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nowość: w trybie Nie przeszkadzać powiadomienia są ukrywane"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Kliknij, by dowiedzieć się więcej i zmienić ustawienia."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Zmiany w trybie Nie przeszkadzać"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Kliknij, by sprawdzić, co jest zablokowane."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Ustawienia"</string>
@@ -2059,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Wyłącz"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Więcej informacji"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"W Androidzie 12 ulepszone powiadomienia zastąpiły dotychczasowe powiadomienia adaptacyjne. Ta funkcja pokazuje sugerowane działania i odpowiedzi oraz porządkuje powiadomienia.\n\nUlepszone powiadomienia mogą czytać całą zawartość powiadomień, w tym informacje osobiste takie jak nazwy kontaktów i treść wiadomości. Funkcja może też zamykać powiadomienia oraz reagować na nie, np. odbierać połączenia telefoniczne i sterować trybem Nie przeszkadzać."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Powiadomienie z informacją o trybie rutynowym"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria może się wyczerpać przed zwykłą porą ładowania"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Włączono Oszczędzanie baterii, by wydłużyć czas pracy na baterii"</string>
@@ -2265,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> działa w tle i zużywa baterię. Kliknij, aby sprawdzić."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> długo działa w tle. Kliknij, aby sprawdzić."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Sprawdź aktywne aplikacje"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nie można uzyskać dostępu do aparatu z tego urządzenia"</string>
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index fd01b22..3bd78d0 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Chamada com três participantes"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejeição das chamadas indesejadas"</string>
     <string name="CndMmi" msgid="185136449405618437">"Chamando número de entrega"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Não perturbe"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"O identificador de chamadas assume o padrão de restrito. Próxima chamada: Restrita"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"O identificador de chamadas assume o padrão de restrito. Próxima chamada: Não restrita"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"O identificador de chamadas assume o padrão de não restrito. Próxima chamada: Restrita"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Arquivos e documentos"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"acessar arquivos e documentos no seu dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outros áudios"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acessar arquivos de áudio no seu dispositivo"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
@@ -539,16 +538,16 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que o app acesse a configuração do Bluetooth no tablet, além de fazer e aceitar conexões com dispositivos pareados."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que o app acesse a configuração do Bluetooth no dispositivo Android TV, além de fazer e aceitar conexões com dispositivos pareados."</string>
     <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que o app acesse a configuração do Bluetooth no telefone, além de fazer e aceitar conexões com dispositivos pareados."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"descobrir e se parear a disp. Bluetooth por perto"</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"descobrir e parear com disp. Bluetooth por perto"</string>
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que o app descubra e se pareie a dispositivos Bluetooth por perto"</string>
-    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conecte-se a dispositivos Bluetooth pareados"</string>
+    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectar a dispositivos Bluetooth pareados"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que o app se conecte a dispositivos Bluetooth pareados"</string>
     <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"anunciar em dispositivos Bluetooth por perto"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que o app seja anunciado em dispositivos Bluetooth por perto"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app veicule anúncios, conecte-se à rede e determine a posição relativa de dispositivos Wi-Fi por perto"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app divulgue, faça conexão e determine a posição relativa de dispositivos Wi-Fi por perto."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Insira seu bloqueio de tela para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detectada"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressão digital e tente novamente"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pressione o sensor com firmeza"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O movimento do dedo está muito lento. Tente novamente."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Impressão digital não reconhecida"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pressione o sensor com firmeza"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite que o proprietário use a interface de nível superior de um serviço de mensagens de operadora. Não deve ser necessária para apps comuns."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular a serviços de operadora"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permite que o proprietário use serviços de operadora. Não deve ser necessário para apps comuns."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"acessar \"Não perturbe\""</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso da permissão para visualização"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"decisões de permissão da visualização inicial"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Pular"</string>
     <string name="no_matches" msgid="6472699895759164599">"Não encontrado"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Localizar na página"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# correspondência}one{# de {total}}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Concluído"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Limpando armazenamento compartilhado…"</string>
     <string name="share" msgid="4157615043345227321">"Compartilhar"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Até <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próximo alarme)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Até você desativar"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Até que você desative \"Não perturbe\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Recolher"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Não perturbe"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Tempo de inatividade"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Durante a semana à noite"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Chamadas e notificações farão o dispositivo vibrar"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Chamadas e notificações ficarão silenciadas"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Alterações do sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Não perturbe"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: o modo Não perturbe está ocultando as notificações"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Toque para saber mais e fazer alterações."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo \"Não perturbe\" foi alterado"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toque para verificar o que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Configurações"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desativar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saiba mais"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"No Android 12, as notificações avançadas substituíram as notificações adaptáveis. Esse recurso exibe ações e respostas sugeridas, além de organizar suas notificações.\n\nAs notificações avançadas podem acessar o conteúdo das notificações, incluindo informações pessoais como nomes de contatos e mensagens. Elas também podem dispensar ou responder às notificações, como atender chamadas telefônicas e controlar o Não perturbe."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificação de informação do modo rotina"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A bateria pode acabar antes da recarga normal"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"A Economia de bateria foi ativada para aumentar a duração da carga"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano e drenando a energia da bateria. Toque para revisar."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Não é possível acessar a câmera neste dispositivo"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index aa8571b..27bdde7 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Chamada de conferência entre três interlocutores"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejeição de chamadas inoportunas indesejadas"</string>
     <string name="CndMmi" msgid="185136449405618437">"Entrega do número chamador"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Não incomodar"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID do autor da chamada é predefinido como restrito. Chamada seguinte: Restrita"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID do autor da chamada é predefinido como restrito. Chamada seguinte: Não restrita"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID do autor da chamada é predefinido como não restrito. Chamada seguinte: Restrita"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"aceder ao calendário"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"enviar e ver mensagens SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Ficheiros e documentos"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"aceder a ficheiros e documentos no seu dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outro áudio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"aceder a ficheiros de áudio no dispositivo"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Introduza o bloqueio de ecrã para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detetada"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressões digitais e tente novamente"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Prima firmemente o sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Moveu o dedo demasiado lentamente. Tente novamente."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Experimente outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Está demasiado claro"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Altere a posição do seu dedo ligeiramente de cada vez"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Impressão digital não reconhecida"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Prima firmemente o sensor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"A impressão digital foi autenticada."</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado."</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado. Prima Confirmar."</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite ao titular ligar à interface de nível superior do serviço de mensagens de um operador. Nunca deve ser necessário para aplicações normais."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular a serviços do operador"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permite ao titular vincular-se a serviços do operador. Nunca deverá ser necessário nas aplicações normais."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"aceder a Não incomodar"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite à app ler e alterar a configuração de Não incomodar"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar utilização da autorização de visualização"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que o titular inicie a utilização de autorizações para uma app. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"começar a ver as decisões de autorização"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Ignorar"</string>
     <string name="no_matches" msgid="6472699895759164599">"Sem correspondências"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Localizar na página"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# correspondência}one{# de {total}}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Concluído"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"A apagar o armazenamento partilhado…"</string>
     <string name="share" msgid="4157615043345227321">"Partilhar"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Até <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próximo alarme)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Até desativar"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Até desativar Não incomodar"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Reduzir"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Não incomodar"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Período de inatividade"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Dias da semana à noite"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"As chamadas e as notificações vibram."</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"É desativado o som das chamadas e das notificações."</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Alterações ao sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Não incomodar"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: o modo Não incomodar está a ocultar as notificações"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Toque para saber mais e alterar."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo Não incomodar foi alterado"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toque para verificar o que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Definições"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desativar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saber mais"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"As notificações melhoradas substituíram as notificações adaptáveis do Android no Android 12. Esta funcionalidade mostra ações e respostas sugeridas e organiza as suas notificações.\n\nAs notificações melhoradas podem aceder a todo o conteúdo das notificações, incluindo informações pessoais como nomes de contactos e mensagens. Esta funcionalidade também pode ignorar ou responder a notificações, como atender chamadas telefónicas, e controlar o modo Não incomodar."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificação de informações do Modo rotina"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pode ficar sem bateria antes do carregamento habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Poupança de bateria ativada para prolongar a duração da bateria"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Mensagem traduzida de <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> para <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Atividade em segundo plano"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Atividade em segundo plano"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"A app <xliff:g id="APP">%1$s</xliff:g> está a ser executada em segundo plano e a consumir rapidamente a bateria Toque para analisar."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está a ser executada em 2.º plano e a consumir muita bateria. Toque para analisar."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"A app <xliff:g id="APP">%1$s</xliff:g> está a ser executada em segundo plano há muito tempo. Toque para analisar."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativas"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Não é possível aceder à câmara a partir deste dispositivo"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index fd01b22..3bd78d0 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Chamada com três participantes"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Rejeição das chamadas indesejadas"</string>
     <string name="CndMmi" msgid="185136449405618437">"Chamando número de entrega"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Não perturbe"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"O identificador de chamadas assume o padrão de restrito. Próxima chamada: Restrita"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"O identificador de chamadas assume o padrão de restrito. Próxima chamada: Não restrita"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"O identificador de chamadas assume o padrão de não restrito. Próxima chamada: Restrita"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"acesse sua agenda"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"envie e veja mensagens SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Arquivos e documentos"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"acessar arquivos e documentos no seu dispositivo"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Música e outros áudios"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"acessar arquivos de áudio no seu dispositivo"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotos e vídeos"</string>
@@ -539,16 +538,16 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Permite que o app acesse a configuração do Bluetooth no tablet, além de fazer e aceitar conexões com dispositivos pareados."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Permite que o app acesse a configuração do Bluetooth no dispositivo Android TV, além de fazer e aceitar conexões com dispositivos pareados."</string>
     <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Permite que o app acesse a configuração do Bluetooth no telefone, além de fazer e aceitar conexões com dispositivos pareados."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"descobrir e se parear a disp. Bluetooth por perto"</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"descobrir e parear com disp. Bluetooth por perto"</string>
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite que o app descubra e se pareie a dispositivos Bluetooth por perto"</string>
-    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conecte-se a dispositivos Bluetooth pareados"</string>
+    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"conectar a dispositivos Bluetooth pareados"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite que o app se conecte a dispositivos Bluetooth pareados"</string>
     <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"anunciar em dispositivos Bluetooth por perto"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite que o app seja anunciado em dispositivos Bluetooth por perto"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"determinar o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permitir que o app determine o posicionamento relativo entre dispositivos de banda ultralarga por perto"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"interagir com dispositivos Wi-Fi por perto"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app veicule anúncios, conecte-se à rede e determine a posição relativa de dispositivos Wi-Fi por perto"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite que o app divulgue, faça conexão e determine a posição relativa de dispositivos Wi-Fi por perto."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informações preferidas de serviço de pagamento por NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite que o app acesse as informações preferidas de serviço de pagamento por NFC, como auxílios registrados ou destinos de trajetos."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlar a comunicação a curta distância"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Insira seu bloqueio de tela para continuar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Impressão digital parcial detectada"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Não foi possível processar a impressão digital. Tente novamente."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Limpe o sensor de impressão digital e tente novamente"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Limpe o sensor e tente novamente"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pressione o sensor com firmeza"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"O movimento do dedo está muito lento. Tente novamente."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Use outra impressão digital"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Claro demais"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mude a posição do dedo ligeiramente a cada momento"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Impressão digital não reconhecida"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pressione o sensor com firmeza"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Impressão digital autenticada"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Rosto autenticado"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Rosto autenticado, pressione \"Confirmar\""</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite que o proprietário use a interface de nível superior de um serviço de mensagens de operadora. Não deve ser necessária para apps comuns."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"vincular a serviços de operadora"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permite que o proprietário use serviços de operadora. Não deve ser necessário para apps comuns."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"acessar \"Não perturbe\""</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permitir que o app leia e grave a configuração \"Não perturbe\"."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"iniciar uso da permissão para visualização"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite que o sistema inicie o uso de permissão para um app. Não deve ser necessário para apps comuns."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"decisões de permissão da visualização inicial"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Pular"</string>
     <string name="no_matches" msgid="6472699895759164599">"Não encontrado"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Localizar na página"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# correspondência}one{# de {total}}other{# de {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Concluído"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Limpando armazenamento compartilhado…"</string>
     <string name="share" msgid="4157615043345227321">"Compartilhar"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Até <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (próximo alarme)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Até você desativar"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Até que você desative \"Não perturbe\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Recolher"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Não perturbe"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Tempo de inatividade"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Durante a semana à noite"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fim de semana"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Chamadas e notificações farão o dispositivo vibrar"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Chamadas e notificações ficarão silenciadas"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Alterações do sistema"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Não perturbe"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novo: o modo Não perturbe está ocultando as notificações"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Toque para saber mais e fazer alterações."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"O modo \"Não perturbe\" foi alterado"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Toque para verificar o que está bloqueado."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistema"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Configurações"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desativar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Saiba mais"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"No Android 12, as notificações avançadas substituíram as notificações adaptáveis. Esse recurso exibe ações e respostas sugeridas, além de organizar suas notificações.\n\nAs notificações avançadas podem acessar o conteúdo das notificações, incluindo informações pessoais como nomes de contatos e mensagens. Elas também podem dispensar ou responder às notificações, como atender chamadas telefônicas e controlar o Não perturbe."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificação de informação do modo rotina"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"A bateria pode acabar antes da recarga normal"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"A Economia de bateria foi ativada para aumentar a duração da carga"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano e drenando a energia da bateria. Toque para revisar."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> está sendo executado em segundo plano faz muito tempo. Toque para revisar."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificar apps ativos"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Não é possível acessar a câmera neste dispositivo"</string>
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index fab2656..15a368b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -71,6 +71,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Apelare de tip conferință"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Respingere apeluri supărătoare nedorite"</string>
     <string name="CndMmi" msgid="185136449405618437">"Se apelează serviciul de furnizare a numerelor"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Nu deranjați"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID-ul apelantului este restricționat în mod prestabilit. Apelul următor: restricționat"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID-ul apelantului este restricționat în mod prestabilit. Apelul următor: nerestricționat"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID-ul apelantului este nerestricționat în mod prestabilit. Apelul următor: Restricționat."</string>
@@ -542,12 +543,12 @@
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Permite aplicației să descopere și să asocieze dispozitive Bluetooth din apropiere"</string>
     <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"să se conecteze la dispozitive Bluetooth asociate"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Permite aplicației să se conecteze la dispozitive Bluetooth asociate"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"să difuzeze anunțuri pe dispozitive Bluetooth din apropiere"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"să transmită anunțuri pe dispozitive Bluetooth din apropiere"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Permite aplicației să difuzeze anunțuri pe dispozitive Bluetooth din apropiere"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Permiteți-i aplicației să stabilească poziția relativă dintre dispozitivele Ultra-Wideband din apropiere"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"să interacționeze cu dispozitive Wi‑Fi din apropiere"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite aplicației să se conecteze la, să afișeze date și să stabilească poziția relativă pentru dispozitive Wi-Fi din apropiere"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Permite aplicației să se conecteze la dispozitive Wi-Fi din apropiere, să transmită anunțuri și să stabilească poziția relativă a acestora"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informații despre serviciul de plăți NFC preferat"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Permite aplicației să obțină informații despre serviciul de plăți NFC preferat, de exemplu, identificatorii de aplicație înregistrați și destinația traseului."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"controlare schimb de date prin Near Field Communication"</string>
@@ -737,6 +738,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Permite aplicației să se conecteze la interfața de nivel superior a unui serviciu de mesagerie oferit de operator. Nu ar trebui să fie niciodată necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"se conectează la serviciile operatorului"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Permite aplicației să se conecteze la serviciile operatorului. Nu ar trebui să fie niciodată necesară pentru aplicațiile obișnuite."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"accesează Nu deranja"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Permite aplicației să citească și să scrie configurația Nu deranja."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"porniți folosirea permisiunii de vizualizare"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Permite proprietarului să pornească folosirea permisiunii pentru o aplicație. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"să înceapă să examineze deciziile privind permisiunile"</string>
@@ -1502,8 +1505,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Omiteți"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nicio potrivire"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Găsiți pe pagină"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# potrivire}few{# din {total}}other{# din {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Terminat"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Se șterge spațiul de stocare distribuit..."</string>
     <string name="share" msgid="4157615043345227321">"Distribuiți"</string>
@@ -1868,8 +1870,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Până la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Până la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (următoarea alarmă)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Până când dezactivați"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Până când dezactivați „Nu deranja”"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Restrângeți"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Nu deranja"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Inactivitate"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Nopțile din zilele lucrătoare"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2034,7 +2038,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Apelurile și notificările vor vibra"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Apelurile și notificările vor avea sunetul dezactivat"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Modificări de sistem"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Nu deranja"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Funcția nouă Nu deranja ascunde notificările"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Atingeți ca să aflați mai multe și să modificați"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Funcția Nu deranja s-a schimbat"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Atingeți pentru a verifica ce este blocat."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Setări"</string>
@@ -2051,6 +2058,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Dezactivați"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Aflați mai multe"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Notificările optimizate au înlocuit Notificările adaptive Android de pe Android 12. Această funcție afișează acțiuni și răspunsuri sugerate și vă organizează notificările.\n\nNotificările optimizate pot accesa conținutul notificărilor, inclusiv informații cu caracter personal, precum mesajele și numele persoanelor de contact. În plus, funcția poate să închidă sau să răspundă la notificări, de exemplu, să răspundă la apeluri telefonice și să gestioneze opțiunea Nu deranja."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificare pentru informații despre modul Rutină"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria se poate descărca înainte de încărcarea obișnuită"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Economisirea bateriei este activată pentru a prelungi durata de funcționare a bateriei"</string>
@@ -2257,6 +2265,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> rulează în fundal și consumă bateria. Atingeți pentru a examina."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> rulează în fundal mult timp. Atingeți pentru a examina."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Verificați aplicațiile active"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nu se poate accesa camera foto de pe acest dispozitiv"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0ba7cb0..bf8e83d 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Вызов с участием трех абонентов"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Отклонение нежелательных звонков"</string>
     <string name="CndMmi" msgid="185136449405618437">"Доставка номера вызывающего абонента"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Не беспокоить"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Идентификация абонента по умолчанию запрещена. След. вызов: запрещена"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Идентификация абонента по умолчанию запрещена. След. вызов: разрешена"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Идентификация абонента по умолчанию не запрещена. След. вызов: запрещена"</string>
@@ -306,10 +307,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"доступ к календарю"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"отправлять и просматривать SMS-сообщения"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файлы и документы"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"Доступ к файлам и документам на вашем устройстве"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музыка и другие аудиозаписи"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"доступ к аудиофайлам на вашем устройстве"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фото и видео"</string>
@@ -343,7 +342,7 @@
     <string name="capability_title_canCaptureFingerprintGestures" msgid="1189053104594608091">"Регистрировать жесты на сканере отпечатков пальцев"</string>
     <string name="capability_desc_canCaptureFingerprintGestures" msgid="6861869337457461274">"Использовать сканер отпечатков пальцев для дополнительных жестов."</string>
     <string name="capability_title_canTakeScreenshot" msgid="3895812893130071930">"Создавать скриншоты"</string>
-    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Создавать скриншоты экрана."</string>
+    <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Создавать снимки экрана."</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"Отключение/изменение строки состояния"</string>
     <string name="permdesc_statusBar" msgid="5809162768651019642">"Приложение сможет отключать строку состояния, а также добавлять и удалять системные значки."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"Замена строки состояния"</string>
@@ -590,12 +589,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Чтобы продолжить, разблокируйте экран."</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Отсканирована только часть отпечатка."</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не удалось распознать отпечаток. Повторите попытку."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Очистите сканер отпечатков пальцев и повторите попытку."</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Очистите сканер и повторите попытку."</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Плотно прижмите палец к сканеру."</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Вы перемещали палец слишком медленно. Повторите попытку."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Попробуйте сохранить отпечаток другого пальца."</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Слишком светло."</string>
@@ -603,10 +599,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Каждый раз немного меняйте положение пальца."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отпечаток не распознан."</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Плотно прижмите палец к сканеру."</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отпечаток пальца проверен"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лицо распознано"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лицо распознано, нажмите кнопку \"Подтвердить\""</string>
@@ -745,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Подключение к базовому интерфейсу службы обмена сообщениями, предоставляемой оператором связи. Это разрешение обычно используется только специальными приложениями."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"Подключение к сервисам оператора связи"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Приложение сможет подключаться к сервисам оператора связи. Это разрешение не используется обычными приложениями."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Доступ к режиму \"Не беспокоить\""</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Открывает приложению доступ к настройкам режима \"Не беспокоить\" и позволяет изменять их."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"Просмотр данных об используемых разрешениях"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Приложение получит доступ к данным об используемых разрешениях. Это разрешение не требуется обычным приложениям."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"Просмотр действий с разрешениями"</string>
@@ -1510,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Пропустить"</string>
     <string name="no_matches" msgid="6472699895759164599">"Нет совпадений"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Найти на странице"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# совпадение}one{# совпадение из {total}}few{# совпадения из {total}}many{# совпадений из {total}}other{# совпадения из {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Готово"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Очистка единого хранилища…"</string>
     <string name="share" msgid="4157615043345227321">"Поделиться"</string>
@@ -1876,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (будильник)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Пока вы не отключите"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Пока вы не отключите режим \"Не беспокоить\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Свернуть"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не беспокоить"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Режим уведомления"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Будний вечер"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Выходные"</string>
@@ -2042,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Для звонков и уведомлений включен вибросигнал."</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Для звонков и уведомлений отключен звук."</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Системные изменения"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не беспокоить"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Теперь в режиме \"Не беспокоить\" уведомления не приходят"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Нажмите, чтобы узнать больше и изменить настройки."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Настройки режима \"Не беспокоить\" изменены"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Нажмите, чтобы проверить настройки."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Настройки"</string>
@@ -2059,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ОК"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Отключить"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Подробнее"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 доступны улучшенные уведомления. Эта функция упорядочивает все ваши уведомления и подсказывает ответы и действия.\n\nЕй доступно содержимое всех уведомлений, в том числе имена контактов, сообщения и другие личные данные. Также эта функция может закрывать уведомления и нажимать кнопки в них, например отвечать на звонки и управлять режимом \"Не беспокоить\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Уведомление о батарее"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батарея может разрядиться"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Чтобы увеличить время работы от батареи, был включен режим энергосбережения."</string>
@@ -2265,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Приложение \"<xliff:g id="APP">%1$s</xliff:g>\" работает в фоновом режиме и расходует заряд батареи. Нажмите, чтобы узнать подробности."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Приложение \"<xliff:g id="APP">%1$s</xliff:g>\" работает в фоновом режиме уже длительное время. Нажмите, чтобы узнать подробности."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверить активные приложения"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Камера на этом устройстве недоступна."</string>
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 2c9950c..63976d6 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"තුන් මාර්ග ඇමතීම"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"අනවශ්‍ය හිරිහැරදායක ඇමතුම් ප්‍රතික්ෂේප කිරීම"</string>
     <string name="CndMmi" msgid="185136449405618437">"ඇමතීමේ අංකය භාරදීම"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"බාධා නොකරන්න"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"අමතන්නාගේ ID සුපුරුද්ද අනුව සීමා වී ඇත. මීළඟ ඇමතුම: සීමා කර ඇත"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"අමතන්නාගේ ID සුපුරුදු අනුව සීමා වී ඇත. මීළඟ ඇමතුම: සීමා කර නැත"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"අමතන්නාගේ ID සුපුරුදු අනුව සීමා වී නැත. මීළඟ ඇමතුම: සීමා කර ඇත"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"කෙටි පණිවිඩ"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS පණිවිඩ යැවීම සහ බැලීම"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"ගොනු සහ ලේඛන"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"ඔබගේ උපාංගයේ ගොනු සහ ලේඛන වෙත ප්‍රවේශ වන්න"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"සංගීතය සහ වෙනත් ශ්‍රව්‍ය"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"ඔබගේ උපාංගයෙහි ඇති ශ්‍රව්‍ය ගොනුවලට ප්‍රවේශ වන්න"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"ඡායාරූප සහ වීඩියෝ"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ඉදිරියට යාමට ඔබගේ තිර අගුල ඇතුළත් කරන්න"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"අර්ධ ඇඟිලි සලකුණක් අනාවරණය කරන ලදි"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ඇඟිලි සලකුණ පිරිසැකසීමට නොහැකි විය. කරුණාකර නැවත උත්සාහ කරන්න."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ඇඟිලි සලකුණු සංවේදකය පිරිසිදු කර නැවත උත්සාහ කරන්න"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"සංවේදකය පිරිසිදු කර නැවත උත්සාහ කරන්න"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"සංවේදකය මත තදින් ඔබන්න"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"ඇඟිල්ල වඩා සෙමෙන් ගෙන යන ලදි. කරුණාකර නැවත උත්සාහ කරන්න."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"තවත් ඇඟිලි සලකුණක් උත්සාහ කරන්න"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"දීප්තිය වැඩියි"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"එක් එක් අවස්ථාවේ ඔබගේ ඇඟිල්ලේ පිහිටීම මදක් වෙනස් කරන්න"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ඇඟිලි සලකුණ හඳුනා නොගන්නා ලදි"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"සංවේදකය මත තදින් ඔබන්න"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ඇඟිලි සලකුණ සත්‍යාපනය කරන ලදී"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"මුහුණ සත්‍යාපනය කරන ලදී"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"මුහුණ සත්‍යාපනය කරන ලදී, කරුණාකර තහවුරු කරන්න ඔබන්න"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"වාහක සේවාව ඉහල මට්ටමේ අතුරු මුහුණතක් වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දෙන්න. සාමාන්‍ය යෙදුම්වලට කිසි විටෙක අවශ්‍ය නොවෙයි."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"වාහක සේවා වෙත බඳින්න"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"වාහක සේවා වෙත සම්බන්ධ කිරීමට ධාරකයාට අවසර දේ. සාමාන්‍ය යෙදුම් සඳහා කිසිදා අවශ්‍ය නොවිය යුතුය."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"බාධා නොකරන්න ප්‍රවේශ වන්න"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"බාධා නොකරන්න වින්‍යාස කිරීම කියවීමට සහ ලිවීමට යෙදුමට ඉඩ දෙයි."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"අවසර භාවිතය බැලීමට ආරම්භ කරන්න"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"තබා සිටින්නාට යෙදුමක් සඳහා අවසර භාවිතය ආරම්භ කිරීමට ඉඩ දෙයි. සාමාන්‍ය යෙදුම් සඳහා කිසි විටෙක අවශ්‍ය නොවිය යුතු ය."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"නව අවසර තීරණ ආරම්භ කරන්න"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"මඟ හරින්න"</string>
     <string name="no_matches" msgid="6472699895759164599">"ගැලපීම් නැත"</string>
     <string name="find_on_page" msgid="5400537367077438198">"පිටුවෙහි සෙවීම"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{ගැළපීම් #}one{{total}කින් #}other{{total}කින් #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"හරි"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"බෙදා ගත් ගබඩාව මකා දමමින්…"</string>
     <string name="share" msgid="4157615043345227321">"බෙදාගන්න"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක්"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක් (ඊළඟ එලාමය)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"ඔබ ක්‍රියාවිරහිත කරන තුරු"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"බාධා නොකරන්න ඔබ අක්‍රිය කරන තුරු"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"හකුළන්න"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"බාධා නොකරන්න"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"බිඳවැටුම් කාලය"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Weeknight"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"සති අන්තය"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"ඇමතුම් සහ දැනුම්දීම් කම්පනය වනු ඇත"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"ඇමතුම් සහ දැනුම්දීම් නිහඬ වනු ඇත"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"පද්ධති වෙනස් කිරීම්"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"බාධා නොකරන්න"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"නව: බාධා නොකරන්න දැනුම්දීම් සඟවමින්"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"තව දැන ගැනීමට සහ වෙනස් කිරීමට තට්ටු කරන්න."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"බාධා නොකරන්න වෙනස් කර ඇත"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"අවහිර කර ඇති දේ පරීක්ෂා කිරීමට තට්ටු කරන්න."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"පද්ධතිය"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"සැකසීම්"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"හරි"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ක්‍රියාවිරහිත කරන්න"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"තව දැන ගන්න"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"වැඩිදියුණු කළ දැනුම්දීම් Android 12 හි Android අනුවර්තී දැනුම්දීම් ප්‍රතිස්ථාපනය කරයි. මෙම විශේෂාංගය යෝජිත ක්‍රියා සහ පිළිතුරු පෙන්වන අතර, ඔබගේ දැනුම්දීම් සංවිධානය කරයි.\n\nවැඩිදියුණු කළ දැනුම්දීම්වලට සම්බන්ධතා නම් සහ පණිවිඩ වැනි පුද්ගලික තොරතුරු ඇතුළුව, සියලු දැනුම්දීම් අන්තර්ගතය වෙත ප්‍රවේශ විය හැකිය. මෙම විශේෂාංගයට දැනුම්දීම් ඉවත දැමීමට හෝ දුරකථන ඇමතුම්වලට පිළිතුරු දීම සහ බාධා නොකිරීම පාලනය කිරීම වැනි, දැනුම්දීම්වලට ප්‍රතිචාර දැක්වීමටද හැකිය."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"දිනචරියා ප්‍රකාර තතු දැනුම්දීම"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"බැටරිය සුපුරුදු ආරෝපණයට පෙර ඉවර විය හැක"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"බැටරි සුරැකුම බැටරි ආයු කාලය දීර්ඝ කිරීමට සක්‍රිය කෙරිණි"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> පසුබිමේ ධාවනය වන අතර බැටරිය බැස යයි. සමාලෝචනය කිරීමට තට්ටු කරන්න."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> දිගු වේලාවක් පසුබිමේ ධාවනය වේ. සමාලෝචනය කිරීමට තට්ටු කරන්න."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"සක්‍රිය යෙදුම් පරීක්ෂා කරන්න"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"මෙම උපාංගයෙන් කැමරාවට ප්‍රවේශ විය නොහැකිය"</string>
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ce70e5f..d06177d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Konferencia troch účastníkov"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Odmietnutie nevyžiadaných obťažujúcich hovorov"</string>
     <string name="CndMmi" msgid="185136449405618437">"Doručenie volaného čísla"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Režim bez vyrušení"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"V predvolenom nastavení je identifikácia volajúceho obmedzená. Ďalší hovor: Obmedzené"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"V predvolenom nastavení je identifikácia volajúceho obmedzená. Ďalší hovor: Bez obmedzenia"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"V predvolenom nastavení nie je identifikácia volajúceho obmedzená. Ďalší hovor: Obmedzené"</string>
@@ -738,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby na odosielanie správ SMS a MMS operátora. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"naviazať sa na služby operátora"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Umožňuje držiteľovi povolenia naviazať sa na služby operátora. Bežné aplikácie by toto povolenie nemali nikdy nepotrebovať."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"prístup k režimu bez vyrušení"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Umožňuje aplikácii čítať a zapisovať konfiguráciu režimu bez vyrušení."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"spustenie používania povolenia na zobrazenie"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Umožňuje držiteľovi spustiť používanie povolenia aplikáciou. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"spustenie zobrazenia rozhodnutí o povolení"</string>
@@ -1503,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Preskočiť"</string>
     <string name="no_matches" msgid="6472699895759164599">"Žiadne zhody"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Vyhľadať na stránke"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# zhoda}few{# z {total}}many{# of {total}}other{# z {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Hotovo"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Vymazáva sa zdieľané úložisko…"</string>
     <string name="share" msgid="4157615043345227321">"Zdieľať"</string>
@@ -1869,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ďalší budík)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Dokým funkciu nevypnete"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dokiaľ nevypnete režim bez vyrušení"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Zbaliť"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Režim bez vyrušení"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Doba pokoja"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noc pracovného dňa"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Víkend"</string>
@@ -2035,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Hovory a upozornenia budú vibrovať"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Hovory a upozornenia budú stlmené"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Zmeny systému"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Režim bez vyrušení"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novinka: režim bez vyrušení skrýva upozornenia"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Klepnutím získate ďalšie informácie a budete môcť vykonať zmeny."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Režim bez vyrušení sa zmenil"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Klepnutím skontrolujete, čo je blokované."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Systém"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavenia"</string>
@@ -2052,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Vypnúť"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Ďalšie informácie"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Adaptívne upozornenia Androidu boli v Androide 12 nahradené zlepšenými upozorneniami. Táto funkcia zobrazuje navrhované akcie aj odpovede a organizuje vaše upozornenia.\n\nZlepšené upozornenia majú prístup k obsahu upozornení vrátane osobných údajov, ako sú mená kontaktov a správy. Táto funkcia tiež môže zavrieť upozornenia alebo na ne reagovať, napríklad prijať telefonáty a ovládať režim bez vyrušení."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Upozornenie s informáciami o rutinnom režime"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batéria sa môže vybiť pred obvyklým nabitím"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Bol aktivovaný šetrič batérie na predĺženie výdrže batérie"</string>
@@ -2258,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikácie <xliff:g id="APP">%1$s</xliff:g> je spustená na pozadí a vybíja batériu. Skontrolujte to klepnutím."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikácia <xliff:g id="APP">%1$s</xliff:g> je dlhodobo spustená na pozadí. Skontrolujte to klepnutím."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Skontrolovať aktívne aplikácie"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"V tomto zariadení nemáte prístup ku kamere"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e23cf85..c1fbb04 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Trismerno klicanje"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Zavrnitev neželenih, motečih klicev"</string>
     <string name="CndMmi" msgid="185136449405618437">"Dostava na klicno številko"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ne moti"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID klicatelja je ponastavljen na omejeno. Naslednji klic: omejeno"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID klicatelja je ponastavljen na omejeno. Naslednji klic: ni omejeno"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID klicatelja je ponastavljen na neomejeno. Naslednji klic: omejeno"</string>
@@ -547,7 +548,7 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Aplikaciji dovoljuje oddajanje napravam Bluetooth v bližini."</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"določanje relativne oddaljenosti med napravami UWB v bližini"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Aplikaciji dovoli, da določi relativno oddaljenost med napravami UWB v bližini."</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"komunikacijo z napravami Wi‑Fi v bližini"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"komunikacija z napravami Wi‑Fi v bližini"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Aplikaciji dovoljuje objavljanje in določanje relativnega položaja naprav Wi‑Fi v bližini ter povezovanje z njimi."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Podatki o prednostni storitvi za plačevanje prek povezave NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Aplikaciji omogoča pridobivanje podatkov o prednostni storitvi za plačevanje prek povezave NFC, kot so registrirani pripomočki in cilj preusmeritve."</string>
@@ -738,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Imetniku omogoča povezovanje z vmesnikom operaterjeve sporočilne storitve najvišje ravni. To naj ne bi bilo nikoli potrebno za navadne aplikacije."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"povezovanje z operaterjevimi storitvami"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Imetniku omogoča povezovanje z operaterjevimi storitvami. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"dostop do načina »ne moti«"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Aplikaciji omogoča branje in pisanje konfiguracije načina »ne moti«."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"začetek uporabe dovoljenja za ogledovanje"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Imetniku omogoča začetek uporabe dovoljenj za aplikacijo. Nikoli ni potrebno za navadne aplikacije."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"prikaz odločitev o dovoljenjih"</string>
@@ -1503,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Preskoči"</string>
     <string name="no_matches" msgid="6472699895759164599">"Ni ujemanj"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Najdi na strani"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# ujemanje}one{# od {total}}two{# od {total}}few{# od {total}}other{# od {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Končano"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Brisanje skupne shrambe …"</string>
     <string name="share" msgid="4157615043345227321">"Deli"</string>
@@ -1869,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (naslednji alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Dokler ne izklopite"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Dokler ne izklopite načina »ne moti«"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Strni"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ne moti"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Čas nedelovanja"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Noč med tednom"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Konec tedna"</string>
@@ -2035,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibriranje bo vklopljeno za klice in obvestila"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Zvonjenje bo izklopljeno za klice in obvestila"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistemske spremembe"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ne moti"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Novi način »ne moti« skriva obvestila"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Dotaknite se, če želite izvedeti več in spremeniti."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Način »ne moti« je spremenjen"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Dotaknite se, da preverite, kaj je blokirano."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Nastavitve"</string>
@@ -2052,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"V redu"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Izklopi"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Več o tem"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Pametna obvestila so v Androidu 12 zamenjala prilagodljiva obvestila Android. Ta funkcija prikazuje predlagana dejanja in odgovore ter organizira vaša obvestila.\n\nPametna obvestila lahko preberejo vso vsebino obvestil, vključno z osebnimi podatki, kot so imena in sporočila stikov. Ta funkcija lahko tudi opusti obvestila ali se odziva nanje (npr. sprejema telefonske klice in upravlja način Ne moti)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutinsko informativno obvestilo o načinu delovanja"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Baterija se bo morda izpraznila, preden jo običajno priključite na polnjenje"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Vklopilo se je varčevanje z energijo baterije za podaljšanje časa delovanja baterije"</string>
@@ -2258,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se izvaja v ozadju in porablja energijo baterije. Dotaknite se za pregled."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> se dolgo časa izvaja v ozadju. Dotaknite se za pregled."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Preverite aktivne aplikacije"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"V tej napravi ni mogoče dostopati do fotoaparata."</string>
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index ec07f41..6303818 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Telefonata me tre drejtime"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Refuzimi i telefonatave të padëshirueshme e të bezdisshme"</string>
     <string name="CndMmi" msgid="185136449405618437">"Dërgimi i numrit të telefonit"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Mos shqetëso"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ID-ja e telefonuesit kalon me paracaktim në listën e të telefonuesve të kufizuar. Telefonata e radhës: E kufizuar!"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ID-ja e telefonuesit kalon me paracaktim në listën e të telefonuesve të kufizuar. Telefonata e radhës: e pakufizuar!"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ID-ja e telefonuesit kalon me paracaktim në listën e të telefonuesve të pakufizuar. Telefonata e radhës: e kufizuar!"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"qasje te kalendari yt"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"dërgo dhe shiko mesazhet SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Skedarët dhe dokumentet"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"përfito qasje te skedarët dhe dokumentet në pajisjen tënde"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muzikë dhe audio të tjera"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"të ketë qasje te skedarët audio në pajisjen tënde"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotografitë dhe videot"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Lejo që aplikacioni të përcaktojë pozicionin e përafërt mes pajisjeve në afërsi me brezin ultra të gjerë"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"të ndërveprojë me pajisjet Wi-Fi në afërsi"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lejon që aplikacioni të reklamojë, të lidhet dhe të përcaktojë pozicionin relativ të pajisjeve Wi-Fi në afërsi"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Lejon që aplikacioni të reklamojë, të lidhet dhe të përcaktojë pozicionin përkatës të pajisjeve Wi-Fi në afërsi"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Informacionet për shërbimin e preferuar të pagesës me NFC"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Lejon aplikacionin të marrë informacione për shërbimin e preferuar të pagesës me NFC si p.sh. ndihmat e regjistruara dhe destinacionin e itinerarit."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrollo \"Komunikimin e fushës në afërsi\" NFC"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fut kyçjen e ekranit për të vazhduar"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"U zbulua gjurmë gishti e pjesshme"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Gjurma e gishtit nuk mund të përpunohej. Provo përsëri."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Pastro sensorin e gjurmës së gishtit dhe provo sërish"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Pastro sensorin dhe provo sërish"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Shtyp fort te sensori"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Gishti lëvizi shumë ngadalë. Provo përsëri."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Provo një gjurmë gishti tjetër"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Me shumë ndriçim"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Ndrysho pak pozicionin e gishtit çdo herë"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Gjurma e gishtit nuk u njoh"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Shtyp fort te sensori"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Gjurma e gishtit u vërtetua"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Fytyra u vërtetua"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Fytyra u vërtetua, shtyp \"Konfirmo\""</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Lejon zotëruesin të lidhet me ndërfaqen e nivelit të lartë të shërbimit të mesazheve të operatorit. Nuk nevojitet për aplikacione normale."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"lidhu me shërbimet e operatorit celular"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Lejon që mbajtësi të lidhet me shërbimet e operatorit celular. Nuk nevojitet për aplikacionet normale."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"qasje te \"Mos shqetëso\""</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Lejon aplikacionin të lexojë dhe shkruajë konfigurimin e \"Mos shqetëso\"."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"nis përdorimin e lejes për shikimin"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Lejon që mbajtësi të nisë përdorimin e lejeve për një aplikacion. Nuk duhet të nevojitet asnjëherë për aplikacionet normale."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"nisë shikimin e vendimeve për lejet"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Kapërce"</string>
     <string name="no_matches" msgid="6472699895759164599">"Asnjë përputhje"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Gjej brenda faqes"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# përputhje}other{# nga {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"U krye"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Po fshin hapësirën ruajtëse të brendshme…"</string>
     <string name="share" msgid="4157615043345227321">"Shpërndaj"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (alarmi tjetër)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Derisa ta çaktivizosh"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Deri sa të çaktivizosh gjendjen \"Mos shqetëso\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Shpalos"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Mos shqetëso"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"periudha joaktive"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Netët e javës"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Fundjava"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Do të lëshojë dridhje për telefonatat dhe njoftimet"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Do të hiqet zëri për telefonatat dhe njoftimet"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Ndryshimet e sistemit"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Mos shqetëso"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"E re: Modaliteti \"Mos shqetëso\" po fsheh njoftimet"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Trokit për të mësuar më shumë dhe për të ndryshuar."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\"Mos shqetëso\" ka ndryshuar"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Trokit për të shënuar atë që është bllokuar"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistemi"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Cilësimet"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Në rregull"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Çaktivizo"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Mëso më shumë"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Njoftimet e përmirësuara kanë zëvendësuar \"Njoftimet me përshtatje të Android\" në Android 12. Kjo veçori shfaq veprimet dhe përgjigjet e sugjeruara dhe organizon njoftimet e tua.\n\nNjoftimet e përmirësuara mund të kenë qasje te përmbajtja e njoftimeve, duke përfshirë informacionet personale si emrat e kontakteve dhe mesazhet. Kjo veçori mund t\'i heqë ose të përgjigjet po ashtu për njoftimet, si p.sh. t\'u përgjigjet telefonatave, dhe të kontrollojë modalitetin \"Mos shqetëso\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Njoftimi i informacionit të \"Modalitetit rutinë\""</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Bateria mund të mbarojë përpara ngarkimit të zakonshëm"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"\"Kursyesi i baterisë\" u aktivizua për të rritur kohëzgjatjen e baterisë"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> po ekzekutohet në sfond dhe po shkarkon baterinë. Trokit për ta shqyrtuar."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> po ekzekutohet në sfond për një kohe të gjatë. Trokit për ta shqyrtuar."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollo aplikacionet aktive"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Nuk mund të qasesh te kamera nga kjo pajisje"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index caac95b..d9b1931 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -71,6 +71,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Тросмерно позивање"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Одбијање непожељних позива"</string>
     <string name="CndMmi" msgid="185136449405618437">"Испорука броја за позивање"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Не узнемиравај"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"ИД позиваоца је подразумевано ограничен. Следећи позив: ограничен."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"ИД позиваоца је подразумевано ограничен. Следећи позив: Није ограничен."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"ИД позиваоца подразумевано није ограничен. Следећи позив: ограничен."</string>
@@ -305,10 +306,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"приступи календару"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"шаље и прегледа SMS поруке"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Фајлови и документи"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"приступање фајловима и документима на уређају"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика и други аудио садржај"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"приступ аудио фајловима на уређају"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Слике и видео снимци"</string>
@@ -589,12 +588,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Употребите закључавање екрана да бисте наставили"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Откривен је делимичан отисак прста"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Није успела обрада отиска прста. Пробајте поново."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Обришите сензор за отисак прста и пробајте поново"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Обришите сензор и пробајте поново"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Јако притисните сензор"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Превише споро сте померили прст. Пробајте поново."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Пробајте са другим отиском прста"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Превише је светло"</string>
@@ -602,10 +598,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Сваки пут лагано промените положај прста"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Отисак прста није препознат"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Јако притисните сензор"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Отисак прста је потврђен"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Лице је потврђено"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Лице је потврђено. Притисните Потврди"</string>
@@ -744,6 +738,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Дозвољава власнику да се повеже са интерфејсом највишег нивоа за услугу за размену порука мобилног оператера. Никада не би требало да буде потребно за стандардне апликације."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"повезивање са услугама оператера"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Дозвољава власнику да се повеже са услугама оператера. Никада не би требало да буде потребно за обичне апликације."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"приступај подешавању Не узнемиравај"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Дозвољава апликацији да чита и уписује конфигурацију подешавања Не узнемиравај."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"почетак коришћења дозволе за преглед"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Дозвољава власнику да започне коришћење дозволе за апликацију. Никада не би требало да буде потребна за уобичајене апликације."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"покретање прегледа одлука о дозволама"</string>
@@ -1509,8 +1505,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Прескочи"</string>
     <string name="no_matches" msgid="6472699895759164599">"Нема подударања"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Пронађи на страници"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# подударање}one{# од {total}}few{# од {total}}other{# од {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Готово"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Брише се дељени меморијски простор…"</string>
     <string name="share" msgid="4157615043345227321">"Дели"</string>
@@ -1875,8 +1870,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (следећи аларм)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Док не искључите"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Док не искључите режим Не узнемиравај"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Скупи"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не узнемиравај"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Одмор"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Радни дан увече"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Викенд"</string>
@@ -2041,7 +2038,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Вибрација за позиве и обавештења је укључена"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Мелодија звона за позиве и обавештење је искључена"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Системске промене"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не узнемиравај"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Ново: Режим Не узнемиравај крије обавештења"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Додирните да бисте сазнали више и променили подешавање."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Режим Не узнемиравај је промењен"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Додирните да бисте проверили шта је блокирано."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Систем"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Подешавања"</string>
@@ -2058,6 +2058,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Потврди"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Искључи"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Сазнајте више"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Побољшана обавештења су заменила Android прилагодљива обавештења у Android-у 12. Ова функција показује предложене радње и одговоре, и организује обавештења.\n\nПобољшана обавештења могу да приступају садржају обавештења, укључујући личне податке попут имена контаката и порука. Ова функција може и да одбацује обавештења или да одговара на њих, на пример, да се јавља на телефонске позиве и контролише режим Не узнемиравај."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Обавештење о информацијама Рутинског режима"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Батерија ће се можда испразнити пре уобичајеног пуњења"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Уштеда батерије је активирана да би се продужило трајање батерије"</string>
@@ -2096,7 +2097,7 @@
     <string name="accessibility_system_action_notifications_label" msgid="6083767351772162010">"Обавештења"</string>
     <string name="accessibility_system_action_quick_settings_label" msgid="4583900123506773783">"Брза подешавања"</string>
     <string name="accessibility_system_action_power_dialog_label" msgid="8095341821683910781">"Дијалог напајања"</string>
-    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Закључани екран"</string>
+    <string name="accessibility_system_action_lock_screen_label" msgid="5484190691945563838">"Закључавање екрана"</string>
     <string name="accessibility_system_action_screenshot_label" msgid="3581566515062741676">"Снимак екрана"</string>
     <string name="accessibility_system_action_headset_hook_label" msgid="8524691721287425468">"Кука за слушалице"</string>
     <string name="accessibility_system_action_on_screen_a11y_shortcut_label" msgid="8488701469459210309">"Пречица за приступачност на екрану"</string>
@@ -2261,9 +2262,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Порука је преведена са језика <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> на <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Активност у позадини"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Активност у позадини"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Апликација <xliff:g id="APP">%1$s</xliff:g> је покренута у позадини и троши батерију. Додирните да бисте прегледали."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Апликација <xliff:g id="APP">%1$s</xliff:g> троши батерију у позадини. Додирните да бисте прегледали."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Апликација <xliff:g id="APP">%1$s</xliff:g> је предуго покренута у позадини. Додирните да бисте прегледали."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Проверите активне апликације"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не можете да приступите камери са овог уређаја"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4adcc47..a969fac 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Trepartssamtal"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Avvisande av oönskade irriterande samtal"</string>
     <string name="CndMmi" msgid="185136449405618437">"Leverans av nummer för inkommande samtal"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Stör ej"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Nummerpresentatören är blockerad som standard. Nästa samtal: Blockerad"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Nummerpresentatörens standardinställning är blockerad. Nästa samtal: Inte blockerad"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Nummerpresentatörens standardinställning är inte blockerad. Nästa samtal: Blockerad"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"få tillgång till din kalender"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Sms"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"skicka och visa sms"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Filer och dokument"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"visa filer och dokument på enheten"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musik och övrigt ljud"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"komma åt ljudfiler på din enhet"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Foton och videor"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Fortsätt med hjälp av ditt skärmlås"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Ofullständigt fingeravtryck upptäcktes"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Det gick inte att bearbeta fingeravtrycket. Försök igen."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Rengör fingeravtryckssensorn och försök igen"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Rengör sensorn och försök igen"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Tryck på sensorn med ett stadigt tryck"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Du rörde fingret för långsamt. Försök igen."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Testa ett annat fingeravtryck"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Det är för ljust"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Flytta fingret lite varje gång"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Fingeravtrycket känns inte igen"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Tryck på sensorn med ett stadigt tryck"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Fingeravtrycket har autentiserats"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Ansiktet har autentiserats"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Ansiktet har autentiserats. Tryck på Bekräfta"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en operatörs meddelandetjänst. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"binder till leverantörstjänster"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Tillåter att innehavaren binder till leverantörstjänster. Det här ska inte behövas för vanliga appar."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"åtkomst till Stör ej"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ger appen läs- och skrivbehörighet till konfigurationen för Stör ej."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"börja visa behörighetsanvändningen"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Gör att innehavaren kan öppna behörighetsanvändning för en app. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"börja visa behörighetsbeslut"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Hoppa över"</string>
     <string name="no_matches" msgid="6472699895759164599">"Inga träffar"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Sök på sidan"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# resultat}other{# av {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Klar"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Delat lagringsutrymme rensas …"</string>
     <string name="share" msgid="4157615043345227321">"Dela"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Till <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Till <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nästa alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Tills du stänger av"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Tills du inaktiverar Stör ej"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Komprimera"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Stör ej"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Avbrottstid"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Vardagskväll"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"I helgen"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Vibrerar vid samtal och aviseringar"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Ljudet stängs av för samtal och aviseringar"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Systemändringar"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Stör ej"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Nytt: Aviseringar döljs av Stör ej"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Tryck här om du vill läsa mer och ändra inställningarna."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Stör ej har ändrats"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Tryck om du vill se vad som blockeras."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Inställningar"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Inaktivera"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Läs mer"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Förbättrade aviseringar har ersatt Anpassade aviseringar för Android i Android 12. Den här funktionen visar förslag på åtgärder och svar och organiserar dina aviseringar.\n\nFörbättrade aviseringar har åtkomst till allt innehåll i aviseringar, inklusive personliga uppgifter som namn på kontakter och meddelanden. Funktionen kan även ignorera aviseringar eller utföra åtgärder utifrån dem, till exempel svara på telefonsamtal och styra Stör ej."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Avisering om rutinläge"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batteriet kan ta slut innan du brukar ladda det"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batterisparläget har aktiverats för att utöka batteritiden"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> körs i bakgrunden så att batteriet tar slut fortare. Tryck för att granska."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> har körts i bakgrunden under lång tid. Tryck för att granska."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Kontrollera aktiva appar"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Det går inte att komma åt kameran från den här enheten"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 02572b0..6351769 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Upigaji simu kwa njia tatu"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Ukataaji wa simu zinazokera zisizohitajika"</string>
     <string name="CndMmi" msgid="185136449405618437">"Kuonyeshwa kwa nambari inayopiga"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Usinisumbue"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Chaguomsingi za ID ya mpigaji simu za kutozuia. Simu ifuatayo: Imezuiliwa"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Chaguomsingi za kitambulisho cha mpigaji simu huwa kuzuiwa. Simu ifuatayo: Haijazuiliwa"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Chaguomsingi za ID ya mpigaji simu za kutozuia. Simu ifuatayo:Imezuiliwa"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"ifikie kalenda yako"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"itume na iangalie SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Faili na hati"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"fikia faili na hati kwenye kifaa chako"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Muziki na sauti nyingine"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"fikia faili za sauti kwenye kifaa chako"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Picha na video"</string>
@@ -539,13 +538,13 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Huruhusu programu kuona usanidi wa Bluetooth kwenye kompyuta kibao, na kutuma na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Huruhusu programu iangalie mipangilio iliyowekwa ya Bluetooth kwenye kifaa chako cha Android TV na kufanya na kukubali miunganisho na vifaa vilivyooanishwa."</string>
     <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Huruhusu programu kuona usanidi wa Bluetooth kwenye simu, na kutuma na kukubali miunganisho kwa vifaa vilivyooanishwa."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"kutambua na kuoanisha vifaa vyenye Bluetooth vilivyo karibu"</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"tambua na oanishe vifaa vyenye Bluetooth vilivyo karibu"</string>
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Huruhusu programu itambue na kuoanisha kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
-    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"kuunganisha kwenye vifaa vyenye Bluetooth vilivyooanishwa"</string>
+    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"unganisha kwenye vifaa vyenye Bluetooth vilivyooanishwa"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Huruhusu programu iunganishe kwenye vifaa vyenye Bluetooth vilivyooanishwa"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"kutangaza kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"tangaza kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Huruhusu programu itangaze kwenye vifaa vyenye Bluetooth vilivyo karibu"</string>
-    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"kubainisha nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
+    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"bainisha nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ruhusu programu ibainishe nafasi kati ya vifaa vyenye Bendi Pana Zaidi vilivyo karibu"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tumia vifaa vya Wi‑Fi vilivyo karibu"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Huruhusu programu kutangaza, kuunganisha na kubaini mahali palipokadiriwa vilipo vifaa vya Wi-Fi vilivyo karibu"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Weka mbinu yako ya kufunga skrini ili uendelee"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Kimetambua sehemu ya alama ya kidole"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Imeshindwa kuchakata alama ya kidole. Tafadhali jaribu tena."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Safisha kitambua alama ya kidole kisha ujaribu tena"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Safisha kitambuzi kisha ujaribu tena"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Bonyeza kwa nguvu kwenye kitambuzi"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Kidole kilisogezwa polepole zaidi. Tafadhali jaribu tena."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Jaribu alama nyingine ya kidole"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Inang\'aa mno"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Badilisha mkao wa kidole chako kiasi kila wakati"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Alama ya kidole haijatambuliwa"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Bonyeza kwa nguvu kwenye kitambuzi"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Imethibitisha alama ya kidole"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Uso umethibitishwa"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Uso umethibitishwa, tafadhali bonyeza thibitisha"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Huruhusu kishikiliaji kushurutisha kwa kiolesura cha hali ya juu cha huduma ya ujumbe ya mtoa huduma. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bandika kwenye huduma ya mtoa huduma"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Huruhusu mmiliki kubandika kwenye huduma ya mtoa huduma. Haipaswi kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"fikia kipengee cha Usinisumbue"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Inaruhusu programu kusoma na kuandika usanidi wa kipengee cha Usinisumbue."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"anzisha kipengele cha kuona matumizi ya ruhusa"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Huruhusu kishikiliaji kuanzisha matumizi ya ruhusa ya programu. Haipaswi kuhitajika kwa ajili ya programu za kawaida."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"kuanzisha uamuzi wa ruhusa za kuangalia"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Ruka"</string>
     <string name="no_matches" msgid="6472699895759164599">"Hakuna vinavyolingana"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Pata kwenye ukurasa"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# inayolingana}other{# kati ya {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Nimemaliza"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Inafuta hifadhi iliyoshirikiwa…"</string>
     <string name="share" msgid="4157615043345227321">"Shiriki"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Hadi <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Mpaka <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (kengele inayofuata)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Hadi utakapoizima"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Hadi utakapozima Usinisumbue"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Kunja"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Usinisumbue"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Wakati wa hali tuli"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Usiku wa wiki"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Wikendi"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Itatetema arifa ikitumwa au simu ikipigwa"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Haitatoa mlio arifa ikitumwa au simu ikipigwa"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Mabadiliko kwenye mfumo"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Usinisumbue"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Mpya: Kipengele cha Usinisumbue kinaficha arifa"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Gusa ili upate maelezo zaidi na ubadilishe."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Kipengele cha Usinisumbue kimebadilishwa"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Gusa ili uangalie kipengee ambacho kimezuiwa."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Mfumo"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Mipangilio"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Sawa"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Zima"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Pata maelezo zaidi"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Kipengele cha Arifa Zilizoboreshwa kilichukua nafasi ya Arifa Zinazojirekebisha za Android katika Android 12. Kipengele hiki kinaonyesha majibu na vitendo vinavyopendekezwa na kupanga arifa zako.\n\nKipengele cha Arifa zilizoboreshwa kinaweza kufikia maudhui ya arifa, ikiwa ni pamoja na taarifa binafsi kama vile majina ya anwani na ujumbe. Kipengele hiki kinaweza pia kuondoa au kujibu arifa, kama vile kujibu simu na kudhibiti kipengele cha Usinisumbue."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Arifa ya maelezo ya Hali ya Kawaida"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Huenda betri itakwisha chaji mapema"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Imewasha Kiokoa Betri ili kurefusha muda wa matumizi ya betri"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> inatumika chinichini na kumaliza nishati ya betri. Gusa ili ukague."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> inatumika chinichini kwa muda mrefu. Gusa ili ukague."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Angalia programu zinazotumika"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Haiwezi kufikia kamera kwenye kifaa hiki"</string>
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 9acbac6..09a361e 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"மும்முனை அழைப்பு"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"விரும்பத்தகாத தொல்லைதரும் அழைப்புகளை நிராகரித்தல்"</string>
     <string name="CndMmi" msgid="185136449405618437">"அழைப்பின் விவரங்கள்"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"தொந்தரவு செய்யாதே"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"அழைப்பாளர் ஐடி ஆனது வரையறுக்கப்பட்டது என்பதற்கு இயல்பாக அமைக்கப்பட்டது. அடுத்த அழைப்பு: வரையறுக்கப்பட்டது"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"அழைப்பாளர் ஐடி ஆனது வரையறுக்கப்பட்டது என்பதற்கு இயல்பாக அமைக்கப்பட்டது. அடுத்த அழைப்பு: வரையறுக்கப்படவில்லை"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"அழைப்பாளர் ஐடி ஆனது வரையறுக்கப்படவில்லை என்பதற்கு இயல்பாக அமைக்கப்பட்டது. அடுத்த அழைப்பு: வரையறுக்கப்பட்டது"</string>
@@ -545,7 +546,7 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"அருகிலுள்ள புளூடூத் சாதனங்களுக்குத் தெரியப்படுத்த ஆப்ஸை அனுமதிக்கும்"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"அருகிலுள்ள அல்ட்ரா-வைடுபேண்ட் சாதனங்களுக்கிடையிலான தூரத்தைத் தீர்மானித்தல்"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"அருகிலுள்ள அல்ட்ரா-வைடுபேண்ட் சாதனங்களுக்கிடையிலான தூரத்தைத் தீர்மானிக்க ஆப்ஸை அனுமதிக்கும்"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"அருகிலுள்ள வைஃபை சாதனங்களுடன் தொடர்பில் இருக்கும்"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"அருகிலுள்ள வைஃபை சாதனங்களுடன் தொடர்பு கொள்ளுதல்"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"அருகிலுள்ள வைஃபை சாதனங்களைத் தெரியப்படுத்தவும் இணைக்கவும் இருப்பிடத்தைத் தீர்மானிக்கவும் இது ஆப்ஸை அனுமதிக்கும்"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்கள்"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"பதிவுசெய்யப்பட்ட கருவிகள், சேருமிடத்திற்கான வழி போன்ற விருப்பமான NFC பேமெண்ட் சேவை தொடர்பான தகவல்களைப் பெற ஆப்ஸை அனுமதிக்கிறது."</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"மொபைல் நிறுவனச் செய்தியிடல் சேவையின் உயர்-நிலை இடைமுகத்துடன் ஹோல்டரை இணைக்க அனுமதிக்கும். இயல்பான பயன்பாடுகளுக்குத் தேவைப்படாது."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"மொபைல் நிறுவன சேவைகளுடன் இணைத்தல்"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"மொபைல் நிறுவன சேவைகளுடன் இணைக்க, ஹோல்டரை அனுமதிக்கும். சாதாரணப் பயன்பாடுகளுக்கு எப்போதுமே தேவைப்படாது."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"தொந்தரவு செய்ய வேண்டாம் அம்சத்தை அணுகுதல்"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"தொந்தரவு செய்ய வேண்டாம் உள்ளமைவைப் படிக்கவும் எழுதவும், ஆப்ஸை அனுமதிக்கிறது."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"அனுமதி உபயோகத்தை அணுகுதல்"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"ஆப்ஸிற்கான அனுமதி உபயோகத்தை ஹோல்டருக்கு வழங்கும். இயல்பான ஆப்ஸிற்கு இது எப்போதுமே தேவைப்படாது."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"அனுமதி முடிவுகளைப் பார்க்கத் தொடங்குதல்"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"தவிர்"</string>
     <string name="no_matches" msgid="6472699895759164599">"பொருத்தம் ஏதுமில்லை"</string>
     <string name="find_on_page" msgid="5400537367077438198">"பக்கத்தில் கண்டறி"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# பொருத்தம்}other{# / {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"முடிந்தது"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"பகிர்ந்த சேமிப்பகத்தை அழிக்கிறது…"</string>
     <string name="share" msgid="4157615043345227321">"பகிர்"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> வரை"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> மணி (அடுத்த அலாரம்) வரை"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"ஆஃப் செய்யும் வரை"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"\'தொந்தரவு செய்யாதே\' என்பதை முடக்கும் வரை"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"சுருக்கு"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"தொந்தரவு செய்யாதே"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"செயலற்ற நேரம்"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"வார இரவு"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"வார இறுதி"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"அழைப்புகள் மற்றும் அறிவிப்புகளுக்கு அதிரும்"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"அழைப்புகள் மற்றும் அறிவிப்புகளுக்கு ஒலியை முடக்கும்"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"சிஸ்டம் மாற்றங்கள்"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"தொந்தரவு செய்ய வேண்டாம்"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"புதியது: \'தொந்தரவு செய்ய வேண்டாம்\' பயன்முறையானது அறிவிப்புகளைக் காட்டாமல் மறைக்கிறது"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"மேலும் அறிந்து மாற்ற, தட்டவும்."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"தொந்தரவு செய்ய வேண்டாம் அமைப்புகள் மாற்றப்பட்டன"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"எவற்றையெல்லாம் தடுக்கிறது என்பதைப் பார்க்க, தட்டவும்."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"சிஸ்டம்"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"அமைப்புகள்"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"சரி"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ஆஃப் செய்"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"மேலும் அறிக"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 பதிப்பில் \'Android சூழலுக்கேற்ற அறிவிப்புகள்\' அம்சத்திற்குப் பதிலாக \'மேம்பட்ட அறிவிப்புகள்\' மாற்றப்பட்டுள்ளது. இந்த அம்சம், பரிந்துரைக்கப்படும் செயல்களையும் பதில்களையும் காட்டுவதுடன் உங்கள் அறிவிப்புகளையும் ஒழுங்கமைக்கும்.\n\nதொடர்புகளின் பெயர்கள், மெசேஜ்கள் போன்ற தனிப்பட்ட தகவல்கள் உட்பட அனைத்து அறிவிப்பு உள்ளடக்கத்தையும் \'மேம்பட்ட அறிவிப்புகள்\' அணுக முடியும். மேலும் இந்த அம்சத்தால் அறிவிப்புகளை நிராகரிக்கவும் அவற்றுக்குப் பதிலளிக்கவும் முடியும் (அழைப்புகளுக்குப் பதிலளிப்பது, \'தொந்தரவு செய்ய வேண்டாம்\' அம்சத்தைக் கட்டுப்படுத்துவது போன்றவை)."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"வழக்கமான பேட்டரி சேமிப்பானுக்கான விவர அறிவிப்பு"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"வழக்கமாகச் சார்ஜ் செய்வதற்கு முன்பே பேட்டரி தீர்ந்துபோகக்கூடும்"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"பேட்டரி நிலையை நீட்டிக்க பேட்டரி சேமிப்பான் இயக்கப்பட்டுள்ளது"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பின்னணியில் இயங்குவதுடன் பேட்டரியை அதிகமாகப் பயன்படுத்துகிறது. பார்க்க தட்டவும்."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் நீண்ட நேரமாகப் பின்னணியில் இயங்குகிறது. பார்க்க தட்டவும்."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"செயலிலுள்ள ஆப்ஸைப் பாருங்கள்"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"இந்தச் சாதனத்திலிருந்து கேமராவை அணுக முடியவில்லை"</string>
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 6e4ef59..21290e9 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"మూడు మార్గాల కాలింగ్"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"అవాంఛిత అంతరాయ కాల్స్‌ల తిరస్కరణ"</string>
     <string name="CndMmi" msgid="185136449405618437">"కాలింగ్ నంబర్ బట్వాడా"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"అంతరాయం కలిగించవద్దు"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"కాలర్ ID ఆటోమేటిక్‌లపై పరిమితి ఉంటుంది. తర్వాత కాల్: పరిమితి ఉంటుంది"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"కాలర్ ID ఆటోమేటిక్‌లపై పరిమితి ఉంటుంది. తర్వాత కాల్: పరిమితి లేదు"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"కాలర్ ID ఆటోమేటిక్‌లపై పరిమితి లేదు. తర్వాత కాల్: పరిమితి ఉంటుంది"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"క్యారియర్ మెసేజింగ్ సర్వీస్‌ యొక్క అగ్ర-స్థాయి ఇంటర్‌ఫేస్‌కు అనుబంధించడానికి హోల్డర్‌ను అనుమతిస్తుంది. సాధారణ యాప్‌లకు ఎప్పటికీ అవసరం ఉండదు."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"క్యారియర్ సేవలకు అనుబంధించడం"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"క్యారియర్ సేవలకు అనుబంధించడానికి హోల్డర్‌ను అనుమతిస్తుంది. సాధారణ యాప్‌లకు ఎప్పటికీ అవసరం ఉండదు."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"అంతరాయం కలిగించవద్దును యాక్సెస్ చేయడం"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"అంతరాయం కలిగించవద్దు ఎంపిక కాన్ఫిగరేషన్ చదవడానికి మరియు రాయడానికి యాప్‌ను అనుమతిస్తుంది."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"వీక్షణ అనుమతి వినియోగాన్ని ప్రారంభించండి"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"యాప్‌నకు అనుమతి వినియోగాన్ని ప్రారంభించడానికి హోల్డర్‌‌ను అనుమతిస్తుంది. సాధారణ యాప్‌లకు ఎప్పటికీ ఇటువంటి అనుమతి అవసరం ఉండదు."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"వీక్షణ అనుమతి నిర్ణయాలను ప్రారంభించండి"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"దాటవేయి"</string>
     <string name="no_matches" msgid="6472699895759164599">"సరిపోలికలు లేవు"</string>
     <string name="find_on_page" msgid="5400537367077438198">"పేజీలో కనుగొనండి"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# మ్యాచ్}other{#లో {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"పూర్తయింది"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"షేర్ చేసిన నిల్వను తొలగిస్తోంది…"</string>
     <string name="share" msgid="4157615043345227321">"షేర్"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> వరకు"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (తర్వాత అలారం) వరకు"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"మీరు ఆఫ్‌ చేసే వరకు"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"మీరు అంతరాయం కలిగించవద్దు ఎంపిక ఆఫ్ చేసే వరకు"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"కుదించండి"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"అంతరాయం కలిగించవద్దు"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ముఖ్యమైన పనిలో ఉన్నప్పుడు"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"వారపు రోజుల్లో రాత్రి"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"వారాంతం"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"కాల్స్‌ మరియు నోటిఫికేషన్‌లు వైబ్రేట్ అవుతాయి"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"కాల్స్‌ మరియు నోటిఫికేషన్‌లు మ్యూట్ చేయబడతాయి"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"సిస్టమ్ మార్పులు"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"అంతరాయం కలిగించవద్దు"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"కొత్తది: అంతరాయం కలిగించవద్దు నోటిఫికేషన్‌లను దాస్తోంది"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"మరింత తెలుసుకోవడానికి మరియు మార్చడానికి నొక్కండి."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"అంతరాయం కలిగించవద్దు మార్చబడింది"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"బ్లాక్ చేయబడిన దాన్ని తనిఖీ చేయడానికి నొక్కండి."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"సిస్టమ్"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"సెట్టింగ్‌లు"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"సరే"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ఆఫ్ చేయండి"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"మరింత తెలుసుకోండి"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12లో Android అనుకూల నోటిఫికేషన్‌లను, మెరుగైన నోటిఫికేషన్‌లు రీప్లేస్‌ చేశాయి. ఈ ఫీచర్, సూచించిన చర్యలను, రిప్లయిలను చూపించి, మీ నోటిఫికేషన్‌లను ఆర్గనైజ్ చేస్తుంది.\n\nకాంటాక్ట్ పేర్లు, మెసేజ్‌లు లాంటి వ్యక్తిగత సమాచారంతో పాటు నోటిఫికేషన్ కంటెంట్‌ను మెరుగైన నోటిఫికేషన్‌లు యాక్సెస్ చేస్తాయి. ఫోన్ కాల్స్‌కు సమాధానమివ్వడం, \'అంతరాయం కలిగించవద్దు\' ఆప్షన్‌ను కంట్రోల్ చేయడం వంటి నోటిఫికేషన్‌లను విస్మరించడం లేదా వాటికి ప్రతిస్పందించడం కూడా ఈ ఫీచర్ చేయగలదు."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"రొటీన్ మోడ్ సమాచార నోటిఫికేషన్"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"మామూలుగా ఛార్జ్ చేసేలోపు బ్యాటరీ ఖాళీ కావచ్చు"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"బ్యాటరీ జీవితకాలాన్ని పెంచడానికి బ్యాటరీ సేవర్ యాక్టివేట్ చేయబడింది"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> బ్యాక్‌గ్రౌండ్‌లో రన్ అవుతోంది, బ్యాటరీని ఎక్కువగా వాడుతోంది. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> చాలా సమయం నుండి బ్యాక్‌గ్రౌండ్‌లో రన్ అవుతోంది. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"యాక్టివ్‌గా ఉన్న యాప్‌లను చెక్ చేయండి"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"ఈ పరికరం నుండి కెమెరాను యాక్సెస్ చేయడం సాధ్యపడదు"</string>
 </resources>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index 0db08fb..88bf18c 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -24,19 +24,6 @@
     <!-- Flags enabling default window features. See Window.java -->
     <bool name="config_defaultWindowFeatureOptionsPanel">false</bool>
 
-    <!-- The percentage of the screen width to use for the default width or height of
-         picture-in-picture windows. Regardless of the percent set here, calculated size will never
-         be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
-    <item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.2</item>
-
-    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
-         These values are in DPs and will be converted to pixel sizes internally. -->
-    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">24x24</string>
-
-    <!-- The default gravity for the picture-in-picture window.
-         Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
-    <integer name="config_defaultPictureInPictureGravity">0x55</integer>
-
     <!-- The maximum height of the expanded horizontal picture-in-picture window -->
     <item name="config_pictureInPictureExpandedHorizontalHeight"
           format="dimension" type="dimen">110dp</item>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 4b33e95..883da19 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"การโทรสามสาย"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"การปฏิเสธสายรบกวนที่ไม่ต้องการ"</string>
     <string name="CndMmi" msgid="185136449405618437">"การส่งหมายเลขที่โทร"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ห้ามรบกวน"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"หมายเลขผู้โทรได้รับการตั้งค่าเริ่มต้นเป็นถูกจำกัด การโทรครั้งต่อไป: ถูกจำกัด"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"หมายเลขผู้โทรได้รับการตั้งค่าเริ่มต้นเป็นถูกจำกัด การโทรครั้งต่อไป: ไม่จำกัด"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"หมายเลขผู้โทรได้รับการตั้งค่าเริ่มต้นเป็นไม่จำกัด การโทรครั้งต่อไป: ถูกจำกัด"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"เข้าถึงปฏิทิน"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"ส่งและดูข้อความ SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"ไฟล์และเอกสาร"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"เข้าถึงไฟล์และเอกสารในอุปกรณ์"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"เพลงและเสียงอื่นๆ"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"เข้าถึงไฟล์เสียงในอุปกรณ์"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"รูปภาพและวิดีโอ"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"ป้อนข้อมูลการล็อกหน้าจอเพื่อดำเนินการต่อ"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"ตรวจพบลายนิ้วมือบางส่วน"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"ประมวลผลลายนิ้วมือไม่ได้ โปรดลองอีกครั้ง"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"ทำความสะอาดเซ็นเซอร์ลายนิ้วมือแล้วลองอีกครั้ง"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"ทำความสะอาดเซ็นเซอร์แล้วลองอีกครั้ง"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"กดเซ็นเซอร์ให้แน่น"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"นิ้วเคลื่อนที่ช้าเกินไป โปรดลองอีกครั้ง"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"ลองลายนิ้วมืออื่น"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"สว่างเกินไป"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"เปลี่ยนตำแหน่งของนิ้วเล็กน้อยไปเรื่อยๆ ทุกครั้ง"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"ไม่รู้จักลายนิ้วมือ"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"กดเซ็นเซอร์ให้แน่น"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"ตรวจสอบสิทธิ์ลายนิ้วมือแล้ว"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"ตรวจสอบสิทธิ์ใบหน้าแล้ว"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"ตรวจสอบสิทธิ์ใบหน้าแล้ว โปรดกดยืนยัน"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"อนุญาตให้แอปพลิเคชันเชื่อมโยงกับอินเทอร์เฟซระดับบนสุดของบริการรับส่งข้อความของผู้ให้บริการ ไม่ควรใช้สำหรับแอปธรรมดาทั่วไป"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"เชื่อมโยงกับบริการของผู้ให้บริการ"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"อนุญาตให้เจ้าของเชื่อมโยงกับบริการของผู้ให้บริการ ไม่ควรต้องใช้สำหรับแอปทั่วไป"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"เข้าถึงโหมดห้ามรบกวน"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"อนุญาตให้แอปอ่านและเขียนการกำหนดค่าโหมดห้ามรบกวน"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"เริ่มการใช้สิทธิ์การดู"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"อนุญาตให้เจ้าของเริ่มการใช้สิทธิ์ของแอป ไม่จำเป็นสำหรับแอปทั่วไป"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"เริ่มดูสิทธิ์ที่เลือกไว้"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"ข้าม"</string>
     <string name="no_matches" msgid="6472699895759164599">"ไม่พบรายการที่ตรงกัน"</string>
     <string name="find_on_page" msgid="5400537367077438198">"ค้นหาบนหน้า"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{ตรงกัน # รายการ}other{ตรงกัน # รายการจาก {total} รายการ}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"เสร็จสิ้น"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"กำลังลบพื้นที่เก็บข้อมูลที่แชร์…"</string>
     <string name="share" msgid="4157615043345227321">"แชร์"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (การปลุกครั้งถัดไป)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"จนกว่าคุณจะปิด"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"จนกว่าคุณจะปิดห้ามรบกวน"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"ยุบ"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ห้ามรบกวน"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ช่วงเวลาเครื่องไม่ทำงาน"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"คืนวันธรรมดา"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"สุดสัปดาห์"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"สายเรียกเข้าและการแจ้งเตือนจะสั่น"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"สายเรียกเข้าและการแจ้งเตือนจะไม่ส่งเสียง"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"การเปลี่ยนแปลงระบบ"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ห้ามรบกวน"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"ใหม่: โหมดห้ามรบกวนซ่อนการแจ้งเตือนไว้"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"แตะเพื่อดูข้อมูลเพิ่มเติมและเปลี่ยนแปลง"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"เปลี่ยน \"ห้ามรบกวน\" แล้ว"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"แตะเพื่อดูรายการที่ถูกบล็อก"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"ระบบ"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"การตั้งค่า"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ตกลง"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"ปิด"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"ดูข้อมูลเพิ่มเติม"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"การแจ้งเตือนที่เพิ่มประสิทธิภาพมาแทนที่การแจ้งเตือนแบบปรับอัตโนมัติของ Android ใน Android 12 ฟีเจอร์นี้จะแสดงการดำเนินการและการตอบกลับที่แนะนำ ตลอดจนจัดระเบียบการแจ้งเตือน\n\nการแจ้งเตือนที่เพิ่มประสิทธิภาพจะเข้าถึงเนื้อหาของการแจ้งเตือนได้ ซึ่งรวมถึงข้อมูลส่วนบุคคล เช่น ชื่อผู้ติดต่อและข้อความ ฟีเจอร์นี้ยังปิดหรือตอบสนองต่อการแจ้งเตือนได้ด้วย เช่น การรับสายโทรศัพท์และการควบคุมโหมดห้ามรบกวน"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"การแจ้งเตือนข้อมูลโหมดกิจวัตร"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"แบตเตอรี่อาจหมดก่อนการชาร์จปกติ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"เปิดใช้งานโหมดประหยัดแบตเตอรี่แล้วเพื่อยืดอายุการใช้งานแบตเตอรี่"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> กำลังทำงานอยู่ในเบื้องหลังและทำให้เปลืองแบตเตอรี่ แตะเพื่อตรวจสอบ"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> ทำงานอยู่ในเบื้องหลังเป็นเวลานาน แตะเพื่อตรวจสอบ"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"ตรวจสอบแอปที่ใช้งานอยู่"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"เข้าถึงกล้องจากอุปกรณ์นี้ไม่ได้"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index e443676..2360951 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Three way na pagtawag"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Pagtanggi sa mga hindi ninanais na nakakaistorbong tawag"</string>
     <string name="CndMmi" msgid="185136449405618437">"Pagpapadala ng numero sa pagtawag"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Huwag istorbohin"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Pinaghihigpitan ang mga default ng Caller ID. Susunod na tawag: Pinaghihigpitan"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Nade-default sa pinaghihigpitan ang Caller ID. Susunod na tawag: hindi pinaghihigpitan"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Naka-default sa hindi pinaghihigpitan ang Caller ID. Susunod na tawag: Pinaghihigpitan"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"i-access ang iyong kalendaryo"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"magpadala at tumingin ng mga mensaheng SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Mga file at dokumento"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"i-access ang mga file at dokumento sa iyong device"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musika at iba pang audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"mag-access ng mga audio file sa iyong device"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Mga larawan at video"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Payagan ang app na tukuyin ang relatibong posisyon sa pagitan ng mga kalapit na Ultra-Wideband device"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"makipag-ugnayan sa mga kalapit na Wi‑Fi device"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Nagbibigay-daan sa app na i-advertise, kumonekta sa, at tukuyin ang nauugnay na posisyon ng mga kalapit na Wi‑Fi device"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Nagbibigay-daan sa app na i-advertise ang, kumonekta sa, at tukuyin ang nauugnay na posisyon ng mga kalapit na Wi‑Fi device"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Impormasyon sa Gustong NFC na Serbisyo sa Pagbabayad"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Pinapayagan ang app na makakuha ng impormasyon sa gustong nfc na serbisyo sa pagbabayad tulad ng mga nakarehistrong application ID at destinasyon ng ruta."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kontrolin ang Near Field Communication"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ilagay ang iyong lock ng screen para magpatuloy"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Hindi buo ang natukoy na fingerprint"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Hindi maproseso ang fingerprint. Pakisubukan ulit."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Linisin ang sensor para sa fingerprint at subukan ulit"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Linisin ang sensor at subukan ulit"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Pumindot nang madiin sa sensor"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Masyadong mabagal ang paggalaw ng daliri. Pakisubukan ulit."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Sumubok ng ibang fingerprint"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Masyadong maliwanag"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Bahagyang baguhin ang posisyon ng iyong daliri sa bawat pagkakataon"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Hindi nakilala ang fingerprint"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Pumindot nang madiin sa sensor"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Na-authenticate ang fingerprint"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Na-authenticate ang mukha"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Na-authenticate ang mukha, pakipindot ang kumpirmahin"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Binibigyang-daan ang may-ari na sumailalim sa interface sa nangungunang antas ng isang serbisyo ng pagmemensahe ng carrier. Hindi kailanman dapat kailanganin para sa mga normal na app."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"mag-bind sa mga serbisyo ng carrier"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Pinapayagan ang may-ari na mag-bind sa mga serbisyo ng carrier. Hindi dapat kailanganin sa mga normal na app."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"i-access ang Huwag Istorbohin"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Nagbibigay-daan sa app na basahin at isulat ang configuration ng Huwag Istorbohin."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"simulan ang paggamit sa pahintulot sa pagtingin"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Binibigyang-daan ang may hawak na simulan ang paggamit ng pahintulot para sa isang app. Hindi dapat kailanganin kailanman para sa mga normal na app."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"simulan ang mga desisyon sa pahintulot na tumingin"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Laktawan"</string>
     <string name="no_matches" msgid="6472699895759164599">"Walang mga tugma"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Maghanap sa pahina"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# tugma}one{# sa {total}}other{# sa {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Tapos na"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Binubura ang nakabahaging storage…"</string>
     <string name="share" msgid="4157615043345227321">"Ibahagi"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (susunod na alarm)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Hanggang sa i-off mo"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Hanggang sa i-off mo ang Huwag Istorbohin"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"I-collapse"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Huwag istorbohin"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Walang serbisyo"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Weeknight"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Weekend"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Magva-vibrate ang mga tawag at notification"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Mamu-mute ang mga tawag at notification"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Mga pagbabago sa system"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Huwag Istorbohin"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Bago: Itinatago ng Huwag Istorbohin ang mga notification"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"I-tap para matuto pa at baguhin."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Binago ang Huwag Istorbohin"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"I-tap para tingnan kung ano ang naka-block."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"System"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Mga Setting"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"I-off"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Matuto pa"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Pinalitan ng Mga pinahusay na notification ang Mga Adaptive na Notification ng Android sa Android 12. Nagpapakita ng mga iminumungkahing pagkilos at sagot ang feature na ito, at isinasaayos nito ang iyong mga notification.\n\nMaa-access ng Mga pinahusay na notification ang content ng notification, kabilang ang personal na impormasyon gaya ng mga pangalan ng contact at mensahe. Magagawa rin ng feature na ito na i-dismiss o tugunan ang mga notification, gaya ng pagsagot sa mga tawag sa telepono, at kontrolin ang Huwag Istorbohin."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notification ng impormasyon ng Routine Mode"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Maaaring maubos ang baterya bago ang karaniwang pag-charge"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Na-activate ang Pantipid ng Baterya para patagalin ang buhay ng baterya"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Gumagana ang <xliff:g id="APP">%1$s</xliff:g> sa background at gumagamit ito ng baterya I-tap para suriin."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Napakatagal nang gumagana ang <xliff:g id="APP">%1$s</xliff:g> sa background. I-tap para suriin."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Tingnan ang mga aktibong app"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Hindi ma-access ang camera mula sa device na ito"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 9546de4..d1a568d 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Üç yönlü arama"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"İstenmeyen sinir bozucu aramaların reddi"</string>
     <string name="CndMmi" msgid="185136449405618437">"Aranan numara iletimi"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Rahatsız etmeyin"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Arayan kimliği varsayılanları kısıtlanmıştır. Sonraki çağrı: Kısıtlanmış"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Arayan kimliği varsayılanları kısıtlanmıştır. Sonraki çağrı: Kısıtlanmamış"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Arayan kimliği varsayılanları kısıtlanmamıştır. Sonraki çağrı: Kısıtlanmış"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"takviminize erişme"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS mesajları gönderme ve görüntüleme"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Dosyalar ve dokümanlar"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"cihazınızdaki dosyalara ve dokümanlara erişme"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Müzik ve diğer sesler"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"cihazınızdaki ses dosyalarına erişme"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Fotoğraflar ve videolar"</string>
@@ -547,7 +546,7 @@
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Uygulamaya, yakındaki Bluetooth cihazlara reklam yayınlama izni verir"</string>
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu bul"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Uygulamanın, yakındaki Ultra Geniş Bant cihazların birbirine göre konumunu belirlemesine izin verin"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"yakındaki kablosuz cihazlarla etkileşim kurma"</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"yakındaki kablosuz cihazlarla etkileşim kur"</string>
     <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Uygulamanın reklam sunmasına, bağlanmasına ve yakındaki kablosuz cihazların göreli konumunu belirlemesine izin verir"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Tercih Edilen NFC Ödeme Hizmeti Bilgileri"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Uygulamaya, kayıtlı yardımlar ve rota hedefi gibi tercih edilen NFC ödeme hizmeti bilgilerini alma izni verir."</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Devam etmek için ekran kilidinizi girin"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Parmak izinin tümü algılanamadı"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Parmak izi işlenemedi. Lütfen tekrar deneyin."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Parmak izi sensörünü temizleyip tekrar deneyin"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensörü temizleyip tekrar deneyin"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sensöre sıkıca bastırın"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Parmak hareketi çok yavaştı. Lütfen tekrar deneyin."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Başka bir parmak izi deneyin"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Çok parlak"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Her defasında parmağınızın konumunu biraz değiştirin"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Parmak izi tanınmadı"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sensöre sıkıca bastırın"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Parmak izi kimlik doğrulaması yapıldı"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Yüz kimliği doğrulandı"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yüz kimliği doğrulandı, lütfen onayla\'ya basın"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"İzin sahibinin, operatör mesajlaşma hizmetinin üst düzey arayüzüne bağlanmasına olanak verir. Normal uygulamalarda hiçbir zaman gerekmez."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"operatör hizmetlerine bağlan"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"İzin sahibinin, operatör hizmetlerine bağlanmasına olanak tanır. Normal uygulamalarda hiçbir zaman gerekmez."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"Rahatsız Etmeyin özelliğine erişme"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Uygulamaya, Rahatsız Etmeyin yapılandırmasını okuma ve yazma izni verir."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"izin kullanımı görüntülemeye başlama"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"İzin sahibinin bir uygulama için izin kullanımı başlatmasına olanak tanır. Normal uygulamalar için hiçbir zaman kullanılmamalıdır."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"izin kararlarını görüntülemeye başlama"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Atla"</string>
     <string name="no_matches" msgid="6472699895759164599">"Eşleşme yok"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Sayfada bul"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# eşleştirme}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Bitti"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Paylaşılan depolama alanı siliniyor…"</string>
     <string name="share" msgid="4157615043345227321">"Paylaş"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Şu saate kadar: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (sonraki alarma) saatine kadar"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Siz kapatana kadar"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Rahatsız Etmeyin ayarını kapatana kadar"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Daralt"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Rahatsız etmeyin"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Bildirim istenmeyen zaman"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Hafta içi gece"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Hafta sonu"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Aramalar ve bildirimler titreşim yapacak"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Aramalar ve bildirimlerin sesi kapalı olacak"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Sistem değişiklikleri"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Rahatsız Etmeyin"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Yeni: Rahatsız Etmeyin ayarı bildirimleri gizliyor"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Daha fazla bilgi edinmek ve değiştirmek için dokunun."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Rahatsız Etmeyin modu değişti"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nelerin engellendiğini kontrol etmek için dokunun."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sistem"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Ayarlar"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Tamam"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Kapat"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Daha fazla bilgi"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Gelişmiş bildirimler, Android 12\'de Android Uyarlamalı Bildirimler\'in yerini aldı. Bu özellik, önerilen işlem ve yanıtları gösterir ve bildirimlerinizi organize eder.\n\nGelişmiş bildirimler, kişiler ve mesajlar gibi kişisel bilgiler dahil olmak üzere tüm bildirim içeriklerine erişebilir. Bu özellik ayrıca bildirimleri kapatabilir veya telefon aramalarını yanıtlamak ve Rahatsız Etmeyin modunu kontrol etmek gibi işlemlerle bildirimlere yanıt verebilir."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Rutin Modu bilgi bildirimi"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pil normal şarjdan önce bitebilir"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Pilin ömrünü uzatmak için Pil Tasarrufu etkinleştirildi"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> arka planda çalışıyor ve pil tüketiyor. İncelemek için dokunun."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzun süredir arka planda çalışıyor. İncelemek için dokunun."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Etkin uygulamaları kontrol edin"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Bu cihazdan kameraya erişilemiyor"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index cc763ad..955651a 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -72,6 +72,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Конференція"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Відхил. небажаних надокучливих дзвінків"</string>
     <string name="CndMmi" msgid="185136449405618437">"Отрим. номера абонента"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Не турбувати"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Ідентиф. абонента за умовч. обмеж. Наст. дзвінок: обмеж."</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Ідентиф. абонента за умовч. обмеж. Наст. дзвінок: не обмеж."</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Ідентиф. абонента за умовч. не обмеж. Наст. дзвінок: обмеж."</string>
@@ -306,10 +307,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"отримувати доступ до календаря"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"надсилати та переглядати SMS-повідомлення"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Файли та документи"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"отримувати доступ до файлів і документів на вашому пристрої"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Музика й інше аудіо"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"отримувати доступ до аудіофайлів на вашому пристрої"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Фото й відео"</string>
@@ -590,12 +589,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Щоб продовжити, введіть дані для розблокування екрана"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Виявлено частковий відбиток пальця"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Не вдалось обробити відбиток пальця. Повторіть спробу."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Очистьте сканер відбитків пальців і повторіть спробу"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Очистьте сканер і повторіть спробу"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Міцно притисніть палець до сканера"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Ви провели пальцем надто повільно. Повторіть спробу."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Спробуйте інший відбиток пальця"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Надто яскраво"</string>
@@ -603,10 +599,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Щоразу трохи змінюйте положення пальця"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Відбиток пальця не розпізнано"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Міцно притисніть палець до сканера"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Відбиток пальця автентифіковано"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Обличчя автентифіковано"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Обличчя автентифіковано. Натисніть \"Підтвердити\""</string>
@@ -745,6 +739,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Додаток зможе підключатися до інтерфейсу верхнього рівня служби надсилання повідомлень через оператора. Звичайні додатки ніколи не використовують цей дозвіл."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"підключатися до служб оператора"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Власник може підключатися до служб оператора. Звичайні додатки ніколи не використовують цей дозвіл."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"доступ до режиму \"Не турбувати\""</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Додаток зможе переглядати та змінювати конфігурацію режиму \"Не турбувати\"."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"перегляньте дані про використання дозволів"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Власник зможе використовувати дозволи для цього додатка. Цей дозвіл не потрібен для звичайних додатків."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"почати перегляд рішень щодо дозволів"</string>
@@ -1510,8 +1506,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Пропустити"</string>
     <string name="no_matches" msgid="6472699895759164599">"Немає збігів"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Знайти на сторінці"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# збіг}one{# з {total}}few{# з {total}}many{# з {total}}other{# з {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Готово"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Стирання спільної пам’яті…"</string>
     <string name="share" msgid="4157615043345227321">"Надіслати"</string>
@@ -1876,8 +1871,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (наступний будильник)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Доки ви не вимкнете"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Доки ввімкнено режим \"Не турбувати\""</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Згорнути"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Не турбувати"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Простій"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Увечері в будні"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"На вихідних"</string>
@@ -2042,7 +2039,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Вібросигнал для викликів і сповіщень увімкнено"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Звуковий сигнал для викликів і сповіщень вимкнено"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Системні зміни"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Не турбувати"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Нове: у режимі \"Не турбувати\" сповіщення ховаються"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Торкніться, щоб дізнатися більше та змінити."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Налаштування режиму \"Не турбувати\" змінено"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Торкніться, щоб перевірити, що заблоковано."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Система"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Налаштування"</string>
@@ -2059,6 +2059,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Вимкнути"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Докладніше"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 адаптивні сповіщення замінено на покращені. Ця функція допомагає впорядковувати сповіщення й показує в них пропоновані дії та відповіді.\n\nПокращені сповіщення надають доступ до вмісту сповіщень, зокрема до такої особистої інформації, як повідомлення й імена контактів. Ця функція може автоматично закривати сповіщення чи реагувати на них, наприклад відповідати на телефонні дзвінки або керувати режимом \"Не турбувати\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Сповіщення про послідовнсть дій"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Акумулятор може розрядитися раніше ніж зазвичай"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Режим енергозбереження активовано для збільшення часу роботи акумулятора"</string>
@@ -2265,6 +2266,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"Додаток <xliff:g id="APP">%1$s</xliff:g> працює у фоновому режимі та розряджає акумулятор. Натисніть, щоб переглянути."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"Додаток <xliff:g id="APP">%1$s</xliff:g> довго працює у фоновому режимі. Натисніть, щоб переглянути."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Перевірте активні додатки"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Не вдається отримати доступ до камери через цей пристрій"</string>
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 8636572..90e20b3 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"تین طرفہ کالنگ"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"غیر مطلوبہ پریشان کن کالز کو مسترد کرنا"</string>
     <string name="CndMmi" msgid="185136449405618437">"کالنگ نمبر ڈیلیوری"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"ڈسٹرب نہ کریں"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"‏کالر ID کی ڈیفالٹ ترتیب محدود کردہ ہے۔ اگلی کال: محدود کردہ"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"‏کالر ID کی ڈیفالٹ ترتیب محدود کردہ ہے۔ اگلی کال: غیر محدود کردہ"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"‏کالر ID کی ڈیفالٹ ترتیب غیر محدود کردہ ہے۔ اگلی کال: محدود کردہ"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"حامل کو ایک کیریئر پیغام رسانی سروس کے اعلی سطحی انٹرفیس کا پابند ہونے کی اجازت دیتی ہے۔ عام ایپس کیلئے کبھی بھی اس کی ضرورت نہیں ہونی چاہیے۔"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"کیریئر سروسز کا پابند کریں"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"حامل کو کیریئر سروسز کا پابند کرنے کی اجازت دیتا ہے۔ معمول کی ایپس کیلئے کبھی درکار نہیں ہونا چاہیے۔"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"ڈسٹرب نہ کریں تک رسائی حاصل کریں"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"ایپ کو ڈسٹرب نہ کریں کنفیگریشن لکھنے اور پڑھنے کے قابل کرتا ہے۔"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"اجازت کی استعمال کا ملاحظہ شروع کریں"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"حامل کو ایپ کی اجازت کے استعمال کو شروع کرنے کی اجازت دیتا ہے۔ عام ایپس کے لیے کبھی بھی درکار نہیں ہونا چاہیے۔"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"اجازت کے فیصلوں کو دیکھنا شروع کریں"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"نظر انداز کریں"</string>
     <string name="no_matches" msgid="6472699895759164599">"کوئی مماثلتیں نہیں ہیں"</string>
     <string name="find_on_page" msgid="5400537367077438198">"صفحہ پر تلاش کریں"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# مماثلت}other{{total} میں سے #}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"ہو گیا"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"اشتراک کردہ اسٹوریج کو صاف کیا جا رہا ہے…"</string>
     <string name="share" msgid="4157615043345227321">"اشتراک کریں"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک (اگلا الارم)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"یہاں تک کہ آپ آف کر دیں"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"جب تک آپ ڈسڑب نہ کریں کو آف نہیں کر دیتے"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"سکیڑیں"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"ڈسٹرب نہ کریں"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"ڈاؤن ٹائم"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"ویک نائٹ"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"ویک اینڈ"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"کالز اور اطلاعات پر وائبریٹ کرے گا"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"کالز اور اطلاعات کی آواز خاموش کر دی جائے گی"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"سسٹم کی تبدیلیاں"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"ڈسٹرب نہ کریں"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"نئی: \'ڈسٹرب نہ کریں\' اطلاعات کو چھپا رہی ہے"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"مزید جاننے اور تبدیل کرنے کیلئے تھپتھپائیں۔"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"\'ڈسٹرب نہ کریں\' تبدیل ہو گيا ہے"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"مسدود کی گئی چیزوں کو چیک کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"سسٹم"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"ترتیبات"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"ٹھیک ہے"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"آف کریں"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"مزید جانیں"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"‏Android 12 میں بہتر کردہ اطلاعات کو Android اڈاپٹیو کی اطلاعات سے تبدیل کیا گیا۔ یہ خصوصیت تجویز کردہ کارروائیاں اور جوابات دکھاتی ہے اور آپ کی اطلاعات کا نظم کرتی ہے۔\n\nبہتر کردہ اطلاعات رابطوں کے نام اور پیغامات جیسی ذاتی معلومات سمیت اطلاعات کے مواد تک رسائی حاصل کر سکتی ہیں۔ یہ خصوصیت اطلاعات کو برخاست کر سکتی ہے یا ان کا جواب بھی دے سکتی ہے جیسے فون کالز کا جواب دینا اور ڈسٹرب نہ کریں کو کنٹرول کرنا۔"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"روٹین موڈ معلومات کی اطلاع"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"معمول چارج سے پہلے بیٹری ختم ہو سکتی ہے"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"بیٹری لائف کو بڑھانے کے لیے بیٹری سیور کو فعال کر دیا گیا ہے"</string>
@@ -2253,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیغام کا ترجمہ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> سے<xliff:g id="TO_LANGUAGE">%2$s</xliff:g> میں کیا گیا۔"</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"پس منظر کی سرگرمی"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"پس منظر کی سرگرمی"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> پس منظر میں چل رہی ہے اور بیٹری ختم ہو رہی ہے۔ جائزے کے لیے تھپتھپائیں۔"</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"‫<xliff:g id="APP">%1$s</xliff:g> پس منظر میں چل رہی ہے اور بیٹری ختم ہو رہی ہے۔ جائزے کے لیے تھپتھپائیں۔"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> کافی وقت سے پس منظر میں چل رہی ہے۔ جائزے کے لیے تھپتھپائیں۔"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"فعال ایپس چیک کریں"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"اس آلہ سے کیمرا تک رسائی حاصل نہیں کر سکتے"</string>
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index e09f634..31c6ec4 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Uch urinishda qo‘ng‘iroq qilish"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Yoqmaydigan asabga teguvchi qo‘ng‘iroqlarni rad qilish"</string>
     <string name="CndMmi" msgid="185136449405618437">"Yetkazib berish raqami terilmoqda"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Halaqit bermang"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Qo‘ng‘iroq qiluvchi ma’lumotlari cheklangan. Keyingi qo‘ng‘iroq: cheklangan"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Qo‘ng‘iroq qiluvchi ma’lumotlari cheklangan. Keyingi qo‘ng‘iroq: cheklanmagan"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Qo‘ng‘iroq qiluvchi ma’lumotlari cheklanmagan. Keyingi qo‘ng‘iroq: cheklangan"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"taqvimingizga kirish"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"SMS xabarlarni yuborish va ko‘rish"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Fayl va hujjatlar"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"qurilmangizdagi fayl va hujjatlarga kirish"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Musiqa va boshqa audio"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"qurilmangizdagi audio fayllarga kirish"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Suratlar va videolar"</string>
@@ -539,16 +538,16 @@
     <string name="permdesc_bluetooth" product="tablet" msgid="3053222571491402635">"Ilovaga planshetdagi Bluetooth‘ning sozlamasini ko‘rishga va bog‘langan qurilmalarga ulanish va ulardan ulanish so‘rovlarini qabul qulishga imkon beradi."</string>
     <string name="permdesc_bluetooth" product="tv" msgid="8851534496561034998">"Ilovaga Android TV qurilmangizdagi Bluetooth sozlamasini koʻrishga va bogʻlangan qurilmalarga ulanish va ulardan ulanish talablarni qabul qilishga imkon beradi."</string>
     <string name="permdesc_bluetooth" product="default" msgid="2779606714091276746">"Ilovaga telefondagi Bluetooth‘ning sozlamasini ko‘rishga va bog‘langan qurilmalarga ulanish va ulardan ulanish so‘rovlarini qabul qulishga imkon beradi."</string>
-    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"Bluetooth qurilmalarini topish va juftlashish"</string>
+    <string name="permlab_bluetooth_scan" msgid="5402587142833124594">"Bluetooth qurilmalarni topish va juftlash"</string>
     <string name="permdesc_bluetooth_scan" product="default" msgid="6540723536925289276">"Ilovaga yaqin-atrofdagi Bluetooth qurilmalarini topish va juftlashish uchun ruxsat beradi"</string>
-    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"juftlangan Bluetooth qurilmalariga ulanish"</string>
+    <string name="permlab_bluetooth_connect" msgid="6657463246355003528">"Juftlangan Bluetooth qurilmalarga ulanish"</string>
     <string name="permdesc_bluetooth_connect" product="default" msgid="4546016548795544617">"Ilovaga juftlangan Bluetooth qurilmalariga ulanish uchun ruxsat beradi"</string>
-    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"atrofdagi Bluetooth qurilmalariga reklama berish"</string>
+    <string name="permlab_bluetooth_advertise" msgid="2781147747928853177">"Atrofdagi Bluetooth qurilmalarga reklama yuborish"</string>
     <string name="permdesc_bluetooth_advertise" product="default" msgid="6085174451034210183">"Ilovaga yaqin-atrofdagi Bluetooth qurilmalariga reklama yuborish imkonini beradi"</string>
-    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlash"</string>
+    <string name="permlab_uwb_ranging" msgid="8141915781475770665">"Atrofdagi ultra-keng aloqa kanalli qurilmalarning nisbiy joylashuvini aniqlash"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Ilovaga yaqin atrofdagi ultra keng polosali qurilmalarining nisbiy joylashishini aniqlashga ruxsat beradi"</string>
-    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Yaqin-atrofdagi Wi-Fi qurilmalari bilan ishlash"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ilovaga yaqin-atrofdagi Wi-Fi qurilmalarga reklama yuborish, ulanish va taxminiy joylashuvini aniqlash imkonini beradi."</string>
+    <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"Yaqin-atrofdagi Wi-Fi qurilmalar bilan ishlash"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Ilovaga yaqin-atrofdagi Wi-Fi qurilmalarga reklama yuborish, ulanish va ularning taxminiy joylashuvini aniqlash imkonini beradi."</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Asosiy NFC toʻlov xizmati haqidagi axborot"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Bu ilovaga asosiy NFC toʻlov xizmati haqidagi axborotni olish imkonini beradi (masalan, qayd qilingan AID identifikatorlari va marshrutning yakuniy manzili)."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"NFC modulini boshqarish"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Ekran qulfini kiritish bilan davom eting"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Barmoq izi qismi aniqlandi"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Barmoq izi aniqlanmadi. Qaytadan urining."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Barmoq izi skanerini tozalang va qayta urining"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Sensorni tozalang va qayta urining"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Sensorni mahkam bosing"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Barmoq juda sekin harakatlandi. Qayta urinib ko‘ring."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Boshqa barmoq izi bilan urining"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Juda yorqin"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Barmoqni har safar biroz surib joylang"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Barmoq izi aniqlanmadi"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Sensorni mahkam bosing"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Barmoq izi tekshirildi"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Yuzingiz aniqlandi"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Yuzingiz aniqlandi, tasdiqlash uchun bosing"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Egasiga aloqa operatorining xabar almashinuv xizmatining yuqori darajali interfeysiga bog‘lanish uchun ruxsat beradi. Oddiy ilovalar uchun hech qachon kerak bo‘lmaydi."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"aloqa operatori xizmatlariga ulanish"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Aloqa operatori xizmatlariga ulanish imkonini beradi. Oddiy ilovalar uchun talab qilinmaydi."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"“Bezovta qilinmasin” rejimidan foydalanish"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"“Bezovta qilinmasin” rejimi sozlamalarini ko‘rish va o‘zgartirish."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"foydalaniladigan ruxsatlar axborotini ochish"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ilova foydalanadigan ruxsatlar axborotini ishga tushirishga ruxsat beradi. Oddiy ilovalar uchun talab qilinmaydi."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"ilova ruxsatlarini tekshirishni boshlash"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Tashlab o‘tish"</string>
     <string name="no_matches" msgid="6472699895759164599">"Topilmadi"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Sahifadan topish"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# ta moslik}other{# / {total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Tayyor"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Umumiy xotira tozalanmoqda…"</string>
     <string name="share" msgid="4157615043345227321">"Yuborish"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> gacha"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> gacha (keyingi signal)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Rejimdan chiqilgunicha"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Bezovta qilinmasin rejimidan chiqilgunicha"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Yig‘ish"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Bezovta qilinmasin"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Nofaol vaqt"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Ish kunlari kechqurun"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Dam olish kunlari"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Chaqiruvlar va bildirishnomalar tebranadi"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Chaqiruvlar va bildirishnomalar ovozsiz qilinadi"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Tizimga oid o‘zgarishlar"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Bezovta qilinmasin"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Yangi: Bezovta qilinmasin rejimi bildirishnomalarni berkitmoqda"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Batafsil axborot olish va o‘zgartirish uchun bosing."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Bezovta qilinmasin rejimi sozlamalari o‘zgartirildi"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nimalar bloklanganini tekshirish uchun bosing"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Tizim"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Sozlamalar"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Faolsizlantirish"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Batafsil"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Android 12 tizimida moslashuvchan bildirishnomalar oʻrniga yangicha bildirishnomalar chiqadi. Bu funksiya amallar va javoblarni taklif qiladi va bildirishnomalaringizni boshqaradi.\n\nYangicha bildirishnomalar barcha bildirishnomalar kontentini, jumladan kontakt nomlari va xabarlar kabi shaxsiy bildirishnomalarni ham oʻqiy oladi. Shuningdek, bu funksiya bildirishnomalarni yopishi yoki telefon chaqiruvlariga javob berishi va Bezovta qilinmasin rejimini boshqarishi mumkin."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Kun tartibi rejimi haqidagi bildirishnoma"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Batareya quvvati odatdagidan ertaroq tugashi mumkin"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Batareya quvvatini uzoqroq vaqtga yetkazish uchun quvvat tejash rejimi yoqildi"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Xabar <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> tilidan <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> tiliga tarjima qilindi."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Fondagi harakatlar"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Fondagi harakatlar"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> orqa fonda ishlamoqda va batareyani ortiqcha sarflamoqda. Tekshirish uchun bosing."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> fonda ishlamoqda va batareyani tugatmoqda. Tekshirish uchun bosing."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> uzoq vaqt orqa fonda ishlamoqda. Tekshirish uchun bosing."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Faol ilovalarni tekshiring"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Kamera bu qurilma orqali ochilmadi"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 329f193..e53546f 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Gọi ba chiều"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Từ chối các cuộc gọi làm phiền không mong muốn"</string>
     <string name="CndMmi" msgid="185136449405618437">"Gửi số đang gọi"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Không làm phiền"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"Số gọi đến mặc định thành bị giới hạn. Cuộc gọi tiếp theo: Bị giới hạn"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"Số gọi đến mặc định thành bị giới hạn. Cuộc gọi tiếp theo. Không bị giới hạn"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"Số gọi đến mặc định thành không bị giới hạn. Cuộc gọi tiếp theo. Bị giới hạn"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"truy cập lịch của bạn"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"Tin nhắn SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"gửi và xem tin nhắn SMS"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"Tệp và tài liệu"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"truy cập vào các tệp và tài liệu trên thiết bị của bạn"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"Nhạc và âm thanh khác"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"truy cập vào tệp âm thanh trên thiết bị"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"Ảnh và video"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"Cho phép ứng dụng xác định khoảng cách tương đối giữa các thiết bị ở gần dùng Băng tần siêu rộng"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"tương tác với các thiết bị Wi‑Fi lân cận"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Cho phép ứng dụng thông báo, kết nối và xác định vị trí tương đối của các thiết bị Wi‑Fi lân cận"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"Cho phép ứng dụng này thông báo, kết nối và xác định vị trí tương đối của các thiết bị Wi‑Fi lân cận"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"Thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần (NFC) được ưu tiên"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"Cho phép ứng dụng nhận thông tin về dịch vụ thanh toán qua công nghệ giao tiếp tầm gần mà bạn ưu tiên, chẳng hạn như các hình thức hỗ trợ đã đăng ký và điểm đến trong hành trình."</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"kiểm soát Liên lạc trường gần"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Hãy nhập phương thức khóa màn hình của bạn để tiếp tục"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"Phát hiện thấy một phần vân tay"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"Không thể xử lý vân tay. Vui lòng thử lại."</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Hãy vệ sinh cảm biến vân tay rồi thử lại"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"Vệ sinh cảm biến rồi thử lại"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"Nhấn chắc trên cảm biến"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"Di chuyển ngón tay quá chậm. Vui lòng thử lại."</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"Hãy thử một vân tay khác"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"Quá sáng"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"Mỗi lần, hãy thay đổi vị trí ngón tay một chút"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"Không nhận dạng được vân tay"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"Nhấn chắc trên cảm biến"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"Đã xác thực vân tay"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"Đã xác thực khuôn mặt"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"Đã xác thực khuôn mặt, vui lòng nhấn để xác nhận"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của dịch vụ nhắn tin của nhà cung cấp dịch vụ. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"liên kết với dịch vụ của nhà cung cấp"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Cho phép chủ sở hữu liên kết với các dịch vụ của nhà cung cấp. Không bao giờ cần cho các ứng dụng thông thường."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"quyền truy cập chế độ Không làm phiền"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Cho phép ứng dụng đọc và ghi cấu hình Không làm phiền."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"cấp quyền xem"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Cho phép chủ sở hữu cấp quyền cho một ứng dụng. Các ứng dụng thông thường sẽ không bao giờ cần quyền này."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"bắt đầu xem các quyết định cấp quyền"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Bỏ qua"</string>
     <string name="no_matches" msgid="6472699895759164599">"Không có kết quả nào phù hợp"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Tìm kiếm trên trang"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# kết quả trùng khớp}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Xong"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Đang xóa bộ nhớ dùng chung…"</string>
     <string name="share" msgid="4157615043345227321">"Chia sẻ"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Cho đến <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Cho tới <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (cảnh báo tiếp theo)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Cho đến khi bạn tắt"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Cho đến khi bạn tắt Đừng làm phiền"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Thu gọn"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Không làm phiền"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Thời gian ngừng hoạt động"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Đêm trong tuần"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Cuối tuần"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Cuộc gọi và thông báo sẽ rung"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Cuộc gọi và thông báo sẽ tắt tiếng"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Thay đổi hệ thống"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Không làm phiền"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Mới: Chế độ Không làm phiền sẽ ẩn thông báo"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Nhấn để tìm hiểu thêm và thay đổi."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Cài đặt Không làm phiền đã thay đổi"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Nhấn để xem những thông báo bị chặn."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Hệ thống"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Cài đặt"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Tắt"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Tìm hiểu thêm"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Thông báo nâng cao đã thay thế Thông báo thích ứng trên Android trong Android 12. Tính năng này hiển thị những thao tác và câu trả lời đề xuất, đồng thời sắp xếp các thông báo của bạn.\n\nThông báo nâng cao có thể đọc mọi nội dung thông báo, bao gồm cả thông tin cá nhân như tên liên hệ và tin nhắn. Tính năng này cũng có thể đóng hoặc phản hồi các thông báo, chẳng hạn như trả lời cuộc gọi điện thoại, đồng thời có thể kiểm soát chế độ Không làm phiền."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Thông báo cung cấp thông tin về chế độ sạc thông thường"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Pin có thể hết trước khi sạc bình thường"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Trình tiết kiệm pin được kích hoạt để kéo dài thời lượng pin"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Đã dịch thông báo từ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> sang <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"Hoạt động trong nền"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"Hoạt động trong nền"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> đang chạy trong nền và làm tiêu hao pin. Nhấn để xem lại."</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> đang chạy trong nền và làm tiêu hao pin. Nhấn để xem."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> đang chạy trong nền trong thời gian dài. Nhấn để xem lại."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Xem các ứng dụng đang hoạt động"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Không sử dụng được máy ảnh trên thiết bị này"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index dbfef83..5986cb7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"三方通话"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"拒绝不想接听的骚扰电话"</string>
     <string name="CndMmi" msgid="185136449405618437">"主叫号码传送"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"勿扰"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"默认不显示本机号码,在下一次通话中也不显示"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"默认不显示本机号码,但在下一次通话中显示"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"默认显示本机号码,但在下一次通话中不显示"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"访问您的日历"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"短信"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"发送和查看短信"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"文件和文档"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"访问您设备上的文件和文档"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音乐和其他音频"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"访问您设备上的音频文件"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"照片和视频"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"输入您的屏幕锁定凭据才能继续"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"检测到局部指纹"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"无法处理指纹,请重试。"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"请清洁指纹传感器,然后重试"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"请清洁传感器,然后重试"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"请用力按住传感器"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"手指移动太慢,请重试。"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"请试试其他指纹"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"光线太亮"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"请在每次放手指时略微更改手指的位置"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"未能识别指纹"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"请用力按住传感器"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"已验证指纹"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"面孔已验证"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已验证,请按确认按钮"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"允许应用绑定到运营商消息传递服务的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"绑定到运营商服务"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"允许应用绑定到运营商服务。普通应用绝不需要此权限。"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"“勿扰”模式使用权限"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"允许此应用读取和写入“勿扰”模式配置。"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"授权使用“查看权限”"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"允许该应用开始查看应用的权限使用情况(普通应用绝不需要此权限)。"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"开始查看权限决策"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"跳过"</string>
     <string name="no_matches" msgid="6472699895759164599">"无匹配项"</string>
     <string name="find_on_page" msgid="5400537367077438198">"在网页上查找"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# 条匹配结果}other{#/{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"完成"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"正在清空共享的存储空间…"</string>
     <string name="share" msgid="4157615043345227321">"分享"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"直到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>(闹钟下次响铃时)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"直到您将其关闭"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"直到您关闭“勿扰”模式"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"收起"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"勿扰"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"休息时间"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"周一至周五夜间"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"周末"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"有来电和通知时会振动"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"有来电和通知时会静音"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"系统变更"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"勿扰"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"新功能:勿扰模式目前可隐藏通知"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"点按即可了解详情以及进行更改。"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"“勿扰”设置有变更"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"点按即可查看屏蔽内容。"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"系统"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"设置"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"确定"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"关闭"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"了解详情"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"在 Android 12 中,增强型通知功能取代了 Android 自适应通知功能。增强型通知功能可以显示建议的操作和回复,并可将通知整理得井井有条。\n\n增强型通知功能可以读取通知内容,包括联系人名称和消息等个人信息。该功能还可以关闭通知或对通知做出回应,例如接听来电以及控制勿扰模式。"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式信息通知"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"电池电量可能会在您平时的充电时间之前耗尽"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已启用省电模式以延长电池续航时间"</string>
@@ -2260,9 +2261,8 @@
     <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"已将消息内容从<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>翻译成<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>。"</string>
     <string name="notification_channel_abusive_bg_apps" msgid="6092140213264920355">"后台活动"</string>
     <string name="notification_title_abusive_bg_apps" msgid="344582472797982073">"后台活动"</string>
-    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> 正在后台运行,并且消耗了大量电池电量。点按即可查看。"</string>
-    <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> 已在后台运行较长时间。点按即可查看。"</string>
+    <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"“<xliff:g id="APP">%1$s</xliff:g>”正在后台运行,并且消耗了大量电池电量。点按即可查看。"</string>
+    <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"“<xliff:g id="APP">%1$s</xliff:g>”已在后台运行较长时间。点按即可查看。"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的应用"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"无法使用此设备的摄像头"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c4fa7a0..59572ee 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"三方通話"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"拒接不想接聽的騷擾電話"</string>
     <string name="CndMmi" msgid="185136449405618437">"顯示發話號碼"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"請勿騷擾"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"預設不顯示來電號碼,下一通電話也不顯示。"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"預設不顯示來電號碼,但下一通電話則顯示。"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"預設顯示來電號碼,但下一通電話不顯示。"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取您的日曆"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"短訊"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送和查看短訊"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"檔案和文件"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"存取裝置上的檔案和文件"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音樂和其他音訊"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"存取裝置上的音訊檔案"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"相片和影片"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定解鎖憑證"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"只偵測到部分指紋"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋。請再試一次。"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"請清潔指紋感應器,然後再試一次"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"請清潔感應器,然後再試一次"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"請用力按住感應器"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"手指移動太慢,請重試。"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃瞄時請稍微變更手指的位置"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"無法辨識指紋"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"請用力按住感應器"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"驗證咗指紋"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"面孔已經驗證"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"面孔已經驗證,請㩒一下 [確認]"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"允許應用程式繫結至流動網絡供應商短訊服務的頂層介面 (不建議一般應用程式使用)。"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"繫結至流動網絡供應商服務"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"允許擁有者繫結至流動網絡供應商服務 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"存取「請勿騷擾」"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"允許應用程式讀取和寫入「請勿騷擾」設定。"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"開始查看權限使用情況"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"允許應用程式開始查看應用程式的權限使用情況 (一般應用程式並不需要)。"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"開始檢視權限決定"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"略過"</string>
     <string name="no_matches" msgid="6472699895759164599">"沒有相符的結果"</string>
     <string name="find_on_page" msgid="5400537367077438198">"在頁面中尋找"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# 個相符的項目}other{第 # 個 (共 {total} 個相符的項目)}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"完成"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"正在清除共用儲存空間資料…"</string>
     <string name="share" msgid="4157615043345227321">"分享"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"完成時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"直至<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (下一次響鬧)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"直至您關閉為止"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"直至您關閉「請勿騷擾」功能"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"收合"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"請勿騷擾"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"休息時間"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"平日夜間"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"有來電和通知時會震動"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"有來電和通知時會靜音"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"系統變更"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"請勿騷擾"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"新通知:「請勿騷擾」模式目前隱藏通知"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"輕按即可瞭解詳情和作出變更。"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"請勿騷擾已變更"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"輕按即可查看封鎖內容。"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"系統"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"設定"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"確定"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"關閉"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"瞭解詳情"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"加強版通知在 Android 12 取代了 Android 自動調整通知。此功能會顯示建議的操作和回覆,更可為您整理通知。\n\n加強版通知功能可存取您的通知內容 (包括聯絡人姓名和訊息等個人資料),亦可以關閉或回應通知,例如接聽來電和控制「請勿騷擾」功能。"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"「日常安排模式」資料通知"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電量可能會在日常充電前耗盡"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"「省電模式」已啟用,以便延長電池壽命"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"<xliff:g id="APP">%1$s</xliff:g> 正在背景執行並大量耗電。輕按即可查看。"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"<xliff:g id="APP">%1$s</xliff:g> 已長時間在背景執行。輕按即可查看。"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"無法存取此裝置的相機"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 843c7517..e0e03dc 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"三方通話"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"拒接不想接聽的騷擾電話"</string>
     <string name="CndMmi" msgid="185136449405618437">"顯示發話號碼"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"勿干擾"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"預設不顯示本機號碼,下一通電話也不顯示。"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"預設不顯示本機號碼,但下一通電話顯示。"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"預設顯示本機號碼,但下一通電話不顯示。"</string>
@@ -304,10 +305,8 @@
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"存取你的日曆"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"簡訊"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"傳送及查看簡訊"</string>
-    <!-- no translation found for permgrouplab_storage (9173334109512154196) -->
-    <skip />
-    <!-- no translation found for permgroupdesc_storage (8352226729501080525) -->
-    <skip />
+    <string name="permgrouplab_storage" msgid="9173334109512154196">"檔案與文件"</string>
+    <string name="permgroupdesc_storage" msgid="8352226729501080525">"存取裝置上的檔案與文件"</string>
     <string name="permgrouplab_readMediaAural" msgid="5885210465560755316">"音樂和其他音訊"</string>
     <string name="permgroupdesc_readMediaAural" msgid="1170143315714662822">"存取裝置上的音訊檔案"</string>
     <string name="permgrouplab_readMediaVisual" msgid="9137695801926624061">"相片和影片"</string>
@@ -548,7 +547,7 @@
     <string name="permlab_uwb_ranging" msgid="8141915781475770665">"判斷附近超寬頻裝置間的相對位置"</string>
     <string name="permdesc_uwb_ranging" msgid="2519723069604307055">"允許應用程式判斷附近超寬頻裝置間的相對位置"</string>
     <string name="permlab_nearby_wifi_devices" msgid="392774237063608500">"與鄰近的 Wi-Fi 裝置互動"</string>
-    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式向鄰近的 Wi-Fi 裝置廣播、與這些裝置連線,並能判斷這些裝置的相對位置"</string>
+    <string name="permdesc_nearby_wifi_devices" msgid="3054307728646332906">"允許應用程式顯示鄰近的 Wi-Fi 裝置的資料、與其連線並判斷相對位置"</string>
     <string name="permlab_preferredPaymentInfo" msgid="5274423844767445054">"首選 NFC 付費服務資訊"</string>
     <string name="permdesc_preferredPaymentInfo" msgid="8583552469807294967">"允許應用程式取得首選 NFC 付費服務資訊,例如已註冊的輔助工具和路線目的地。"</string>
     <string name="permlab_nfc" msgid="1904455246837674977">"控制近距離無線通訊"</string>
@@ -588,12 +587,9 @@
     <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"如要繼續操作,請輸入螢幕鎖定憑證"</string>
     <string name="fingerprint_acquired_partial" msgid="694598777291084823">"僅偵測到局部指紋"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2545149524031515411">"無法處理指紋,請再試一次。"</string>
-    <!-- no translation found for fingerprint_acquired_imager_dirty (1770676120848224250) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_imager_dirty_alt (9169582140486372897) -->
-    <skip />
-    <!-- no translation found for fingerprint_acquired_too_fast (1628459767349116104) -->
-    <skip />
+    <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"請清潔指紋感應器,然後再試一次"</string>
+    <string name="fingerprint_acquired_imager_dirty_alt" msgid="9169582140486372897">"清潔感應器,然後再試一次"</string>
+    <string name="fingerprint_acquired_too_fast" msgid="1628459767349116104">"請確實按住感應器"</string>
     <string name="fingerprint_acquired_too_slow" msgid="6683510291554497580">"手指移動速度過慢,請再試一次。"</string>
     <string name="fingerprint_acquired_already_enrolled" msgid="2285166003936206785">"改用其他指紋"</string>
     <string name="fingerprint_acquired_too_bright" msgid="3863560181670915607">"太亮"</string>
@@ -601,10 +597,8 @@
     <string name="fingerprint_acquired_immobile" msgid="1621891895241888048">"每次掃描時請稍微變更手指的位置"</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for fingerprint_error_not_match (4599441812893438961) -->
-    <skip />
-    <!-- no translation found for fingerprint_udfps_error_not_match (4709197752023550709) -->
-    <skip />
+    <string name="fingerprint_error_not_match" msgid="4599441812893438961">"指紋辨識失敗"</string>
+    <string name="fingerprint_udfps_error_not_match" msgid="4709197752023550709">"請確實按住感應器"</string>
     <string name="fingerprint_authenticated" msgid="2024862866860283100">"指紋驗證成功"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="8867889115112348167">"臉孔驗證成功"</string>
     <string name="face_authenticated_confirmation_required" msgid="6872632732508013755">"臉孔驗證成功,請按下 [確認] 按鈕"</string>
@@ -743,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"允許應用程式與電信業者簡訊服務的頂層介面繫結 (一般應用程式並不需要)。"</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"與電信業者服務繫結"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"允許應用程式繫結至電信業者服務 (一般應用程式並不需要)。"</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"存取「零打擾」模式"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"允許應用程式讀取及寫入「零打擾」設定。"</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"啟動檢視權限用途"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"允許應用程式開始使用其他應用程式 (一般應用程式並不需要)。"</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"開始檢視權限決定"</string>
@@ -1508,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"略過"</string>
     <string name="no_matches" msgid="6472699895759164599">"沒有相符項目"</string>
     <string name="find_on_page" msgid="5400537367077438198">"在頁面中尋找"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# 個相符的項目}other{第 # 個,共 {total} 個相符的項目}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"完成"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"正在清除共用儲存空間…"</string>
     <string name="share" msgid="4157615043345227321">"分享"</string>
@@ -1874,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"結束時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> 為止 (下一個鬧鐘)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"直到你關閉為止"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"直到你關閉「零打擾」模式"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"收合"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"零打擾"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"停機"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"週間晚上"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"週末"</string>
@@ -2040,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"有來電和通知時會震動"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"有來電和通知時會靜音"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"系統變更"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"零打擾"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"新功能:「零打擾」模式現在可以隱藏通知"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"輕觸即可瞭解詳情及進行變更。"</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"「零打擾」設定已變更"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"輕觸即可查看遭封鎖的項目。"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"系統"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"設定"</string>
@@ -2057,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"確定"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"關閉"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"瞭解詳情"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"在 Android 12 中,加強型通知功能已取代 Android 自動調整通知。這項功能可以顯示建議的操作和回覆內容,也可以幫你整理通知訊息。\n\n加強型通知功能可存取通知內容,包括聯絡人名稱和訊息內文等個人資訊。此外,這項功能還能關閉或回覆通知,例如接聽來電及控管「零打擾」功能。"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"日常安排模式資訊通知"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"電池電力可能會在你平常的充電時間前耗盡"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"已啟用省電模式以延長電池續航力"</string>
@@ -2263,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"「<xliff:g id="APP">%1$s</xliff:g>」正在背景運作且耗用大量電力。輕觸即可查看。"</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"「<xliff:g id="APP">%1$s</xliff:g>」已長時間在背景運作。輕觸即可查看。"</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"查看使用中的應用程式"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"無法存取這部裝置的相機"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 41cd8b0..336e78e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -70,6 +70,7 @@
     <string name="ThreeWCMmi" msgid="2436550866139999411">"Ukushayela kwezindlela ezintathu"</string>
     <string name="RuacMmi" msgid="1876047385848991110">"Ukwenqabela amakholi acikayo"</string>
     <string name="CndMmi" msgid="185136449405618437">"Ishayela ukuthumela inombolo"</string>
+    <string name="DndMmi" msgid="8797375819689129800">"Ungaphazamisi"</string>
     <string name="CLIRDefaultOnNextCallOn" msgid="4511621022859867988">"I-ID Yomshayeli ishintshela kokungavinjelwe. Ucingo olulandelayo: Luvinjelwe"</string>
     <string name="CLIRDefaultOnNextCallOff" msgid="5036749051007098105">"i-ID yomshayeli ishintshela kokuvinjiwe. Ucingo olulandelayo: Aluvinjelwe"</string>
     <string name="CLIRDefaultOffNextCallOn" msgid="1022781126694885017">"I-ID Yomshayeli ishintshela kokungavinjelwe. Ucingo olulandelayo: Luvinjelwe"</string>
@@ -736,6 +737,8 @@
     <string name="permdesc_bindCarrierMessagingService" msgid="6316457028173478345">"Ivumela isibambi ukuhlanganisa isixhumanisi sokubona esiphezulu sesevisi yomlayezo yenkampani yenethiwekhi. Akufanele idingeke kuzinhlelo zokusebenza ezivamile."</string>
     <string name="permlab_bindCarrierServices" msgid="2395596978626237474">"bophezela kumasevisi wenkampani yenethiwekhi"</string>
     <string name="permdesc_bindCarrierServices" msgid="9185614481967262900">"Ivumela umbambi ukuthi abophezele kumasevisi wenkampani yenethiwekhi. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+    <string name="permlab_access_notification_policy" msgid="5524112842876975537">"finyelela kokuthi Ungaphazamisi"</string>
+    <string name="permdesc_access_notification_policy" msgid="8538374112403845013">"Ivumela izinhlelo zokusebenza ukufunda nokubhala ukulungiswa kokuthi Ungaphazamisi."</string>
     <string name="permlab_startViewPermissionUsage" msgid="1504564328641112341">"qala ukusetshenziswa kokubuka imvume"</string>
     <string name="permdesc_startViewPermissionUsage" msgid="2820325605959586538">"Ivumela umphathi ukuthi aqale ukusetshenziswa kwemvume kohlelo lokusebenza. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_startReviewPermissionDecisions" msgid="8690578688476599284">"qala ukubuka izinqumo zemvume"</string>
@@ -1501,8 +1504,7 @@
     <string name="skip_button_label" msgid="3566599811326688389">"Yeqa"</string>
     <string name="no_matches" msgid="6472699895759164599">"Akukho okufanayo"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Thola ekhasini"</string>
-    <!-- no translation found for matches_found (2296462299979507689) -->
-    <skip />
+    <string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{okufanayo okungu-#}one{okungu-# kokungu-{total}}other{okungu-# kokungu-{total}}}"</string>
     <string name="action_mode_done" msgid="2536182504764803222">"Kwenziwe"</string>
     <string name="progress_erasing" msgid="6891435992721028004">"Isusa isitoreji esabiwe…"</string>
     <string name="share" msgid="4157615043345227321">"Yabelana"</string>
@@ -1867,8 +1869,10 @@
     <string name="zen_mode_until" msgid="2250286190237669079">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
     <string name="zen_mode_alarm" msgid="7046911727540499275">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (i-alamu elandelayo)"</string>
     <string name="zen_mode_forever" msgid="740585666364912448">"Uze uvale isikrini"</string>
+    <string name="zen_mode_forever_dnd" msgid="3423201955704180067">"Uze uvale ungaphazamisi"</string>
     <string name="zen_mode_rule_name_combination" msgid="7174598364351313725">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
     <string name="toolbar_collapse_description" msgid="8009920446193610996">"Goqa"</string>
+    <string name="zen_mode_feature_name" msgid="3785547207263754500">"Ungaphazamisi"</string>
     <string name="zen_mode_downtime_feature_name" msgid="5886005761431427128">"Isikhathi sokuphumula"</string>
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"Ubusuku beviki"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"Ngempelasonto"</string>
@@ -2033,7 +2037,10 @@
     <string name="volume_dialog_ringer_guidance_vibrate" msgid="2055927873175228519">"Amakholi nezaziso zizodlidliza"</string>
     <string name="volume_dialog_ringer_guidance_silent" msgid="1011246774949993783">"Amakholi nezaziso zizothuliswa"</string>
     <string name="notification_channel_system_changes" msgid="2462010596920209678">"Ushintsho lwesistimu"</string>
+    <string name="notification_channel_do_not_disturb" msgid="7832584281883687653">"Ungaphazamisi"</string>
+    <string name="zen_upgrade_notification_visd_title" msgid="2001148984371968620">"Ukungaphazamisi kufihle izaziso"</string>
     <string name="zen_upgrade_notification_visd_content" msgid="3683314609114134946">"Thepha ukuze ufunde kabanzi futhi ushintshe."</string>
+    <string name="zen_upgrade_notification_title" msgid="8198167698095298717">"Ukungaphazamisi kushintshile"</string>
     <string name="zen_upgrade_notification_content" msgid="5228458567180124005">"Thepha ukuze uhlole ukuthi yini evinjelwe."</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Isistimu"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Izilungiselelo"</string>
@@ -2050,6 +2057,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"KULUNGILE"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Vala"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Funda kabanzi"</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Izaziso ezithuthukisiwe zithathe isikhundla sezaziso eziguqukayo ze-Android ku-Android 12. Lesi sakhi sikhombisa izenzo eziphakanyisiwe nezimpendulo, futhi sihlela izaziso zakho.\n\nIzaziso ezithuthukisiwe zingafinyelela kokuqukethwe kwesaziso, kuhlanganise nemininingwane yomuntu efana namagama woxhumana nabo nemilayezo. Lesi sakhi singacashisa noma siphendule izaziso, njengokuphendula amakholi wefoni, nokulawula okuthi Ungaphazamisi."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Isaziso solwazi lwe-Routine Mode"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Ibhethri lingaphela ngaphambi kokushaja okuvamile"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Isilondolozi sebhethri siyasebenza ngaphandle kwempilo yebhethri"</string>
@@ -2256,6 +2264,5 @@
     <string name="notification_content_abusive_bg_apps" msgid="5572096708044958249">"I-<xliff:g id="APP">%1$s</xliff:g> isebenza ngemuva futhi idla ibhethri. Thepha ukuze ubuyekeze."</string>
     <string name="notification_content_long_running_fgs" msgid="8878031652441570178">"I-<xliff:g id="APP">%1$s</xliff:g> isebenza ngemuva isikhathi eside. Thepha ukuze ubuyekeze."</string>
     <string name="notification_action_check_bg_apps" msgid="4758877443365362532">"Hlola ama-app asebenzayo"</string>
-    <!-- no translation found for vdm_camera_access_denied (6345652513729130490) -->
-    <skip />
+    <string name="vdm_camera_access_denied" msgid="6345652513729130490">"Ayikwazi ukufinyelela ikhamera kule divayisi"</string>
 </resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 8f2d6c3..dff7751 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -185,6 +185,12 @@
         <item>@string/app_info</item>
     </string-array>
 
+    <!-- Certificate digests for trusted apps that will be allowed to obtain the knownSigner Wi-Fi
+         permissions. The digest should be computed over the DER encoding of the trusted certificate
+         using the SHA-256 digest algorithm. -->
+    <string-array name="wifi_known_signers">
+    </string-array>
+
     <!-- Device-specific array of SIM slot indexes which are are embedded eUICCs.
          e.g. If a device has two physical slots with indexes 0, 1, and slot 1 is an
          eUICC, then the value of this array should be:
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 689d37c..da5f899 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3932,12 +3932,12 @@
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INPUT_METHOD_EDITOR}. -->
             <flag name="flagInputMethodEditor" value="0x0008000" />
         </attr>
-        <!-- Component name of an activity that allows the user to modify
-             the settings for this service. This setting cannot be changed at runtime. -->
+        <!-- Fully qualified class name of an activity that allows the user to modify the settings
+             for this service. This setting cannot be changed at runtime. -->
         <attr name="settingsActivity" />
-        <!-- Component name of {@link android.service.quicksettings.TileService} is associated
-             with this accessibility service for one to one mapping. It is used by system settings
-             to remind users this accessibility service has a
+        <!-- Fully qualified class name of {@link android.service.quicksettings.TileService} is
+             associated with this accessibility service for one to one mapping. It is used by system
+             settings to remind users this accessibility service has a
              {@link android.service.quicksettings.TileService}. -->
         <attr name="tileService" format="string" />
         <!-- Attribute whether the accessibility service wants to be able to retrieve the
@@ -4026,12 +4026,12 @@
         <!-- Html description of the target of accessibility shortcut usage, availability, or
              limitations (e.g. isn't supported by all apps). -->
         <attr name="htmlDescription" format="reference"/>
-        <!-- Component name of an activity that allows the user to modify the settings for this
-             target of accessibility shortcut. -->
+        <!-- Fully qualified class name of an activity that allows the user to modify the settings
+             for this target of accessibility shortcut. -->
         <attr name="settingsActivity" />
-        <!-- Component name of {@link android.service.quicksettings.TileService} is associated
-             with this accessibility shortcut target for one to one mapping. It is used by system
-             settings to remind users this accessibility service has a
+        <!-- Fully qualified class name of {@link android.service.quicksettings.TileService} is
+             associated with this accessibility shortcut target for one to one mapping. It is used
+             by system settings to remind users this accessibility service has a
              {@link android.service.quicksettings.TileService}. -->
         <attr name="tileService" format="string" />
         <!-- Detailed intro of the target of accessibility shortcut purpose or behavior. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0e0c6a3..579ef51 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2035,7 +2035,7 @@
              {@link android.app.Activity#onBackPressed Activity.onBackPressed()}
              and related event will be forwarded to the Activities and View, otherwise those events
              will be replaced by a call to
-             {@link android.view.OnBackInvokedCallback#onBackInvoked
+             {@link android.window.OnBackInvokedCallback#onBackInvoked
              OnBackInvokedCallback.onBackInvoked()} on the focused window. -->
         <attr name="enableOnBackInvokedCallback" format="boolean"/>
     </declare-styleable>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 05894d5..0bdf716 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1207,13 +1207,13 @@
 
     <!-- Display low battery warning when battery level dips to this value.
          Also, the battery stats are flushed to disk when we hit this level.  -->
-    <integer name="config_criticalBatteryWarningLevel">5</integer>
+    <integer name="config_criticalBatteryWarningLevel">10</integer>
 
     <!-- Shutdown if the battery temperature exceeds (this value * 0.1) Celsius. -->
     <integer name="config_shutdownBatteryTemperature">680</integer>
 
     <!-- Display low battery warning when battery level dips to this value -->
-    <integer name="config_lowBatteryWarningLevel">15</integer>
+    <integer name="config_lowBatteryWarningLevel">20</integer>
 
     <!-- The default suggested battery % at which we enable battery saver automatically.  -->
     <integer name="config_lowBatteryAutoTriggerDefaultLevel">15</integer>
@@ -2113,7 +2113,7 @@
         TODO(b/189347385) make this a @SystemAPI -->
     <string name="config_systemTelevisionRemoteService" translatable="false">@string/config_tvRemoteServicePackage</string>
     <!-- The name of the package that will hold the device management role -->
-    <string name="config_deviceManager" translatable="false"></string>
+    <string name="config_devicePolicyManagement" translatable="false"></string>
     <!-- The name of the package that will hold the app protection service role. -->
     <string name="config_systemAppProtectionService" translatable="false"></string>
     <!-- The name of the package that will hold the system calendar sync manager role. -->
@@ -2122,7 +2122,7 @@
     <string name="config_defaultAutomotiveNavigation" translatable="false"></string>
 
     <!-- The name of the package that will handle updating the device management role. -->
-    <string name="config_deviceManagerUpdater" translatable="false"></string>
+    <string name="config_devicePolicyManagementUpdater" translatable="false"></string>
 
     <!-- The name of the package that will be allowed to change its components' label/icon. -->
     <string name="config_overrideComponentUiPackage" translatable="false">com.android.stk</string>
@@ -2723,7 +2723,7 @@
     <string name="config_bandwidthEstimateSource">bandwidth_estimator</string>
 
     <!-- Whether force to enable telephony new data stack or not -->
-    <bool name="config_force_enable_telephony_new_data_stack">false</bool>
+    <bool name="config_force_enable_telephony_new_data_stack">true</bool>
 
     <!-- Whether WiFi display is supported by this device.
          There are many prerequisites for this feature to work correctly.
@@ -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>
@@ -3704,26 +3709,6 @@
          snapped to any position between the first target and the last target. -->
     <bool name="config_dockedStackDividerFreeSnapMode">false</bool>
 
-    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
-         These values are in DPs and will be converted to pixel sizes internally. -->
-    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">16x16</string>
-
-    <!-- The percentage of the screen width to use for the default width or height of
-         picture-in-picture windows. Regardless of the percent set here, calculated size will never
-         be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
-    <item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.23</item>
-
-    <!-- The default aspect ratio for picture-in-picture windows. -->
-    <item name="config_pictureInPictureDefaultAspectRatio" format="float" type="dimen">1.777778</item>
-
-    <!-- This is the limit for the max and min aspect ratio (1 / this value) at which the min size
-         will be used instead of an adaptive size based loosely on area. -->
-    <item name="config_pictureInPictureAspectRatioLimitForMinSize" format="float" type="dimen">1.777778</item>
-
-    <!-- The default gravity for the picture-in-picture window.
-         Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
-    <integer name="config_defaultPictureInPictureGravity">0x55</integer>
-
     <!-- The minimum aspect ratio (width/height) that is supported for picture-in-picture.  Any
          ratio smaller than this is considered too tall and thin to be usable. Currently, this
          is the inverse of the max landscape aspect ratio (1:2.39), but this is an extremely
@@ -4150,9 +4135,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.
@@ -5212,6 +5197,10 @@
          when TextClassifier has not been initialized. -->
     <integer name="config_smartSelectionInitializingTimeoutMillis">500</integer>
 
+    <!-- The delay in milliseconds before focused Views set themselves as preferred to keep clear.
+         Set to -1 if Views should not set themselves as preferred to keep clear. -->
+    <integer name="config_preferKeepClearForFocusDelayMillis">-1</integer>
+
     <!-- Indicates that default fitness tracker app needs to request sensor and location permissions. -->
     <bool name="config_trackerAppNeedsPermissions">false</bool>
 
@@ -5278,9 +5267,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 adf8f8e..1b9f7fe 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -717,16 +717,6 @@
     <!-- The default minimal size of a resizable task, in both dimensions. -->
     <dimen name="default_minimal_size_resizable_task">220dp</dimen>
 
-    <!-- The default minimal size of a PiP task, in both dimensions. -->
-    <dimen name="default_minimal_size_pip_resizable_task">108dp</dimen>
-
-    <!--
-      The overridable minimal size of a PiP task, in both dimensions.
-      Different from default_minimal_size_pip_resizable_task, this is to limit the dimension
-      when the pinned stack size is overridden by app via minWidth/minHeight.
-    -->
-    <dimen name="overridable_minimal_size_pip_resizable_task">48dp</dimen>
-
     <!-- Height of a task when in minimized mode from the top when launcher is resizable. -->
     <dimen name="task_height_of_minimized_mode">80dp</dimen>
 
@@ -881,7 +871,7 @@
     <integer name="autofill_max_visible_datasets">3</integer>
 
     <!-- Size of an icon in the Autolfill fill dialog -->
-    <dimen name="autofill_dialog_icon_size">56dp</dimen>
+    <dimen name="autofill_dialog_icon_size">24dp</dimen>
 
     <!-- Size of a slice shortcut view -->
     <dimen name="slice_shortcut_size">56dp</dimen>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index bccd2b6..082acbe 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -62,8 +62,9 @@
   <!-- View id for the action of text editor inside of an extracted text
         {@link InputMethodService#onCreateExtractTextView IME extract view}. -->
   <item type="id" name="inputExtractAction" />
-  <!-- View id for the accessories of text editor inside of an extracted text
-        {@link InputMethodService#onCreateExtractTextView IME extract view}. -->
+  <!-- View id for the accessories (such as the extracted input action button) of text editor
+       inside of an extracted text {@link InputMethodService#onCreateExtractTextView IME extract
+       view}. This layout must contain the {@link #inputExtractAction}. -->
   <item type="id" name="inputExtractAccessories" />
   <item type="id" name="selectAll" />
   <item type="id" name="cut" />
@@ -269,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 3beb4b2..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_deviceManager" />
-    <!-- @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..2dc17b8
--- /dev/null
+++ b/core/res/res/values/public-staging.xml
@@ -0,0 +1,228 @@
+<?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" />
+  </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 e41aa45..602e42d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -197,7 +197,7 @@
     <string name="ThreeWCMmi">Three way calling</string>
     <string name="RuacMmi">Rejection of undesired annoying calls</string>
     <string name="CndMmi">Calling number delivery</string>
-    <string name="DndMmi" translatable="false">Priority mode</string>
+    <string name="DndMmi">Do not disturb</string>
 
     <!-- Displayed to confirm to the user that caller ID will be restricted on the next call as usual. -->
     <string name="CLIRDefaultOnNextCallOn">Caller ID defaults to restricted. Next call: Restricted</string>
@@ -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>
@@ -2036,9 +2036,9 @@
     <string name="permdesc_bindCarrierServices">Allows the holder to bind to carrier services. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, for applications that wish to access notification policy. -->
-    <string name="permlab_access_notification_policy" translatable="false">access Priority mode</string>
+    <string name="permlab_access_notification_policy">access Do Not Disturb</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_access_notification_policy" translatable="false">Allows the app to read and write Priority mode configuration.</string>
+    <string name="permdesc_access_notification_policy">Allows the app to read and write Do Not Disturb configuration.</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_startViewPermissionUsage">start view permission usage</string>
@@ -4095,10 +4095,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>
@@ -4894,6 +4904,8 @@
     <string name="user_logging_out_message">Logging out <xliff:g id="name" example="Bob">%1$s</xliff:g>\u2026</string>
     <!-- Default name of the owner user [CHAR LIMIT=20] -->
     <string name="owner_name" msgid="3879126011135546571">Owner</string>
+    <!-- Default name of the guest user [CHAR LIMIT=35] -->
+    <string name="guest_name">Guest</string>
     <!-- Error message title [CHAR LIMIT=35] -->
     <string name="error_message_title">Error</string>
     <!-- Message informing user that the change was disallowed by an administrator. [CHAR LIMIT=none] -->
@@ -5302,7 +5314,7 @@
     <string name="zen_mode_forever">Until you turn off</string>
 
     <!-- Zen mode condition: no exit criteria, includes the name of the feature for emphasis. [CHAR LIMIT=NONE] -->
-    <string name="zen_mode_forever_dnd" translatable="false">Until you turn off Priority mode</string>
+    <string name="zen_mode_forever_dnd">Until you turn off Do Not Disturb</string>
 
     <!-- Zen mode active automatic rule name separator. [CHAR LIMIT=NONE] -->
     <string name="zen_mode_rule_name_combination"><xliff:g id="first" example="Weeknights">%1$s</xliff:g> / <xliff:g id="rest" example="Meetings">%2$s</xliff:g></string>
@@ -5311,7 +5323,7 @@
     <string name="toolbar_collapse_description">Collapse</string>
 
     <!-- Zen mode - feature name. [CHAR LIMIT=40] -->
-    <string name="zen_mode_feature_name" translatable="false">Priority mode</string>
+    <string name="zen_mode_feature_name">Do not disturb</string>
 
     <!-- Zen mode - downtime legacy feature name. [CHAR LIMIT=40] -->
     <string name="zen_mode_downtime_feature_name">Downtime</string>
@@ -5719,16 +5731,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>
@@ -5745,14 +5758,14 @@
 
     <!-- Title for the notification channel notifying user of settings system changes. [CHAR LIMIT=NONE] -->
     <string name="notification_channel_system_changes">System changes</string>
-    <!-- Title for the notification channel notifying user of priority mode system changes (i.e. Priority mode has changed). [CHAR LIMIT=NONE] -->
-    <string name="notification_channel_do_not_disturb" translatable="false">Priority mode</string>
-    <!-- Title of notification indicating Priority mode visual interruption settings have changed when upgrading to P -->
-    <string name="zen_upgrade_notification_visd_title" translatable="false">New: Priority mode is hiding notifications</string>
+    <!-- Title for the notification channel notifying user of do not disturb system changes (i.e. Do Not Disturb has changed). [CHAR LIMIT=NONE] -->
+    <string name="notification_channel_do_not_disturb">Do Not Disturb</string>
+    <!-- Title of notification indicating do not disturb visual interruption settings have changed when upgrading to P -->
+    <string name="zen_upgrade_notification_visd_title">New: Do Not Disturb is hiding notifications</string>
     <!-- Content of notification indicating users can tap on the notification to go to dnd behavior settings -->
     <string name="zen_upgrade_notification_visd_content">Tap to learn more and change.</string>
-    <!-- Title of notification indicating priority mode settings have changed when upgrading to P -->
-    <string name="zen_upgrade_notification_title" translatable="false">Priority mode has changed</string>
+    <!-- Title of notification indicating do not disturb settings have changed when upgrading to P -->
+    <string name="zen_upgrade_notification_title">Do Not Disturb has changed</string>
     <!-- Content of notification indicating users can tap on the notification to go to dnd behavior settings -->
     <string name="zen_upgrade_notification_content">Tap to check what\'s blocked.</string>
 
@@ -5793,7 +5806,7 @@
     <!-- Label of notification action button to learn more about the enhanced notifications [CHAR LIMIT=20] -->
     <string name="nas_upgrade_notification_learn_more_action">Learn more</string>
     <!-- Content of notification learn more dialog about the enhanced notifications [CHAR LIMIT=NONE] -->
-    <string name="nas_upgrade_notification_learn_more_content" translatable="false">Enhanced notifications replaced Android Adaptive Notifications in Android 12. This feature shows suggested actions and replies, and organizes your notifications.\n\nEnhanced notifications can access notification content, including personal information like contact names and messages. This feature can also dismiss or respond to notifications, such as answering phone calls, and control Priority mode.</string>
+    <string name="nas_upgrade_notification_learn_more_content">Enhanced notifications replaced Android Adaptive Notifications in Android 12. This feature shows suggested actions and replies, and organizes your notifications.\n\nEnhanced notifications can access notification content, including personal information like contact names and messages. This feature can also dismiss or respond to notifications, such as answering phone calls, and control Do Not Disturb.</string>
 
 
     <!-- Dynamic mode battery saver strings -->
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 558e3c3..8f3abd6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -408,11 +408,6 @@
   <java-symbol type="array" name="config_localPrivateDisplayPorts" />
   <java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" />
   <java-symbol type="bool" name="config_enableAppWidgetService" />
-  <java-symbol type="string" name="config_defaultPictureInPictureScreenEdgeInsets" />
-  <java-symbol type="dimen" name="config_pictureInPictureDefaultSizePercent" />
-  <java-symbol type="dimen" name="config_pictureInPictureDefaultAspectRatio" />
-  <java-symbol type="dimen" name="config_pictureInPictureAspectRatioLimitForMinSize" />
-  <java-symbol type="integer" name="config_defaultPictureInPictureGravity" />
   <java-symbol type="dimen" name="config_pictureInPictureMinAspectRatio" />
   <java-symbol type="dimen" name="config_pictureInPictureMaxAspectRatio" />
   <java-symbol type="integer" name="config_pictureInPictureMaxNumberOfActions" />
@@ -498,6 +493,7 @@
   <java-symbol type="string" name="config_bandwidthEstimateSource" />
   <java-symbol type="integer" name="config_smartSelectionInitializedTimeoutMillis" />
   <java-symbol type="integer" name="config_smartSelectionInitializingTimeoutMillis" />
+  <java-symbol type="integer" name="config_preferKeepClearForFocusDelayMillis" />
   <java-symbol type="bool" name="config_hibernationDeletesOatArtifactsEnabled"/>
   <java-symbol type="integer" name="config_defaultAnalogClockSecondsHandFps"/>
 
@@ -1112,6 +1108,7 @@
   <java-symbol type="string" name="media_route_status_not_available" />
   <java-symbol type="string" name="media_route_status_in_use" />
   <java-symbol type="string" name="owner_name" />
+  <java-symbol type="string" name="guest_name" />
   <java-symbol type="string" name="config_chooseAccountActivity" />
   <java-symbol type="string" name="config_chooseTypeAndAccountActivity" />
   <java-symbol type="string" name="config_chooserActivity" />
@@ -1295,6 +1292,8 @@
   <java-symbol type="array" name="vendor_required_apps_managed_user" />
   <java-symbol type="array" name="vendor_required_apps_managed_profile" />
   <java-symbol type="array" name="vendor_required_apps_managed_device" />
+  <java-symbol type="array" name="vendor_required_attestation_certificates" />
+  <java-symbol type="string" name="vendor_required_attestation_revocation_list_url" />
   <java-symbol type="array" name="vendor_disallowed_apps_managed_user" />
   <java-symbol type="array" name="vendor_disallowed_apps_managed_profile" />
   <java-symbol type="array" name="vendor_disallowed_apps_managed_device" />
@@ -2016,8 +2015,6 @@
   <java-symbol type="id" name="replace_message" />
   <java-symbol type="fraction" name="config_dimBehindFadeDuration" />
   <java-symbol type="dimen" name="default_minimal_size_resizable_task" />
-  <java-symbol type="dimen" name="default_minimal_size_pip_resizable_task" />
-  <java-symbol type="dimen" name="overridable_minimal_size_pip_resizable_task" />
   <java-symbol type="dimen" name="task_height_of_minimized_mode" />
   <java-symbol type="fraction" name="config_screenAutoBrightnessDozeScaleFactor" />
   <java-symbol type="bool" name="config_allowPriorityVibrationsInLowPowerMode" />
@@ -3680,7 +3677,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" />
@@ -3886,6 +3883,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" />
 
@@ -4731,7 +4732,7 @@
 
   <java-symbol type="bool" name="config_enableSafetyCenter" />
 
-  <java-symbol type="string" name="config_deviceManagerUpdater" />
+  <java-symbol type="string" name="config_devicePolicyManagementUpdater" />
 
   <java-symbol type="string" name="config_deviceSpecificDeviceStatePolicyProvider" />
 
@@ -4767,4 +4768,6 @@
   <java-symbol type="bool" name="config_bg_prompt_fgs_with_noti_to_bg_restricted" />
   <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" />
+
 </resources>
diff --git a/core/res/res/values/vendor_required_attestation_certificates.xml b/core/res/res/values/vendor_required_attestation_certificates.xml
new file mode 100644
index 0000000..ff7313e
--- /dev/null
+++ b/core/res/res/values/vendor_required_attestation_certificates.xml
@@ -0,0 +1,38 @@
+<?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.
+ */
+-->
+<resources>
+  <!-- The PEM-encoded certificates added here are used for verifying attestations.
+    The trustworthiness of the attestation depends on the root certificate of the chain.
+
+    Certificates that can be used can be retrieved from:
+    https://developer.android.com/training/articles/security-key-attestation#root_certificate.
+
+    If not already present in resource overlay, please add
+    vendor_required_attestation_certificates.xml (matching this file) in vendor overlay
+    with <item></item> of the PEM-encoded root certificates.
+  -->
+    <string-array translatable="false" name="vendor_required_attestation_certificates">
+    </string-array>
+
+    <!-- Url to mapping of revoked certificates' hex encoded serial numbers. Example format
+      can be found at:
+      https://developer.android.com/training/articles/security-key-attestation#certificate_status
+    -->
+    <string translatable="false" name="vendor_required_attestation_revocation_list_url"></string>
+</resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index a80424e..04857ec 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1494,6 +1494,16 @@
             android:permission="android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE"
             android:exported="true"/>
 
+        <service
+            android:name="com.android.internal.infra.ServiceConnectorTest$TestService"
+            android:process=":ServiceConnectorRemoteService"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.BIND_TEST_SERVICE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </service>
+
         <provider android:name="android.app.activity.LocalProvider"
                 android:authorities="com.android.frameworks.coretests.LocalProvider">
             <meta-data android:name="com.android.frameworks.coretests.string" android:value="foo" />
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/ITestServiceConnectorService.aidl
similarity index 68%
rename from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
rename to core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/ITestServiceConnectorService.aidl
index 2894780..09544b3 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/ITestServiceConnectorService.aidl
@@ -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,8 @@
  * limitations under the License.
  */
 
-package com.android.systemui.dagger;
+package com.android.frameworks.coretests.aidl;
 
-import dagger.Module;
-
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
+interface ITestServiceConnectorService {
+    void crashProcess();
 }
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/accessibilityservice/AccessibilityShortcutInfoTest.java b/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
index f605a00..eebc578 100644
--- a/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/AccessibilityShortcutInfoTest.java
@@ -129,7 +129,7 @@
     @Test
     public void testTileService() {
         assertThat("Tile service is not correct",
-                mShortcutInfo.getTileServiceClassName(), is(TILE_SERVICE_NAME));
+                mShortcutInfo.getTileServiceName(), is(TILE_SERVICE_NAME));
     }
 
 
diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
index 5338d04..ed2b101 100644
--- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
+++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
@@ -38,7 +38,7 @@
 public class PropertyInvalidatedCacheTests {
 
     // Configuration for creating caches
-    private static final int MODULE = PropertyInvalidatedCache.MODULE_TEST;
+    private static final String MODULE = PropertyInvalidatedCache.MODULE_TEST;
     private static final String API = "testApi";
 
     // This class is a proxy for binder calls.  It contains a counter that increments
@@ -214,13 +214,13 @@
             this(MODULE, API);
         }
 
-        TestCache(int module, String api) {
+        TestCache(String module, String api) {
             this(module, api, new TestQuery());
             setTestMode(true);
             testPropertyName();
         }
 
-        TestCache(int module, String api, TestQuery query) {
+        TestCache(String module, String api, TestQuery query) {
             super(4, module, api, api, query);
             mQuery = query;
             setTestMode(true);
@@ -364,15 +364,6 @@
         n1 = PropertyInvalidatedCache.createPropertyName(
             PropertyInvalidatedCache.MODULE_SYSTEM, "get_package_info");
         assertEquals(n1, "cache_key.system_server.get_package_info");
-        try {
-            n1 = PropertyInvalidatedCache.createPropertyName(
-                PropertyInvalidatedCache.MODULE_SYSTEM - 1, "get package_info");
-            // n1 is an invalid api name.
-            assertEquals(false, true);
-        } catch (IllegalArgumentException e) {
-            // An exception is expected here.
-        }
-
         n1 = PropertyInvalidatedCache.createPropertyName(
             PropertyInvalidatedCache.MODULE_BLUETOOTH, "getState");
         assertEquals(n1, "cache_key.bluetooth.get_state");
diff --git a/core/tests/coretests/src/android/companion/virtual/audio/VirtualAudioSessionTest.java b/core/tests/coretests/src/android/companion/virtual/audio/VirtualAudioSessionTest.java
index d66cb71..0e09d56 100644
--- a/core/tests/coretests/src/android/companion/virtual/audio/VirtualAudioSessionTest.java
+++ b/core/tests/coretests/src/android/companion/virtual/audio/VirtualAudioSessionTest.java
@@ -22,6 +22,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 import static org.testng.Assert.assertThrows;
 
@@ -168,7 +169,7 @@
 
         mVirtualAudioSession.onPlaybackConfigChanged(configs);
 
-        verify(mCallback).onPlaybackConfigChanged(configs);
+        verify(mCallback, timeout(2000)).onPlaybackConfigChanged(configs);
     }
 
     @Test
@@ -177,6 +178,6 @@
 
         mVirtualAudioSession.onRecordingConfigChanged(configs);
 
-        verify(mCallback).onRecordingConfigChanged(configs);
+        verify(mCallback, timeout(2000)).onRecordingConfigChanged(configs);
     }
 }
diff --git a/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
index e690da2..76e761a 100644
--- a/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
@@ -49,7 +49,7 @@
 abstract class AbstractCrossUserContentResolverTest {
     private static final int TIMEOUT_SERVICE_CONNECTION_SEC = 4;
     private static final int TIMEOUT_CONTENT_CHANGE_SEC = 4;
-    private static final int TIMEOUT_USER_UNLOCK_SEC = 4;
+    private static final int TIMEOUT_USER_UNLOCK_SEC = 10;
 
     private Context mContext;
     protected UserManager mUm;
diff --git a/core/tests/coretests/src/android/graphics/FontListParserTest.java b/core/tests/coretests/src/android/graphics/FontListParserTest.java
index 701e619..479e52a 100644
--- a/core/tests/coretests/src/android/graphics/FontListParserTest.java
+++ b/core/tests/coretests/src/android/graphics/FontListParserTest.java
@@ -355,6 +355,27 @@
         assertThat(config.getAliases()).isEmpty();
     }
 
+    @Test
+    public void ignore() throws Exception {
+        String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+                + "<familyset>"
+                + "  <family name='sans-serif'>"
+                + "    <font>test.ttf</font>"
+                + "  </family>"
+                + "  <family lang='und-Zsye' ignore='true'>"
+                + "    <font>emoji_legacy.ttf</font>"
+                + "  </family>"
+                + "  <family lang='und-Zsye'>"
+                + "    <font>emoji.ttf</font>"
+                + "  </family>"
+                + "</familyset>";
+        FontConfig config = readFamilies(xml, true /* include non-existing font files */);
+        List<FontConfig.FontFamily> families = config.getFontFamilies();
+        assertThat(families.size()).isEqualTo(2);  // legacy one should be ignored.
+        assertThat(families.get(1).getFontList().get(0).getFile().getName())
+                .isEqualTo("emoji.ttf");
+    }
+
     private FontConfig readFamilies(String xml, boolean allowNonExisting)
             throws IOException, XmlPullParserException {
         ByteArrayInputStream buffer = new ByteArrayInputStream(
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/ContentRecordingSessionTest.java b/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
new file mode 100644
index 0000000..df96a7d
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ContentRecordingSessionTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.view;
+
+import static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
+import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link ContentRecordingSession} class.
+ *
+ * Build/Install/Run:
+ * atest FrameworksCoreTests:ContentRecordingSessionTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class ContentRecordingSessionTest {
+    private static final int DISPLAY_ID = 1;
+    private static final IBinder WINDOW_TOKEN = new Binder("DisplayContentWindowToken");
+
+    @Test
+    public void testParcelable() {
+        ContentRecordingSession session = ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
+        session.setDisplayId(DISPLAY_ID);
+
+        Parcel parcel = Parcel.obtain();
+        session.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+        ContentRecordingSession session2 = ContentRecordingSession.CREATOR.createFromParcel(parcel);
+        assertThat(session).isEqualTo(session2);
+        parcel.recycle();
+    }
+
+    @Test
+    public void testTaskConstructor() {
+        ContentRecordingSession session = ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
+        assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_TASK);
+        assertThat(session.getTokenToRecord()).isEqualTo(WINDOW_TOKEN);
+    }
+
+    @Test
+    public void testDisplayConstructor() {
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
+                WINDOW_TOKEN);
+        assertThat(session.getContentToRecord()).isEqualTo(RECORD_CONTENT_DISPLAY);
+        assertThat(session.getTokenToRecord()).isEqualTo(WINDOW_TOKEN);
+    }
+
+    @Test
+    public void testIsValid() {
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
+                WINDOW_TOKEN);
+        assertThat(ContentRecordingSession.isValid(session)).isFalse();
+
+        session.setDisplayId(DEFAULT_DISPLAY);
+        assertThat(ContentRecordingSession.isValid(session)).isTrue();
+
+        session.setDisplayId(INVALID_DISPLAY);
+        assertThat(ContentRecordingSession.isValid(session)).isFalse();
+    }
+
+    @Test
+    public void testIsSameDisplay() {
+        assertThat(ContentRecordingSession.isSameDisplay(null, null)).isFalse();
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
+                WINDOW_TOKEN);
+        session.setDisplayId(DEFAULT_DISPLAY);
+        assertThat(ContentRecordingSession.isSameDisplay(session, null)).isFalse();
+
+        ContentRecordingSession incomingSession = ContentRecordingSession.createDisplaySession(
+                WINDOW_TOKEN);
+        incomingSession.setDisplayId(DEFAULT_DISPLAY);
+        assertThat(ContentRecordingSession.isSameDisplay(session, incomingSession)).isTrue();
+
+        incomingSession.setDisplayId(DEFAULT_DISPLAY + 1);
+        assertThat(ContentRecordingSession.isSameDisplay(session, incomingSession)).isFalse();
+    }
+
+    @Test
+    public void testEquals() {
+        ContentRecordingSession session = ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
+        session.setDisplayId(DISPLAY_ID);
+
+        ContentRecordingSession session2 = ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
+        session2.setDisplayId(DISPLAY_ID);
+        assertThat(session).isEqualTo(session2);
+    }
+}
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/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS
index 10f6f1f..a142e27 100644
--- a/core/tests/coretests/src/android/view/OWNERS
+++ b/core/tests/coretests/src/android/view/OWNERS
@@ -13,6 +13,7 @@
 per-file *View* = file:/services/core/java/com/android/server/wm/OWNERS
 per-file *Visibility* = file:/services/core/java/com/android/server/wm/OWNERS
 per-file *Window*  = file:/services/core/java/com/android/server/wm/OWNERS
+per-file *ContentRecord*  = file:/services/core/java/com/android/server/wm/OWNERS
 
 # Scroll Capture
 per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/tests/coretests/src/android/view/ViewInputConnectionTest.java b/core/tests/coretests/src/android/view/ViewInputConnectionTest.java
index d60c0c6..fda294c 100644
--- a/core/tests/coretests/src/android/view/ViewInputConnectionTest.java
+++ b/core/tests/coretests/src/android/view/ViewInputConnectionTest.java
@@ -549,6 +549,11 @@
         }
 
         @Override
+        public boolean requestCursorUpdates(int cursorUpdateMode, int cursorUpdateFilter) {
+            return false;
+        }
+
+        @Override
         public Handler getHandler() {
             return null;
         }
diff --git a/core/tests/coretests/src/android/window/BackNavigationTest.java b/core/tests/coretests/src/android/window/BackNavigationTest.java
index 91d8531..8fa48ef 100644
--- a/core/tests/coretests/src/android/window/BackNavigationTest.java
+++ b/core/tests/coretests/src/android/window/BackNavigationTest.java
@@ -27,7 +27,6 @@
 import android.app.Instrumentation;
 import android.os.RemoteException;
 import android.support.test.uiautomator.UiDevice;
-import android.view.OnBackInvokedCallback;
 
 import androidx.lifecycle.Lifecycle;
 import androidx.test.core.app.ActivityScenario;
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 1f2bcfb..f8c9944 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -27,8 +27,6 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.IWindow;
 import android.view.IWindowSession;
-import android.view.OnBackInvokedCallback;
-import android.view.OnBackInvokedDispatcher;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.platform.app.InstrumentationRegistry;
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 23ec3ea..cf78646 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -1307,55 +1307,6 @@
                 is(testBaseScore * SHORTCUT_TARGET_SCORE_BOOST));
     }
 
-    /**
-     * The case when AppPrediction service is not defined in PackageManager is already covered
-     * as a test parameter {@link ChooserActivityTest#packageManagers}. This test is checking the
-     * case when the prediction service is defined but the component is not available on the device.
-     */
-    @Test
-    public void testIsAppPredictionServiceAvailable() {
-        Intent sendIntent = createSendTextIntent();
-        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
-        when(
-                ChooserActivityOverrideData
-                        .getInstance()
-                        .resolverListController
-                        .getResolversForIntent(
-                                Mockito.anyBoolean(),
-                                Mockito.anyBoolean(),
-                                Mockito.isA(List.class)))
-                .thenReturn(resolvedComponentInfos);
-
-        final ChooserActivity activity =
-                mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
-        waitForIdle();
-        if (activity.getPackageManager().getAppPredictionServicePackageName() == null) {
-            assertThat(activity.isAppPredictionServiceAvailable(), is(false));
-        } else {
-            if (!shouldTestTogglingAppPredictionServiceAvailabilityAtRuntime()) {
-                return;
-            }
-
-            // This isn't a toggle per-se, but isAppPredictionServiceAvailable only works in
-            // system (see comment in the method).
-            assertThat(activity.isAppPredictionServiceAvailable(), is(true));
-
-            ChooserActivityOverrideData.getInstance().resources =
-                    Mockito.spy(activity.getResources());
-            when(
-                    ChooserActivityOverrideData
-                            .getInstance()
-                            .resources
-                            .getString(
-                                    getRuntimeResourceId(
-                                            "config_defaultAppPredictionService",
-                                            "string")))
-                    .thenReturn("ComponentNameThatDoesNotExist");
-
-            assertThat(activity.isAppPredictionServiceAvailable(), is(false));
-        }
-    }
-
     @Test
     public void testConvertToChooserTarget_predictionService() {
         Intent sendIntent = createSendTextIntent();
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/infra/ServiceConnectorTest.java b/core/tests/coretests/src/com/android/internal/infra/ServiceConnectorTest.java
new file mode 100644
index 0000000..725dcf3
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/infra/ServiceConnectorTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.infra;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.Nullable;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.UserHandle;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.frameworks.coretests.aidl.ITestServiceConnectorService;
+import com.android.internal.infra.ServiceConnectorTest.CapturingServiceLifecycleCallbacks.ServiceLifeCycleEvent;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Unit tests for {@link ServiceConnector}
+ */
+@RunWith(AndroidJUnit4.class)
+public class ServiceConnectorTest {
+
+    private final CapturingServiceLifecycleCallbacks mCapturingServiceLifecycleCallbacks =
+            new CapturingServiceLifecycleCallbacks();
+    private ServiceConnector<ITestServiceConnectorService> mServiceConnector;
+
+    @Before
+    public void setup() {
+        Context context = InstrumentationRegistry.getInstrumentation().getContext();
+        Intent testServiceConnectorServiceIntent = new Intent(TestService.ACTION_TEST_SERVICE);
+        testServiceConnectorServiceIntent.setPackage(context.getPackageName());
+
+        ServiceConnector.Impl<ITestServiceConnectorService> serviceConnector =
+                new ServiceConnector.Impl<ITestServiceConnectorService>(
+                        context,
+                        testServiceConnectorServiceIntent,
+                        /* bindingFlags= */ 0,
+                        UserHandle.myUserId(),
+                        ITestServiceConnectorService.Stub::asInterface);
+        serviceConnector.setServiceLifecycleCallbacks(mCapturingServiceLifecycleCallbacks);
+        mServiceConnector = serviceConnector;
+    }
+
+    @Test
+    public void connect_invokesLifecycleCallbacks() throws Exception {
+        connectAndWaitForDone();
+
+        assertThat(mCapturingServiceLifecycleCallbacks.getCapturedLifecycleEvents())
+                .containsExactly(ServiceLifeCycleEvent.ON_CONNECTED)
+                .inOrder();
+    }
+
+    @Test
+    public void connect_alreadyConnected_invokesLifecycleCallbacksOnce() throws Exception {
+        connectAndWaitForDone();
+        connectAndWaitForDone();
+
+        assertThat(mCapturingServiceLifecycleCallbacks.getCapturedLifecycleEvents())
+                .containsExactly(ServiceLifeCycleEvent.ON_CONNECTED)
+                .inOrder();
+    }
+
+    @Test
+    public void unbind_neverConnected_noLifecycleCallbacks() {
+        unbindAndWaitForDone();
+
+        assertThat(mCapturingServiceLifecycleCallbacks.getCapturedLifecycleEvents())
+                .isEmpty();
+    }
+
+    @Test
+    public void unbind_whileConnected_invokesLifecycleCallbacks() throws Exception {
+        connectAndWaitForDone();
+        unbindAndWaitForDone();
+
+        assertThat(mCapturingServiceLifecycleCallbacks.getCapturedLifecycleEvents())
+                .containsExactly(
+                        ServiceLifeCycleEvent.ON_CONNECTED,
+                        ServiceLifeCycleEvent.ON_DISCONNECTED)
+                .inOrder();
+    }
+
+
+    @Test
+    public void unbind_alreadyUnbound_invokesLifecycleCallbacks() throws Exception {
+        connectAndWaitForDone();
+        unbindAndWaitForDone();
+        unbindAndWaitForDone();
+
+        assertThat(mCapturingServiceLifecycleCallbacks.getCapturedLifecycleEvents())
+                .containsExactly(
+                        ServiceLifeCycleEvent.ON_CONNECTED,
+                        ServiceLifeCycleEvent.ON_DISCONNECTED)
+                .inOrder();
+    }
+
+    @Test
+    public void binds_connectsAndUnbindsMultipleTimes_invokesLifecycleCallbacks() throws Exception {
+        connectAndWaitForDone();
+        unbindAndWaitForDone();
+        connectAndWaitForDone();
+        unbindAndWaitForDone();
+        connectAndWaitForDone();
+
+        assertThat(mCapturingServiceLifecycleCallbacks.getCapturedLifecycleEvents())
+                .containsExactly(
+                        ServiceLifeCycleEvent.ON_CONNECTED,
+                        ServiceLifeCycleEvent.ON_DISCONNECTED,
+                        ServiceLifeCycleEvent.ON_CONNECTED,
+                        ServiceLifeCycleEvent.ON_DISCONNECTED,
+                        ServiceLifeCycleEvent.ON_CONNECTED)
+                .inOrder();
+    }
+
+    @Test
+    public void processCrashes_whileConnected_invokesLifecycleCallbacks() throws Exception {
+        connectAndWaitForDone();
+        waitForDone(mServiceConnector.post(service -> service.crashProcess()));
+
+        assertThat(mCapturingServiceLifecycleCallbacks.getCapturedLifecycleEvents())
+                .containsExactly(
+                        ServiceLifeCycleEvent.ON_CONNECTED,
+                        ServiceLifeCycleEvent.ON_BINDER_DIED)
+                .inOrder();
+    }
+
+    private void connectAndWaitForDone() {
+        waitForDone(mServiceConnector.connect());
+    }
+
+    private void unbindAndWaitForDone() {
+        mServiceConnector.unbind();
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+
+    private static void waitForDone(AndroidFuture<?> androidFuture) {
+        if (androidFuture.isDone()) {
+            return;
+        }
+
+        try {
+            androidFuture.get(10, TimeUnit.SECONDS);
+        } catch (InterruptedException | TimeoutException ex) {
+            throw new RuntimeException(ex);
+        } catch (ExecutionException | CancellationException ex) {
+            // Failed and canceled futures are completed
+            return;
+        }
+    }
+
+    public static final class CapturingServiceLifecycleCallbacks implements
+            ServiceConnector.ServiceLifecycleCallbacks<ITestServiceConnectorService> {
+        public enum ServiceLifeCycleEvent {
+            ON_CONNECTED,
+            ON_DISCONNECTED,
+            ON_BINDER_DIED,
+        }
+
+        private final ArrayList<ServiceLifeCycleEvent> mCapturedLifecycleEventServices =
+                new ArrayList<>();
+
+        public ArrayList<ServiceLifeCycleEvent> getCapturedLifecycleEvents() {
+            return mCapturedLifecycleEventServices;
+        }
+
+        @Override
+        public void onConnected(@NonNull ITestServiceConnectorService service) {
+            requireNonNull(service);
+            mCapturedLifecycleEventServices.add(ServiceLifeCycleEvent.ON_CONNECTED);
+        }
+
+        @Override
+        public void onDisconnected(@NonNull ITestServiceConnectorService service) {
+            requireNonNull(service);
+            mCapturedLifecycleEventServices.add(ServiceLifeCycleEvent.ON_DISCONNECTED);
+        }
+
+        @Override
+        public void onBinderDied() {
+            mCapturedLifecycleEventServices.add(ServiceLifeCycleEvent.ON_BINDER_DIED);
+        }
+    }
+
+    public static final class TestService extends Service {
+
+        public static String ACTION_TEST_SERVICE = "android.intent.action.BIND_TEST_SERVICE";
+
+        @Nullable
+        @Override
+        public IBinder onBind(@Nullable Intent intent) {
+            if (intent == null) {
+                return null;
+            }
+
+            if (!intent.getAction().equals(ACTION_TEST_SERVICE)) {
+                return null;
+            }
+
+            return new TestServiceConnectorService().asBinder();
+        }
+    }
+
+    private static final class TestServiceConnectorService extends
+            ITestServiceConnectorService.Stub {
+        @Override
+        public void crashProcess() {
+            Process.killProcess(Process.myPid());
+        }
+    }
+}
+
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 2d2c03b..deffa3a 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -20,13 +20,6 @@
 applications that come with the platform
 -->
 <permissions>
-    <privapp-permissions package="android.ext.services">
-        <permission name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
-        <permission name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
-        <permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
-        <permission name="android.permission.INTERACT_ACROSS_USERS" />
-    </privapp-permissions>
-
     <!-- Needed for Build.getSerial(), which is used to send a unique number for serial, per HUIG. -->
     <privapp-permissions package="android.car.usb.handler">
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
@@ -244,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"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 1779655..df2b2a3 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -193,12 +193,6 @@
       "group": "WM_DEBUG_SYNC_ENGINE",
       "at": "com\/android\/server\/wm\/BLASTSyncEngine.java"
     },
-    "-1898316768": {
-      "message": "Unable to retrieve window container to start layer mirroring for display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "-1895337367": {
       "message": "Delete root task display=%d winMode=%d",
       "level": "VERBOSE",
@@ -301,6 +295,12 @@
       "group": "WM_DEBUG_STARTING_WINDOW",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-1781861035": {
+      "message": "Display %d has content (%b) so pause recording",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-1777196134": {
       "message": "goodToGo(): No apps to animate, mPendingAnimations=%d",
       "level": "DEBUG",
@@ -445,6 +445,12 @@
       "group": "WM_DEBUG_LOCKTASK",
       "at": "com\/android\/server\/wm\/LockTaskController.java"
     },
+    "-1605829532": {
+      "message": "Unable to start recording due to null token for display %d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-1598452494": {
       "message": "activityDestroyedLocked: r=%s",
       "level": "DEBUG",
@@ -709,6 +715,12 @@
       "group": "WM_DEBUG_TASKS",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
+    "-1373875178": {
+      "message": "Going ahead with updating recording for display %d to new bounds %s and\/or orientation %d.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-1364754753": {
       "message": "Task vanished taskId=%d",
       "level": "VERBOSE",
@@ -733,6 +745,12 @@
       "group": "WM_DEBUG_STARTING_WINDOW",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-1326876381": {
+      "message": "Provided surface for recording on display %d is not present, so do not update the surface",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-1311436264": {
       "message": "Unregister task fragment organizer=%s uid=%d pid=%d",
       "level": "VERBOSE",
@@ -1105,12 +1123,6 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "-904499590": {
-      "message": "Provided surface for layer mirroring on display %d is not present, so do not update the surface",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "-883738232": {
       "message": "Adding more than one toast window for UID at a time.",
       "level": "WARN",
@@ -1267,6 +1279,12 @@
       "group": "WM_DEBUG_SCREEN_ON",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "-751255162": {
+      "message": "Unable to update recording for display %d to new bounds %s and\/or orientation %d, since the surface is not available.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-743856570": {
       "message": "shouldWaitAnimatingExit: isAnimating: %s",
       "level": "DEBUG",
@@ -1279,6 +1297,12 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
+    "-732715767": {
+      "message": "Unable to retrieve window container to start recording for display %d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-729530161": {
       "message": "Moving to DESTROYED: %s (no app)",
       "level": "VERBOSE",
@@ -1345,12 +1369,6 @@
       "group": "WM_DEBUG_ORIENTATION",
       "at": "com\/android\/server\/wm\/RootWindowContainer.java"
     },
-    "-663411559": {
-      "message": "Going ahead with updating layer mirroring for display %d to new bounds %s and\/or orientation %d.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "-655104359": {
       "message": "Frontmost changed immersion: %s",
       "level": "DEBUG",
@@ -1609,10 +1627,10 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "-384564722": {
-      "message": "Unable to start layer mirroring for display %d since the surface is not available.",
+    "-381522987": {
+      "message": "Display %d state is now (%d), so update recording?",
       "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
       "at": "com\/android\/server\/wm\/DisplayContent.java"
     },
     "-381475323": {
@@ -1699,12 +1717,6 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/TaskFragment.java"
     },
-    "-309399422": {
-      "message": "Display %d state is now (%d), so update layer mirroring?",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "-304728471": {
       "message": "New wallpaper: target=%s prev=%s",
       "level": "DEBUG",
@@ -1717,6 +1729,12 @@
       "group": "WM_DEBUG_RECENTS_ANIMATIONS",
       "at": "com\/android\/server\/wm\/RecentsAnimation.java"
     },
+    "-302468137": {
+      "message": "Display %d was already recording, so apply transformations if necessary",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-292790591": {
       "message": "Attempted to set IME policy to a display that does not exist: %d",
       "level": "WARN",
@@ -1753,6 +1771,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS",
       "at": "com\/android\/server\/wm\/AppTransitionController.java"
     },
+    "-237664290": {
+      "message": "Pause the recording session on display %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+    },
     "-235225312": {
       "message": "Skipping config check for initializing activity: %s",
       "level": "VERBOSE",
@@ -1789,12 +1813,6 @@
       "group": "WM_DEBUG_WINDOW_MOVEMENT",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "-190034097": {
-      "message": "Unable to retrieve window container to update layer mirroring for display %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "-182877285": {
       "message": "Wallpaper layer changed: assigning layers + relayout",
       "level": "VERBOSE",
@@ -1843,6 +1861,12 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/Task.java"
     },
+    "-142844021": {
+      "message": "Unable to start recording for display %d since the surface is not available.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "-134091882": {
       "message": "Screenshotting Activity %s",
       "level": "VERBOSE",
@@ -1903,12 +1927,6 @@
       "group": "WM_DEBUG_STATES",
       "at": "com\/android\/server\/wm\/TaskFragment.java"
     },
-    "-79877120": {
-      "message": "Display %d has content (%b) so disable layer mirroring",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "-70719599": {
       "message": "Unregister remote animations for organizer=%s uid=%d pid=%d",
       "level": "VERBOSE",
@@ -2473,12 +2491,6 @@
       "group": "WM_DEBUG_WINDOW_ORGANIZER",
       "at": "com\/android\/server\/wm\/DisplayAreaOrganizerController.java"
     },
-    "504397469": {
-      "message": "Unable to update layer mirroring for display %d to new bounds %s and\/or orientation %d, since the surface is not available.",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "508887531": {
       "message": "applyAnimation voice: anim=%s transit=%s isEntrance=%b Callers=%s",
       "level": "VERBOSE",
@@ -2587,6 +2599,12 @@
       "group": "WM_SHOW_TRANSACTIONS",
       "at": "com\/android\/server\/wm\/Session.java"
     },
+    "609880497": {
+      "message": "Display %d has no content and is on, so start recording for state %d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "620368427": {
       "message": "******* TELLING SURFACE FLINGER WE ARE BOOTED!",
       "level": "INFO",
@@ -3253,6 +3271,12 @@
       "group": "WM_DEBUG_WINDOW_ORGANIZER",
       "at": "com\/android\/server\/wm\/TaskOrganizerController.java"
     },
+    "1401287081": {
+      "message": "Handle incoming session on display %d, with a pre-existing session %s",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecordingController.java"
+    },
     "1401295262": {
       "message": "Mode default, asking user",
       "level": "WARN",
@@ -3265,12 +3289,6 @@
       "group": "WM_DEBUG_SCREEN_ON",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
-    "1407569006": {
-      "message": "Display %d was already layer mirroring, so apply transformations if necessary",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "1422781269": {
       "message": "Resuming rotation after re-position",
       "level": "DEBUG",
@@ -3301,6 +3319,12 @@
       "group": "WM_ERROR",
       "at": "com\/android\/server\/wm\/WindowManagerService.java"
     },
+    "1444064727": {
+      "message": "Unexpectedly null window container; unable to update recording for display %d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "1448683958": {
       "message": "Override pending remote transitionSet=%b adapter=%s",
       "level": "INFO",
@@ -3427,6 +3451,12 @@
       "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
       "at": "com\/android\/server\/wm\/AppTransition.java"
     },
+    "1608402305": {
+      "message": "Unable to start recording due to invalid region for display %d",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_CONTENT_RECORDING",
+      "at": "com\/android\/server\/wm\/ContentRecorder.java"
+    },
     "1610646518": {
       "message": "Enqueueing pending finish: %s",
       "level": "VERBOSE",
@@ -3517,12 +3547,6 @@
       "group": "WM_DEBUG_CONFIGURATION",
       "at": "com\/android\/server\/wm\/ActivityRecord.java"
     },
-    "1687376052": {
-      "message": "Display %d has no content and is on, so start layer mirroring for state %d",
-      "level": "VERBOSE",
-      "group": "WM_DEBUG_LAYER_MIRRORING",
-      "at": "com\/android\/server\/wm\/DisplayContent.java"
-    },
     "1689989893": {
       "message": "SyncGroup %d: Set ready",
       "level": "VERBOSE",
@@ -3793,6 +3817,12 @@
       "group": "WM_DEBUG_REMOTE_ANIMATIONS",
       "at": "com\/android\/server\/wm\/NonAppWindowAnimationAdapter.java"
     },
+    "2001473656": {
+      "message": "App %s is focused, but the window is not ready. Start a transaction to remove focus from the window of non-focused apps.",
+      "level": "VERBOSE",
+      "group": "WM_DEBUG_FOCUS_LIGHT",
+      "at": "com\/android\/server\/wm\/InputMonitor.java"
+    },
     "2018454757": {
       "message": "WS.removeImmediately: %s Already removed...",
       "level": "VERBOSE",
@@ -3936,6 +3966,9 @@
     "WM_DEBUG_CONTAINERS": {
       "tag": "WindowManager"
     },
+    "WM_DEBUG_CONTENT_RECORDING": {
+      "tag": "WindowManager"
+    },
     "WM_DEBUG_DRAW": {
       "tag": "WindowManager"
     },
@@ -3954,9 +3987,6 @@
     "WM_DEBUG_KEEP_SCREEN_ON": {
       "tag": "WindowManager"
     },
-    "WM_DEBUG_LAYER_MIRRORING": {
-      "tag": "WindowManager"
-    },
     "WM_DEBUG_LOCKTASK": {
       "tag": "WindowManager"
     },
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index e050e17..84e949a 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -1328,6 +1328,9 @@
               postScriptName="NotoSerifCJKjp-Regular">NotoSerifCJK-Regular.ttc
         </font>
     </family>
+    <family lang="und-Zsye" ignore="true">
+        <font weight="400" style="normal">NotoColorEmojiLegacy.ttf</font>
+    </family>
     <family lang="und-Zsye">
         <font weight="400" style="normal">NotoColorEmoji.ttf</font>
     </family>
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 2678c79d..7f70e1c 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -16,10 +16,11 @@
 
 package android.graphics;
 
-import android.annotation.Nullable;
 import android.view.Surface;
 import android.view.SurfaceControl;
 
+import java.util.function.Consumer;
+
 /**
  * @hide
  */
@@ -27,13 +28,14 @@
     // Note: This field is accessed by native code.
     public long mNativeObject; // BLASTBufferQueue*
 
-    private static native long nativeCreate(String name);
+    private static native long nativeCreate(String name, boolean updateDestinationFrame);
     private static native void nativeDestroy(long ptr);
     private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle);
-    private static native void nativeSetSyncTransaction(long ptr, long transactionPtr,
-            boolean acquireSingleBuffer);
+    private static native void nativeSyncNextTransaction(long ptr,
+            Consumer<SurfaceControl.Transaction> callback, boolean acquireSingleBuffer);
+    private static native void nativeStopContinuousSyncTransaction(long ptr);
     private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height,
-            int format, long transactionPtr);
+            int format);
     private static native void nativeMergeWithNextTransaction(long ptr, long transactionPtr,
                                                               long frameNumber);
     private static native long nativeGetLastAcquiredFrameNum(long ptr);
@@ -45,12 +47,12 @@
     /** Create a new connection with the surface flinger. */
     public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
             @PixelFormat.Format int format) {
-        this(name);
+        this(name, false /* updateDestinationFrame */);
         update(sc, width, height, format);
     }
 
-    public BLASTBufferQueue(String name) {
-        mNativeObject = nativeCreate(name);
+    public BLASTBufferQueue(String name, boolean updateDestinationFrame) {
+        mNativeObject = nativeCreate(name, updateDestinationFrame);
     }
 
     public void destroy() {
@@ -74,25 +76,39 @@
     }
 
     /**
-     * Send the transaction to BBQ so the next frame can be added and not applied immediately. This
-     * gives the caller a chance to apply the transaction when it's ready.
-     *
-     * @param t                   The transaction to add the frame to. This can be null to clear the
-     *                            transaction.
+     * Send a callback that accepts a transaction to BBQ. BBQ will acquire buffers into the a
+     * transaction it created and will eventually send the transaction into the callback
+     * when it is ready.
+     * @param callback The callback invoked when the buffer has been added to the transaction. The
+     *                 callback will contain the transaction with the buffer.
      * @param acquireSingleBuffer If true, only acquire a single buffer when processing frames. The
-     *                            transaction will be cleared once a single buffer has been
+     *                            callback will be cleared once a single buffer has been
      *                            acquired. If false, continue to acquire all buffers into the
-     *                            transaction until setSyncTransaction is called again with a null
-     *                            transaction.
+     *                            transaction until stopContinuousSyncTransaction is called.
      */
-    public void setSyncTransaction(@Nullable SurfaceControl.Transaction t,
-            boolean acquireSingleBuffer) {
-        nativeSetSyncTransaction(mNativeObject, t == null ? 0 : t.mNativeObject,
-                acquireSingleBuffer);
+    public void syncNextTransaction(boolean acquireSingleBuffer,
+            Consumer<SurfaceControl.Transaction> callback) {
+        nativeSyncNextTransaction(mNativeObject, callback, acquireSingleBuffer);
     }
 
-    public void setSyncTransaction(@Nullable SurfaceControl.Transaction t) {
-        setSyncTransaction(t, true /* acquireSingleBuffer */);
+    /**
+     * Send a callback that accepts a transaction to BBQ. BBQ will acquire buffers into the a
+     * transaction it created and will eventually send the transaction into the callback
+     * when it is ready.
+     * @param callback The callback invoked when the buffer has been added to the transaction. The
+     *                 callback will contain the transaction with the buffer.
+     */
+    public void syncNextTransaction(Consumer<SurfaceControl.Transaction> callback) {
+        syncNextTransaction(true /* acquireSingleBuffer */, callback);
+    }
+
+    /**
+     * Tell BBQ to stop acquiring buffers into a single transaction. BBQ will send the sync
+     * transaction callback after this has been called. This should only be used when
+     * syncNextTransaction was called with acquireSingleBuffer set to false.
+     */
+    public void stopContinuousSyncTransaction() {
+        nativeStopContinuousSyncTransaction(mNativeObject);
     }
 
     /**
@@ -101,15 +117,9 @@
      * @param width The new width for the buffer.
      * @param height The new height for the buffer.
      * @param format The new format for the buffer.
-     * @param t Adds destination frame changes to the passed in transaction.
      */
-    public void update(SurfaceControl sc, int width, int height, @PixelFormat.Format int format,
-            SurfaceControl.Transaction t) {
-        nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format, t.mNativeObject);
-    }
-
     public void update(SurfaceControl sc, int width, int height, @PixelFormat.Format int format) {
-        nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format, 0);
+        nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 96b3325..4bb16c6 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -218,6 +218,7 @@
         final String name = parser.getAttributeValue(null, "name");
         final String lang = parser.getAttributeValue("", "lang");
         final String variant = parser.getAttributeValue(null, "variant");
+        final String ignore = parser.getAttributeValue(null, "ignore");
         final List<FontConfig.Font> fonts = new ArrayList<>();
         while (keepReading(parser)) {
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
@@ -240,7 +241,9 @@
                 intVariant = FontConfig.FontFamily.VARIANT_ELEGANT;
             }
         }
-        if (fonts.isEmpty()) {
+
+        boolean skip = (ignore != null && (ignore.equals("true") || ignore.equals("1")));
+        if (skip || fonts.isEmpty()) {
             return null;
         }
         return new FontConfig.FontFamily(fonts, name, LocaleList.forLanguageTags(lang), intVariant);
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/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 33b09b8..55f205b 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -690,6 +690,14 @@
         }
     }
 
+    /**
+     * Gets the total duration of the animation
+     * @hide
+     */
+    public long getTotalDuration() {
+        return mAnimatorSet.getTotalDuration();
+    }
+
     private static class AnimatedVectorDrawableState extends ConstantState {
         @Config int mChangingConfigurations;
         VectorDrawable mVectorDrawable;
@@ -1074,6 +1082,7 @@
         boolean isInfinite();
         void pause();
         void resume();
+        long getTotalDuration();
     }
 
     private static class VectorDrawableAnimatorUI implements VectorDrawableAnimator {
@@ -1085,6 +1094,7 @@
         // setup by init().
         private ArrayList<AnimatorListener> mListenerArray = null;
         private boolean mIsInfinite = false;
+        private long mTotalDuration;
 
         VectorDrawableAnimatorUI(@NonNull AnimatedVectorDrawable drawable) {
             mDrawable = drawable;
@@ -1100,7 +1110,8 @@
             // Keep a deep copy of the set, such that set can be still be constantly representing
             // the static content from XML file.
             mSet = set.clone();
-            mIsInfinite = mSet.getTotalDuration() == Animator.DURATION_INFINITE;
+            mTotalDuration = mSet.getTotalDuration();
+            mIsInfinite = mTotalDuration == Animator.DURATION_INFINITE;
 
             // If there are listeners added before calling init(), now they should be setup.
             if (mListenerArray != null && !mListenerArray.isEmpty()) {
@@ -1219,6 +1230,11 @@
         private void invalidateOwningView() {
             mDrawable.invalidateSelf();
         }
+
+        @Override
+        public long getTotalDuration() {
+            return mTotalDuration;
+        }
     }
 
     /**
@@ -1249,6 +1265,7 @@
         private int mLastListenerId = 0;
         private final IntArray mPendingAnimationActions = new IntArray();
         private final AnimatedVectorDrawable mDrawable;
+        private long mTotalDuration;
 
         VectorDrawableAnimatorRT(AnimatedVectorDrawable drawable) {
             mDrawable = drawable;
@@ -1270,7 +1287,8 @@
                     .getNativeTree();
             nSetVectorDrawableTarget(mSetPtr, vectorDrawableTreePtr);
             mInitialized = true;
-            mIsInfinite = set.getTotalDuration() == Animator.DURATION_INFINITE;
+            mTotalDuration = set.getTotalDuration();
+            mIsInfinite = mTotalDuration == Animator.DURATION_INFINITE;
 
             // Check reversible.
             mIsReversible = true;
@@ -1796,6 +1814,11 @@
             }
             mPendingAnimationActions.clear();
         }
+
+        @Override
+        public long getTotalDuration() {
+            return mTotalDuration;
+        }
     }
 
     private static native long nCreateAnimatorSet();
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 8c3fa44..7fd2201 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -424,6 +424,17 @@
             System.arraycopy(mDurations, 0, newDurations, 0, oldSize);
             mDurations = newDurations;
         }
+
+        public long getTotalDuration() {
+            if (mDurations != null) {
+                int total = 0;
+                for (int dur : mDurations) {
+                    total += dur;
+                }
+                return total;
+            }
+            return 0;
+        }
     }
 
     @Override
@@ -435,6 +446,14 @@
         }
     }
 
+    /**
+     * Gets the total duration of the animation
+     * @hide
+     */
+    public long getTotalDuration() {
+        return mAnimationState.getTotalDuration();
+    }
+
     private AnimationDrawable(AnimationState state, Resources res) {
         final AnimationState as = new AnimationState(state, this, res);
         setConstantState(as);
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/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 02cdeef..4b367e0 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -1117,6 +1117,7 @@
                     intent, keyChainServiceConnection, Context.BIND_AUTO_CREATE, user);
         }
         if (!bindSucceed) {
+            context.unbindService(keyChainServiceConnection);
             throw new AssertionError("could not bind to KeyChainService");
         }
         countDownLatch.await();
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 2e85b30..31dd10a 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -66,6 +66,7 @@
 import java.security.UnrecoverableKeyException;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.ECGenParameterSpec;
+import java.security.spec.NamedParameterSpec;
 import java.security.spec.RSAKeyGenParameterSpec;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -119,36 +120,42 @@
     private static final int RSA_MIN_KEY_SIZE = 512;
     private static final int RSA_MAX_KEY_SIZE = 8192;
 
-    private static final Map<String, Integer> SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE =
+    private static final Map<String, Integer> SUPPORTED_EC_CURVE_NAME_TO_SIZE =
             new HashMap<String, Integer>();
-    private static final List<String> SUPPORTED_EC_NIST_CURVE_NAMES = new ArrayList<String>();
-    private static final List<Integer> SUPPORTED_EC_NIST_CURVE_SIZES = new ArrayList<Integer>();
+    private static final List<String> SUPPORTED_EC_CURVE_NAMES = new ArrayList<String>();
+    private static final List<Integer> SUPPORTED_EC_CURVE_SIZES = new ArrayList<Integer>();
+    private static final String CURVE_X_25519 = NamedParameterSpec.X25519.getName();
+    private static final String CURVE_ED_25519 = NamedParameterSpec.ED25519.getName();
+
 
     static {
         // Aliases for NIST P-224
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-224", 224);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp224r1", 224);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-224", 224);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp224r1", 224);
 
 
         // Aliases for NIST P-256
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-256", 256);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp256r1", 256);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("prime256v1", 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-256", 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp256r1", 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("prime256v1", 256);
+        // Aliases for Curve 25519
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put(CURVE_X_25519.toLowerCase(Locale.US), 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put(CURVE_ED_25519.toLowerCase(Locale.US), 256);
 
         // Aliases for NIST P-384
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-384", 384);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp384r1", 384);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-384", 384);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp384r1", 384);
 
         // Aliases for NIST P-521
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-521", 521);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp521r1", 521);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-521", 521);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp521r1", 521);
 
-        SUPPORTED_EC_NIST_CURVE_NAMES.addAll(SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.keySet());
-        Collections.sort(SUPPORTED_EC_NIST_CURVE_NAMES);
+        SUPPORTED_EC_CURVE_NAMES.addAll(SUPPORTED_EC_CURVE_NAME_TO_SIZE.keySet());
+        Collections.sort(SUPPORTED_EC_CURVE_NAMES);
 
-        SUPPORTED_EC_NIST_CURVE_SIZES.addAll(
-                new HashSet<Integer>(SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.values()));
-        Collections.sort(SUPPORTED_EC_NIST_CURVE_SIZES);
+        SUPPORTED_EC_CURVE_SIZES.addAll(
+                new HashSet<Integer>(SUPPORTED_EC_CURVE_NAME_TO_SIZE.values()));
+        Collections.sort(SUPPORTED_EC_CURVE_SIZES);
     }
 
     private final int mOriginalKeymasterAlgorithm;
@@ -164,6 +171,7 @@
     private int mKeySizeBits;
     private SecureRandom mRng;
     private KeyDescriptor mAttestKeyDescriptor;
+    private String mEcCurveName;
 
     private int[] mKeymasterPurposes;
     private int[] mKeymasterBlockModes;
@@ -177,12 +185,15 @@
         mOriginalKeymasterAlgorithm = keymasterAlgorithm;
     }
 
-    private @EcCurve int keySize2EcCurve(int keySizeBits)
+    private static @EcCurve int keySizeAndNameToEcCurve(int keySizeBits, String ecCurveName)
             throws InvalidAlgorithmParameterException {
         switch (keySizeBits) {
             case 224:
                 return EcCurve.P_224;
             case 256:
+                if (isCurve25519(ecCurveName)) {
+                    return EcCurve.CURVE_25519;
+                }
                 return EcCurve.P_256;
             case 384:
                 return EcCurve.P_384;
@@ -247,7 +258,8 @@
             if (mKeySizeBits == -1) {
                 mKeySizeBits = getDefaultKeySize(keymasterAlgorithm);
             }
-            checkValidKeySize(keymasterAlgorithm, mKeySizeBits, mSpec.isStrongBoxBacked());
+            checkValidKeySize(keymasterAlgorithm, mKeySizeBits, mSpec.isStrongBoxBacked(),
+                    mEcCurveName);
 
             if (spec.getKeystoreAlias() == null) {
                 throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
@@ -299,6 +311,7 @@
 
             mAttestKeyDescriptor = buildAndCheckAttestKeyDescriptor(spec);
             checkAttestKeyPurpose(spec);
+            checkCorrectKeyPurposeForCurve(spec);
 
             success = true;
         } finally {
@@ -317,6 +330,42 @@
         }
     }
 
+    private void checkCorrectKeyPurposeForCurve(KeyGenParameterSpec spec)
+            throws InvalidAlgorithmParameterException {
+        // Validate the key usage purposes against the curve. x25519 should be
+        // key exchange only, ed25519 signing and attesting.
+
+        if (!isCurve25519(mEcCurveName)) {
+            return;
+        }
+
+        if (mEcCurveName.equalsIgnoreCase(CURVE_X_25519)
+                && spec.getPurposes() != KeyProperties.PURPOSE_AGREE_KEY) {
+            throw new InvalidAlgorithmParameterException(
+                    "x25519 may only be used for key agreement.");
+        } else if (mEcCurveName.equalsIgnoreCase(CURVE_ED_25519)
+                && !hasOnlyAllowedPurposeForEd25519(spec.getPurposes())) {
+            throw new InvalidAlgorithmParameterException(
+                    "ed25519 may not be used for key agreement.");
+        }
+    }
+
+    private static boolean isCurve25519(String ecCurveName) {
+        if (ecCurveName == null) {
+            return false;
+        }
+        return ecCurveName.equalsIgnoreCase(CURVE_X_25519)
+                || ecCurveName.equalsIgnoreCase(CURVE_ED_25519);
+    }
+
+    private static boolean hasOnlyAllowedPurposeForEd25519(@KeyProperties.PurposeEnum int purpose) {
+        final int allowedPurposes = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
+                | KeyProperties.PURPOSE_ATTEST_KEY;
+        boolean hasAllowedPurpose = (purpose & allowedPurposes) != 0;
+        boolean hasDisallowedPurpose = (purpose & ~allowedPurposes) != 0;
+        return hasAllowedPurpose && !hasDisallowedPurpose;
+    }
+
     private KeyDescriptor buildAndCheckAttestKeyDescriptor(KeyGenParameterSpec spec)
             throws InvalidAlgorithmParameterException {
         if (spec.getAttestKeyAlias() != null) {
@@ -473,6 +522,7 @@
         mRSAPublicExponent = null;
         mRng = null;
         mKeyStore = null;
+        mEcCurveName = null;
     }
 
     private void initAlgorithmSpecificParameters() throws InvalidAlgorithmParameterException {
@@ -514,13 +564,13 @@
             case KeymasterDefs.KM_ALGORITHM_EC:
                 if (algSpecificSpec instanceof ECGenParameterSpec) {
                     ECGenParameterSpec ecSpec = (ECGenParameterSpec) algSpecificSpec;
-                    String curveName = ecSpec.getName();
-                    Integer ecSpecKeySizeBits = SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.get(
-                            curveName.toLowerCase(Locale.US));
+                    mEcCurveName = ecSpec.getName();
+                    final Integer ecSpecKeySizeBits = SUPPORTED_EC_CURVE_NAME_TO_SIZE.get(
+                            mEcCurveName.toLowerCase(Locale.US));
                     if (ecSpecKeySizeBits == null) {
                         throw new InvalidAlgorithmParameterException(
-                                "Unsupported EC curve name: " + curveName
-                                        + ". Supported: " + SUPPORTED_EC_NIST_CURVE_NAMES);
+                                "Unsupported EC curve name: " + mEcCurveName
+                                        + ". Supported: " + SUPPORTED_EC_CURVE_NAMES);
                     }
                     if (mKeySizeBits == -1) {
                         mKeySizeBits = ecSpecKeySizeBits;
@@ -744,7 +794,7 @@
 
         if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
             params.add(KeyStore2ParameterUtils.makeEnum(
-                    Tag.EC_CURVE, keySize2EcCurve(mKeySizeBits)
+                    Tag.EC_CURVE, keySizeAndNameToEcCurve(mKeySizeBits, mEcCurveName)
             ));
         }
 
@@ -864,7 +914,8 @@
     private static void checkValidKeySize(
             int keymasterAlgorithm,
             int keySize,
-            boolean isStrongBoxBacked)
+            boolean isStrongBoxBacked,
+            String mEcCurveName)
             throws InvalidAlgorithmParameterException {
         switch (keymasterAlgorithm) {
             case KeymasterDefs.KM_ALGORITHM_EC:
@@ -873,9 +924,13 @@
                             "Unsupported StrongBox EC key size: "
                                     + keySize + " bits. Supported: 256");
                 }
-                if (!SUPPORTED_EC_NIST_CURVE_SIZES.contains(keySize)) {
+                if (isStrongBoxBacked && isCurve25519(mEcCurveName)) {
+                    throw new InvalidAlgorithmParameterException(
+                            "Unsupported StrongBox EC: " + mEcCurveName);
+                }
+                if (!SUPPORTED_EC_CURVE_SIZES.contains(keySize)) {
                     throw new InvalidAlgorithmParameterException("Unsupported EC key size: "
-                            + keySize + " bits. Supported: " + SUPPORTED_EC_NIST_CURVE_SIZES);
+                            + keySize + " bits. Supported: " + SUPPORTED_EC_CURVE_SIZES);
                 }
                 break;
             case KeymasterDefs.KM_ALGORITHM_RSA:
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index 72a145f..e5d1276 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -66,6 +66,11 @@
     private static final String DESEDE_SYSTEM_PROPERTY =
             "ro.hardware.keystore_desede";
 
+    // Conscrypt returns the Ed25519 OID as the JCA key algorithm.
+    private static final String ED25519_OID = "1.3.101.112";
+    // Conscrypt returns "XDH" as the X25519 JCA key algorithm.
+    private static final String X25519_ALIAS = "XDH";
+
     /** @hide **/
     public AndroidKeyStoreProvider() {
         super(PROVIDER_NAME, 1.0, "Android KeyStore security provider");
@@ -219,12 +224,17 @@
 
         KeyStoreSecurityLevel securityLevel = iSecurityLevel;
         if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) {
-
             return new AndroidKeyStoreECPublicKey(descriptor, metadata,
                     iSecurityLevel, (ECPublicKey) publicKey);
         } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(jcaKeyAlgorithm)) {
             return new AndroidKeyStoreRSAPublicKey(descriptor, metadata,
                     iSecurityLevel, (RSAPublicKey) publicKey);
+        } else if (ED25519_OID.equalsIgnoreCase(jcaKeyAlgorithm)) {
+            //TODO(b/214203951) missing classes in conscrypt
+            throw new ProviderException("Curve " + ED25519_OID + " not supported yet");
+        } else if (X25519_ALIAS.equalsIgnoreCase(jcaKeyAlgorithm)) {
+            //TODO(b/214203951) missing classes in conscrypt
+            throw new ProviderException("Curve " + X25519_ALIAS + " not supported yet");
         } else {
             throw new ProviderException("Unsupported Android Keystore public key algorithm: "
                     + jcaKeyAlgorithm);
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 0bf078d..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;
@@ -404,7 +405,7 @@
     TaskFragmentContainer getTopActiveContainer() {
         for (int i = mContainers.size() - 1; i >= 0; i--) {
             TaskFragmentContainer container = mContainers.get(i);
-            if (!container.isFinished() && container.getTopNonFinishingActivity() != null) {
+            if (!container.isFinished() && container.getRunningActivityCount() > 0) {
                 return container;
             }
         }
@@ -499,6 +500,10 @@
     boolean launchPlaceholderIfNecessary(@NonNull Activity activity) {
         final  TaskFragmentContainer container = getContainerWithActivity(
                 activity.getActivityToken());
+        // Don't launch placeholder if the container is occluded.
+        if (container != getTopActiveContainer()) {
+            return false;
+        }
 
         SplitContainer splitContainer = container != null ? getActiveSplitForContainer(container)
                 : null;
@@ -759,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) {
@@ -775,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/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/packages/SystemUI/res/values-w650dp-land/dimens.xml b/libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml
similarity index 73%
rename from packages/SystemUI/res/values-w650dp-land/dimens.xml
rename to libs/WindowManager/Shell/res/color/letterbox_education_dismiss_button_background_ripple.xml
index 97b6da1..43cba1a 100644
--- a/packages/SystemUI/res/values-w650dp-land/dimens.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) 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,7 +14,6 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<resources>
-    <!-- Standard notification width + gravity -->
-    <dimen name="notification_panel_width">-1px</dimen> <!-- match_parent -->
-</resources>
+<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/layout/bubble_overflow_container.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
index 76fe3c9..cb516cd 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
@@ -19,9 +19,8 @@
     android:id="@+id/bubble_overflow_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:paddingTop="@dimen/bubble_overflow_padding"
-    android:paddingLeft="@dimen/bubble_overflow_padding"
-    android:paddingRight="@dimen/bubble_overflow_padding"
+    android:paddingLeft="@dimen/bubble_overflow_container_padding_horizontal"
+    android:paddingRight="@dimen/bubble_overflow_container_padding_horizontal"
     android:orientation="vertical"
     android:layout_gravity="center_horizontal">
 
diff --git a/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml
index 05b1506..78de76a 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml
@@ -22,7 +22,6 @@
     android:orientation="vertical">
 
     <com.android.wm.shell.bubbles.BadgedImageView
-        xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/bubble_view"
         android:layout_gravity="center"
         android:layout_width="@dimen/bubble_size"
@@ -30,16 +29,14 @@
 
     <TextView
         android:id="@+id/bubble_view_name"
-        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
-        android:textSize="13sp"
+        android:textSize="14sp"
         android:layout_width="@dimen/bubble_name_width"
         android:layout_height="wrap_content"
-        android:maxLines="1"
-        android:lines="2"
+        android:lines="1"
         android:ellipsize="end"
         android:layout_gravity="center"
         android:paddingTop="@dimen/bubble_overflow_text_padding"
         android:paddingEnd="@dimen/bubble_overflow_text_padding"
         android:paddingStart="@dimen/bubble_overflow_text_padding"
-        android:gravity="center"/>
+        android:gravity="center_horizontal|top"/>
 </LinearLayout>
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 88382d7..2476f65 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerakwessies?\nTik om aan te pas"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nie opgelos nie?\nTik om terug te stel"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen kamerakwessies nie? Tik om toe te maak."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sommige programme werk beter in portret"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Probeer een van hierdie opsies om jou spasie ten beste te benut"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Draai jou toestel om dit volskerm te maak"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dubbeltik langs ’n program om dit te herposisioneer"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Het dit"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-af/strings_tv.xml b/libs/WindowManager/Shell/res/values-af/strings_tv.xml
index 1bfe128..f552b81 100644
--- a/libs/WindowManager/Shell/res/values-af/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Maak PIP toe"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Volskerm"</string>
     <string name="pip_move" msgid="1544227837964635439">"Skuif PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Vou PIP uit"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Vou PIP in"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 20d081f..f0c391c 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"የካሜራ ችግሮች አሉ?\nዳግም ለማበጀት መታ ያድርጉ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"አንዳንድ መተግበሪያዎች በቁም ፎቶ ውስጥ በተሻለ ሁኔታ ይሰራሉ"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ቦታዎን በአግባቡ ለመጠቀም ከእነዚህ አማራጮች ውስጥ አንዱን ይሞክሩ"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ወደ የሙሉ ገጽ ዕይታ ለመሄድ መሣሪያዎን ያሽከርክሩት"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ቦታውን ለመቀየር ከመተግበሪያው ቀጥሎ ላይ ሁለቴ መታ ያድርጉ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ገባኝ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-am/strings_tv.xml b/libs/WindowManager/Shell/res/values-am/strings_tv.xml
index 456b4b8..6b6fe9f 100644
--- a/libs/WindowManager/Shell/res/values-am/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIPን ዝጋ"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ሙሉ ማያ ገጽ"</string>
     <string name="pip_move" msgid="1544227837964635439">"ፒአይፒ ውሰድ"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"ፒአይፒን ዘርጋ"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"ፒአይፒን ሰብስብ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index b41e642..aa4b3b7 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"هل هناك مشاكل في الكاميرا؟\nانقر لإعادة الضبط."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ألم يتم حل المشكلة؟\nانقر للعودة"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"أليس هناك مشاكل في الكاميرا؟ انقر للإغلاق."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"تعمل بعض التطبيقات على أكمل وجه في الشاشات العمودية"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"جرِّب تنفيذ أحد هذه الخيارات للاستفادة من مساحتك إلى أقصى حد."</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"قم بتدوير الشاشة للانتقال إلى وضع ملء الشاشة."</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"انقر مرتين بجانب التطبيق لتغيير موضعه."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"حسنًا"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
index 2546fe9..a85d7b1 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"‏إغلاق PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ملء الشاشة"</string>
     <string name="pip_move" msgid="1544227837964635439">"‏نقل نافذة داخل النافذة (PIP)"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"‏توسيع نافذة داخل النافذة (PIP)"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"‏تصغير نافذة داخل النافذة (PIP)"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 663691f..985d3b9 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"কেমেৰাৰ কোনো সমস্যা হৈছে নেকি?\nপুনৰ খাপ খোৱাবলৈ টিপক"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এইটো সমাধান কৰা নাই নেকি?\nপূৰ্বাৱস্থালৈ নিবলৈ টিপক"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"কেমেৰাৰ কোনো সমস্যা নাই নেকি? অগ্ৰাহ্য কৰিবলৈ টিপক।"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"কিছুমান এপে প’ৰ্ট্ৰেইট ম’ডত বেছি ভালকৈ কাম কৰে"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"আপোনাৰ spaceৰ পৰা পাৰ্যমানে উপকৃত হ’বলৈ ইয়াৰে এটা বিকল্প চেষ্টা কৰি চাওক"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"পূৰ্ণ স্ক্ৰীনলৈ যাবলৈ আপোনাৰ ডিভাইচটো ঘূৰাওক"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"এপ্‌টোৰ স্থান সলনি কৰিবলৈ ইয়াৰ কাষত দুবাৰ টিপক"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুজি পালোঁ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-as/strings_tv.xml b/libs/WindowManager/Shell/res/values-as/strings_tv.xml
index d17c1f3..9e2f550 100644
--- a/libs/WindowManager/Shell/res/values-as/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"পিপ বন্ধ কৰক"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"সম্পূৰ্ণ স্ক্ৰীন"</string>
     <string name="pip_move" msgid="1544227837964635439">"পিপ স্থানান্তৰ কৰক"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"পিপ বিস্তাৰ কৰক"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"পিপ সংকোচন কৰক"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 646aba8..8cd9b7a 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera problemi var?\nBərpa etmək üçün toxunun"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera problemi yoxdur? Qapatmaq üçün toxunun."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Bəzi tətbiqlər portret rejimində daha yaxşı işləyir"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Məkanınızdan maksimum yararlanmaq üçün bu seçimlərdən birini sınayın"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Tam ekrana keçmək üçün cihazınızı fırladın"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tətbiqin yerini dəyişmək üçün yanına iki dəfə toxunun"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-az/strings_tv.xml b/libs/WindowManager/Shell/res/values-az/strings_tv.xml
index a5c4792..670b02f 100644
--- a/libs/WindowManager/Shell/res/values-az/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP bağlayın"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Tam ekran"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP tətbiq edin"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP-ni genişləndirin"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP-ni yığcamlaşdırın"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 2ebdf92..49524c6 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Imate problema sa kamerom?\nDodirnite da biste ponovo uklopili"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Neke aplikacije najbolje funkcionišu u uspravnom režimu"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Isprobajte jednu od ovih opcija da biste na najbolji način iskoristili prostor"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotirajte uređaj za prikaz preko celog ekrana"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da biste promenili njenu poziciju"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Važi"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
index b4d9bd1..de23d71 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Ceo ekran"</string>
     <string name="pip_move" msgid="1544227837964635439">"Premesti sliku u slici"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Proširi sliku u slici"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Skupi sliku u slici"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 157e168..1767e0d 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Праблемы з камерай?\nНацісніце, каб пераабсталяваць"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не ўдалося выправіць?\nНацісніце, каб аднавіць"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ніякіх праблем з камерай? Націсніце, каб адхіліць."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Некаторыя праграмы лепш за ўсё працуюць у кніжнай арыентацыі"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Каб эфектыўна выкарыстоўваць прастору, паспрабуйце адзін з гэтых варыянтаў"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Каб перайсці ў поўнаэкранны рэжым, павярніце прыладу"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Двойчы націсніце побач з праграмай, каб перамясціць яе"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Зразумела"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-be/strings_tv.xml b/libs/WindowManager/Shell/res/values-be/strings_tv.xml
index 514d06b..03de88c 100644
--- a/libs/WindowManager/Shell/res/values-be/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Закрыць PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Поўнаэкранны рэжым"</string>
     <string name="pip_move" msgid="1544227837964635439">"Перамясціць PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Разгарнуць відарыс у відарысе"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Згарнуць відарыс у відарысе"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 4ed8672..c22fb86 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблеми с камерата?\nДокоснете за ремонтиране"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблемът не се отстрани?\nДокоснете за връщане в предишното състояние"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нямате проблеми с камерата? Докоснете, за да отхвърлите."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Някои приложения работят най-добре във вертикален режим"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Изпробвайте една от следните опции, за да се възползвате максимално от мястото на екрана"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Завъртете екрана си, за да преминете в режим на цял екран"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Докоснете два пъти дадено приложение, за да промените позицията му"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Разбрах"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
index 19f83e7..38e1ef8 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Затваряне на PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Цял екран"</string>
     <string name="pip_move" msgid="1544227837964635439">"„Картина в картина“: Преместв."</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Разгъване на прозореца за PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Свиване на прозореца за PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 7579fac..c0944e05 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ক্যামেরা সংক্রান্ত সমস্যা?\nরিফিট করতে ট্যাপ করুন"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এখনও সমাধান হয়নি?\nরিভার্ট করার জন্য ট্যাপ করুন"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ক্যামেরা সংক্রান্ত সমস্যা নেই? বাতিল করতে ট্যাপ করুন।"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"কিছু অ্যাপ \'পোর্ট্রেট\' মোডে সবচেয়ে ভাল কাজ করে"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"আপনার স্পেস সবচেয়ে ভালভাবে কাজে লাগাতে এইসব বিকল্পের মধ্যে কোনও একটি ব্যবহার করে দেখুন"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"\'ফুল স্ক্রিন\' মোডে যেতে ডিভাইস ঘোরান"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"কোনও অ্যাপের পাশে ডবল ট্যাপ করে সেটির জায়গা পরিবর্তন করুন"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"বুঝেছি"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
index 5f90eeb..0b24328 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP বন্ধ করুন"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"পূর্ণ স্ক্রিন"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP সরান"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP বড় করুন"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP আড়াল করুন"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 7b08d03..ae01c64 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s kamerom?\nDodirnite da ponovo namjestite"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Određene aplikacije najbolje funkcioniraju u uspravnom načinu rada"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Isprobajte jednu od ovih opcija da maksimalno iskoristite prostor"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zarotirajte uređaj da aktivirate prikaz preko cijelog ekrana"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da promijenite njen položaj"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Razumijem"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
index 3f2adf3..63e23c2 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Zatvori sliku u slici"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Cijeli ekran"</string>
     <string name="pip_move" msgid="1544227837964635439">"Pokreni sliku u slici"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Proširi sliku u slici"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Suzi sliku u slici"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 44429cc..2ec1db4 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tens problemes amb la càmera?\nToca per resoldre\'ls"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"El problema no s\'ha resolt?\nToca per desfer els canvis"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No tens cap problema amb la càmera? Toca per ignorar."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunes aplicacions funcionen millor en posició vertical"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prova una d\'aquestes opcions per treure el màxim profit de l\'espai"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gira el dispositiu per passar a pantalla completa"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Fes doble toc al costat d\'una aplicació per canviar-ne la posició"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entesos"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
index db750c4..e35390a 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Tanca PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mou pantalla en pantalla"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Desplega pantalla en pantalla"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Replega pantalla en pantalla"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index d6e7136..d0cf80a 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s fotoaparátem?\nKlepnutím vyřešíte"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepomohlo to?\nKlepnutím se vrátíte"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Žádné problémy s fotoaparátem? Klepnutím zavřete."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Některé aplikace fungují nejlépe na výšku"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Pokud chcete maximálně využít prostor, vyzkoušejte jednu z těchto možností"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Otočením zařízení přejděte do režimu celé obrazovky"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvojitým klepnutím vedle aplikace změňte její umístění"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
index cef0b99..9b38537 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Ukončit obraz v obraze (PIP)"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Celá obrazovka"</string>
     <string name="pip_move" msgid="1544227837964635439">"Přesunout PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Rozbalit PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Sbalit PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index e7b8e73..bb81c10 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du problemer med dit kamera?\nTryk for at gendanne det oprindelige format"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Løste det ikke problemet?\nTryk for at fortryde"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen problemer med dit kamera? Tryk for at afvise."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Nogle apps fungerer bedst i stående format"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prøv én af disse muligheder for at få mest muligt ud af dit rum"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Drej din enhed for at gå til fuld skærm"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tryk to gange ud for en app for at ændre dens placering"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-da/strings_tv.xml b/libs/WindowManager/Shell/res/values-da/strings_tv.xml
index 2330530..2f3b359 100644
--- a/libs/WindowManager/Shell/res/values-da/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Luk integreret billede"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Fuld skærm"</string>
     <string name="pip_move" msgid="1544227837964635439">"Flyt PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Udvid PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Skjul PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 57af696c..3a110793 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Probleme mit der Kamera?\nZum Anpassen tippen."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Einige Apps funktionieren am besten im Hochformat"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Mithilfe dieser Möglichkeiten kannst du dein Display optimal nutzen"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gerät drehen, um zum Vollbildmodus zu wechseln"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Neben einer App doppeltippen, um die Position zu ändern"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ok"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-de/strings_tv.xml b/libs/WindowManager/Shell/res/values-de/strings_tv.xml
index 8da9110..07fc28d 100644
--- a/libs/WindowManager/Shell/res/values-de/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP schließen"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Vollbild"</string>
     <string name="pip_move" msgid="1544227837964635439">"BiB verschieben"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"BiB maximieren"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"BiB minimieren"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 873b329..70f5505 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Προβλήματα με την κάμερα;\nΠατήστε για επιδιόρθωση."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Δεν διορθώθηκε;\nΠατήστε για επαναφορά."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Δεν αντιμετωπίζετε προβλήματα με την κάμερα; Πατήστε για παράβλεψη."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Ορισμένες εφαρμογές λειτουργούν καλύτερα σε κατακόρυφο προσανατολισμό"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Δοκιμάστε μία από αυτές τις επιλογές για να αξιοποιήσετε στο έπακρο τον χώρο σας."</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Περιστρέψτε τη συσκευή σας για μετάβαση σε πλήρη οθόνη."</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Πατήστε δύο φορές δίπλα σε μια εφαρμογή για να αλλάξετε τη θέση της."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Το κατάλαβα"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-el/strings_tv.xml b/libs/WindowManager/Shell/res/values-el/strings_tv.xml
index df35113..1eba0b7 100644
--- a/libs/WindowManager/Shell/res/values-el/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Κλείσιμο PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Πλήρης οθόνη"</string>
     <string name="pip_move" msgid="1544227837964635439">"Μετακίνηση PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Ανάπτυξη PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Σύμπτυξη PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index da4933b..0b5aefa5 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml
index 1fb3191..79a8b95 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string>
     <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index da4933b..0b5aefa5 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml
index 1fb3191..79a8b95 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string>
     <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index da4933b..0b5aefa5 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml
index 1fb3191..79a8b95 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string>
     <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index da4933b..0b5aefa5 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Camera issues?\nTap to refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Some apps work best in portrait"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Try one of these options to make the most of your space"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotate your device to go full screen"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Double-tap next to an app to reposition it"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Got it"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml
index 1fb3191..79a8b95 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Close PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string>
     <string name="pip_move" msgid="1544227837964635439">"Move PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Expand PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Collapse PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml
index 3b12d90..8925f18 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎Close PIP‎‏‎‎‏‎"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎Full screen‎‏‎‎‏‎"</string>
     <string name="pip_move" msgid="1544227837964635439">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‏‏‎Move PIP‎‏‎‎‏‎"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎Expand PIP‎‏‎‎‏‎"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‏‏‏‎‎Collapse PIP‎‏‎‎‏‎"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index 154c7ab..e523ae5 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Tienes problemas con la cámara?\nPresiona para reajustarla"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se resolvió?\nPresiona para revertir los cambios"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No tienes problemas con la cámara? Presionar para descartar."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunas apps funcionan mejor en modo vertical"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prueba estas opciones para aprovechar al máximo tu espacio"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rota el dispositivo para ver la pantalla completa"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Presiona dos veces junto a una app para cambiar su posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
index 1beb0b5..1b1a419 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Cerrar PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mover PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Maximizar PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Minimizar PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index e2fa3a0..9749607 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Problemas con la cámara?\nToca para reajustar"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se ha solucionado?\nToca para revertir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No hay problemas con la cámara? Toca para cerrar."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunas aplicaciones funcionan mejor en vertical"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prueba una de estas opciones para sacar el máximo partido al espacio de tu pantalla"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gira el dispositivo para ir al modo de pantalla completa"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toca dos veces junto a una aplicación para cambiar su posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-es/strings_tv.xml b/libs/WindowManager/Shell/res/values-es/strings_tv.xml
index d042b43..29ff1c6 100644
--- a/libs/WindowManager/Shell/res/values-es/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Cerrar PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mover imagen en imagen"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Mostrar imagen en imagen"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Ocultar imagen en imagen"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index da33f4d..a5f82a6 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kas teil on kaameraprobleeme?\nPuudutage ümberpaigutamiseks."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Kas probleemi ei lahendatud?\nPuudutage ennistamiseks."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kas kaameraprobleeme pole? Puudutage loobumiseks."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Mõni rakendus töötab kõige paremini vertikaalpaigutuses"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Proovige ühte neist valikutest, et oma ruumi parimal moel kasutada"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pöörake seadet, et aktiveerida täisekraanirežiim"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Topeltpuudutage rakenduse kõrval, et selle asendit muuta"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Selge"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-et/strings_tv.xml b/libs/WindowManager/Shell/res/values-et/strings_tv.xml
index 3da16db..f528bb2 100644
--- a/libs/WindowManager/Shell/res/values-et/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Sule PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Täisekraan"</string>
     <string name="pip_move" msgid="1544227837964635439">"Teisalda PIP-režiimi"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Laienda PIP-akent"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Ahenda PIP-aken"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index e0dd3ca2..caa335a 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Arazoak dauzkazu kamerarekin?\nBerriro doitzeko, sakatu hau."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ez al da konpondu?\nLeheneratzeko, sakatu hau."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ez daukazu arazorik kamerarekin? Baztertzeko, sakatu hau."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Aplikazio batzuk orientazio bertikalean funtzionatzen dute hobekien"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Pantailako eremuari ahalik eta etekinik handiena ateratzeko, probatu aukera hauetakoren bat"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pantaila osoko modua erabiltzeko, biratu gailua"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Aplikazioaren posizioa aldatzeko, sakatu birritan haren ondoko edozein toki"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ados"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
index e4b57ba..72f9980 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Itxi PIPa"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pantaila osoa"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mugitu pantaila txiki gainjarria"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Zabaldu pantaila txiki gainjarria"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Tolestu pantaila txiki gainjarria"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index 6fcb5ee..9e72571 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"دوربین مشکل دارد؟\nبرای تنظیم مجدد اندازه ضربه بزنید"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن ضربه بزنید"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن ضربه بزنید."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"برخی‌از برنامه‌ها در حالت عمودی عملکرد بهتری دارند"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"با امتحان کردن یکی از این گزینه‌ها، بیشترین بهره را از فضایتان ببرید"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"برای رفتن به حالت تمام صفحه، دستگاهتان را بچرخانید"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"در کنار برنامه دوضربه بزنید تا جابه‌جا شود"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"متوجه‌ام"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings_tv.xml b/libs/WindowManager/Shell/res/values-fa/strings_tv.xml
index aaab34f..5fa59be 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"‏بستن PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"تمام صفحه"</string>
     <string name="pip_move" msgid="1544227837964635439">"‏انتقال PIP (تصویر در تصویر)"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"گسترده کردن «تصویر در تصویر»"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"جمع کردن «تصویر در تصویر»"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index fc51ad4..c809b487 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Onko kameran kanssa ongelmia?\nKorjaa napauttamalla"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Eikö ongelma ratkennut?\nKumoa napauttamalla"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ei ongelmia kameran kanssa? Hylkää napauttamalla."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Osa sovelluksista toimii parhaiten pystytilassa"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Kokeile jotakin näistä vaihtoehdoista, jotta saat parhaan hyödyn näytön tilasta"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Käännä laitetta, niin se siirtyy koko näytön tilaan"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Kaksoisnapauta sovellusta, jos haluat siirtää sitä"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
index 21c6463..217a85c 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Sulje PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Koko näyttö"</string>
     <string name="pip_move" msgid="1544227837964635439">"Siirrä PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Laajenna PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Tiivistä PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 43fad3a..62b2bb6 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo?\nTouchez pour réajuster"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Certaines applications fonctionnent mieux en mode portrait"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Essayez l\'une de ces options pour tirer le meilleur parti de votre espace"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Faites pivoter votre appareil pour passer en plein écran"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Touchez deux fois à côté d\'une application pour la repositionner"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
index f4baaad..b6f401f 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Fermer mode IDI"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Plein écran"</string>
     <string name="pip_move" msgid="1544227837964635439">"Déplacer l\'image incrustée"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Développer l\'image incrustée"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Réduire l\'image incrustée"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 8b8cc09..b3e22af 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo ?\nAppuyez pour réajuster"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu ?\nAppuyez pour rétablir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo ? Appuyez pour ignorer."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Certaines applis fonctionnent mieux en mode Portrait"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Essayez l\'une de ces options pour exploiter pleinement l\'espace"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Faites pivoter l\'appareil pour passer en plein écran"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Appuyez deux fois à côté d\'une appli pour la repositionner"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
index 6ad8174..ffa4a22 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Fermer mode PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Plein écran"</string>
     <string name="pip_move" msgid="1544227837964635439">"Déplacer le PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Développer la fenêtre PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Réduire la fenêtre PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 9bc9d93..b8e0396 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Tes problemas coa cámara?\nToca para reaxustala"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algunhas aplicacións funcionan mellor en modo vertical"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Proba unha destas opcións para sacar o máximo proveito do espazo da pantalla"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Xira o dispositivo para ver o contido en pantalla completa"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toca dúas veces a carón dunha aplicación para cambiala de posición"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendido"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
index dcb8709..3a7ed89 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Pechar PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pantalla completa"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mover pantalla superposta"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Despregar pantalla superposta"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Contraer pantalla superposta"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 032b591..deda2d7 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"કૅમેરામાં સમસ્યાઓ છે?\nફરીથી ફિટ કરવા માટે ટૅપ કરો"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"સુધારો નથી થયો?\nપહેલાંના પર પાછું ફેરવવા માટે ટૅપ કરો"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"કૅમેરામાં કોઈ સમસ્યા નથી? છોડી દેવા માટે ટૅપ કરો."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"અમુક ઍપ પોર્ટ્રેટ મોડમાં શ્રેષ્ઠ રીતે કાર્ય કરે છે"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"તમારી સ્પેસનો વધુને વધુ લાભ લેવા માટે, આ વિકલ્પોમાંથી કોઈ એક અજમાવો"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"પૂર્ણ સ્ક્રીન મોડ લાગુ કરવા માટે, તમારા ડિવાઇસને ફેરવો"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"કોઈ ઍપની જગ્યા બદલવા માટે, તેની બાજુમાં બે વાર ટૅપ કરો"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"સમજાઈ ગયું"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings_tv.xml b/libs/WindowManager/Shell/res/values-gu/strings_tv.xml
index ed815ca..7a9bb25 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP બંધ કરો"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"પૂર્ણ સ્ક્રીન"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP ખસેડો"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP મોટી કરો"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP નાની કરો"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 72fd65c..36b1151 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्या कैमरे से जुड़ी कोई समस्या है?\nफिर से फ़िट करने के लिए टैप करें"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"कुछ ऐप्लिकेशन, पोर्ट्रेट मोड में सबसे अच्छी तरह काम करते हैं"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"जगह का पूरा इस्तेमाल करने के लिए, इनमें से किसी एक विकल्प को आज़माएं"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"फ़ुल स्क्रीन मोड में जाने के लिए, डिवाइस को घुमाएं"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"किसी ऐप्लिकेशन की जगह बदलने के लिए, उसके बगल में दो बार टैप करें"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ठीक है"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
index 8bcc631..5776f81 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP बंद करें"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"फ़ुल स्‍क्रीन"</string>
     <string name="pip_move" msgid="1544227837964635439">"पीआईपी को दूसरी जगह लेकर जाएं"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"पीआईपी विंडो को बड़ा करें"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"पीआईपी विंडो को छोटा करें"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 5315558..5ecc558 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s fotoaparatom?\nDodirnite za popravak"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije riješen?\nDodirnite za vraćanje"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema s fotoaparatom? Dodirnite za odbacivanje."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Neke aplikacije najbolje funkcioniraju u portretnom usmjerenju"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Isprobajte jednu od ovih opcija da biste maksimalno iskoristili prostor"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zakrenite uređaj radi prikaza na cijelom zaslonu"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvaput dodirnite pored aplikacije da biste joj promijenili položaj"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Shvaćam"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
index 49b7ae0..e4d6944 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Zatvori PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Cijeli zaslon"</string>
     <string name="pip_move" msgid="1544227837964635439">"Premjesti PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Proširi PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Sažmi PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 01671c9..2295250 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamerával kapcsolatos problémába ütközött?\nKoppintson a megoldáshoz."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Egyes alkalmazások álló tájolásban működnek a leghatékonyabban"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Próbálja ki az alábbi beállítások egyikét, hogy a legjobban ki tudja használni képernyő területét"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"A teljes képernyős mód elindításához forgassa el az eszközt"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Koppintson duplán az alkalmazás mellett az áthelyezéséhez"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Értem"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings_tv.xml b/libs/WindowManager/Shell/res/values-hu/strings_tv.xml
index 484db0c..43beeea 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP bezárása"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Teljes képernyő"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP áthelyezése"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Kép a képben kibontása"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Kép a képben összecsukása"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 459cd0a..2089365 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Տեսախցիկի հետ կապված խնդիրնե՞ր կան։\nՀպեք՝ վերակարգավորելու համար։"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Որոշ հավելվածներ լավագույնս աշխատում են դիմանկարի ռեժիմում"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Փորձեք այս տարբերակներից մեկը՝ տարածքը հնարավորինս արդյունավետ օգտագործելու համար"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Պտտեք սարքը՝ լիաէկրան ռեժիմին անցնելու համար"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Կրկնակի հպեք հավելվածի կողքին՝ այն տեղափոխելու համար"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Եղավ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
index e447ffc..e439d5c 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Փակել PIP-ն"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Լիէկրան"</string>
     <string name="pip_move" msgid="1544227837964635439">"Տեղափոխել PIP-ը"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Ծավալել PIP-ը"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Ծալել PIP-ը"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index e5b7421..1b46b2f 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Masalah kamera?\nKetuk untuk memperbaiki"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tidak dapat diperbaiki?\nKetuk untuk mengembalikan"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tidak ada masalah kamera? Ketuk untuk menutup."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Beberapa aplikasi berfungsi paling baik dalam mode potret"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Coba salah satu opsi berikut untuk mengoptimalkan area layar Anda"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Putar perangkat untuk tampilan layar penuh"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ketuk dua kali di samping aplikasi untuk mengubah posisinya"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Oke"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-in/strings_tv.xml b/libs/WindowManager/Shell/res/values-in/strings_tv.xml
index b631705..25cb756 100644
--- a/libs/WindowManager/Shell/res/values-in/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Tutup PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Layar penuh"</string>
     <string name="pip_move" msgid="1544227837964635439">"Pindahkan PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Luaskan PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Ciutkan PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 1bfec2b..a201c95 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Myndavélavesen?\nÝttu til að breyta stærð"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ennþá vesen?\nÝttu til að afturkalla"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ekkert myndavélavesen? Ýttu til að hunsa."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sum forrit virka best í skammsniði"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prófaðu einhvern af eftirfarandi valkostum til að nýta plássið sem best"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Snúðu tækinu til að nota allan skjáinn"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ýttu tvisvar við hlið forritsins til að færa það"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ég skil"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-is/strings_tv.xml b/libs/WindowManager/Shell/res/values-is/strings_tv.xml
index 119ecf0..56b9739 100644
--- a/libs/WindowManager/Shell/res/values-is/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Loka mynd í mynd"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Allur skjárinn"</string>
     <string name="pip_move" msgid="1544227837964635439">"Færa innfellda mynd"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Stækka innfellda mynd"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Minnka innfellda mynd"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index ebdf44b..dd5416f 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi con la fotocamera?\nTocca per risolverli"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Alcune app funzionano in modo ottimale in verticale"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prova una di queste opzioni per ottimizzare lo spazio a tua disposizione"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ruota il dispositivo per passare alla modalità a schermo intero"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tocca due volte accanto a un\'app per riposizionarla"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-it/strings_tv.xml b/libs/WindowManager/Shell/res/values-it/strings_tv.xml
index 92f015c..735c5cd 100644
--- a/libs/WindowManager/Shell/res/values-it/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Chiudi PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Schermo intero"</string>
     <string name="pip_move" msgid="1544227837964635439">"Sposta PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Espandi PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Comprimi PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index 3a0f72b..52a6b06 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"בעיות במצלמה?\nאפשר להקיש כדי לבצע התאמה מחדש"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"הבעיה לא נפתרה?\nאפשר להקיש כדי לחזור לגרסה הקודמת"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"אין בעיות במצלמה? אפשר להקיש כדי לסגור."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"חלק מהאפליקציות פועלות בצורה הטובה ביותר במצב תצוגה לאורך"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"כדי להפיק את המרב משטח המסך, ניתן לנסות את אחת מהאפשרויות האלה"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"מסובבים את המכשיר כדי לעבור לתצוגה במסך מלא"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"מקישים הקשה כפולה ליד אפליקציה כדי למקם אותה מחדש"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"הבנתי"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
index d09b850..e4e0bf6 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"‏סגירת PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"מסך מלא"</string>
     <string name="pip_move" msgid="1544227837964635439">"‏העברת תמונה בתוך תמונה (PIP)"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"הרחבת חלון תמונה-בתוך-תמונה"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"כיווץ של חלון תמונה-בתוך-תמונה"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 7b3ad24..5a25c24 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"カメラに関する問題の場合は、\nタップすると修正できます"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"修正されなかった場合は、\nタップすると元に戻ります"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"カメラに関する問題でない場合は、タップすると閉じます。"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"アプリによっては縦向きにすると正常に動作します"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"スペースを最大限に活用するには、以下の方法のいずれかをお試しください"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"全画面表示にするにはデバイスを回転させてください"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"位置を変えるにはアプリの横をダブルタップしてください"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings_tv.xml b/libs/WindowManager/Shell/res/values-ja/strings_tv.xml
index d6399e5..c8326a6 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP を閉じる"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"全画面表示"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP を移動"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP を開く"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP を閉じる"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 07ee0f9..bff86fa 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"კამერად პრობლემები აქვს?\nშეეხეთ გამოსასწორებლად"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"არ გამოსწორდა?\nშეეხეთ წინა ვერსიის დასაბრუნებლად"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"კამერას პრობლემები არ აქვს? შეეხეთ უარყოფისთვის."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ზოგიერთი აპი უკეთ მუშაობს პორტრეტის რეჟიმში"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"გამოცადეთ ამ ვარიანტებიდან ერთ-ერთი, რათა მაქსიმალურად ისარგებლოთ თქვენი მეხსიერებით"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"მოატრიალეთ თქვენი მოწყობილობა სრული ეკრანის გასაშლელად"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ორმაგად შეეხეთ აპის გვერდითა სივრცეს, რათა ის სხვაგან გადაიტანოთ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"გასაგებია"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings_tv.xml b/libs/WindowManager/Shell/res/values-ka/strings_tv.xml
index 8d7bee8..025e5a5 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP-ის დახურვა"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"სრულ ეკრანზე"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP გადატანა"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP-ის გაშლა"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP-ის ჩაკეცვა"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index bdaa03e..f57f3f5 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада қателер шықты ма?\nЖөндеу үшін түртіңіз."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Кейбір қолданба портреттік режимде жақсы жұмыс істейді"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Экранды тиімді пайдалану үшін мына опциялардың бірін байқап көріңіз."</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Толық экранға ауысу үшін құрылғыңызды бұрыңыз."</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Қолданбаның орнын ауыстыру үшін жанынан екі рет түртіңіз."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түсінікті"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings_tv.xml b/libs/WindowManager/Shell/res/values-kk/strings_tv.xml
index 05bdcc7..27afe2e 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP жабу"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Толық экран"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP клипін жылжыту"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP терезесін жаю"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP терезесін жию"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index 2654765..5c04f88 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"មានបញ្ហា​ពាក់ព័ន្ធនឹង​កាមេរ៉ាឬ?\nចុចដើម្បី​ដោះស្រាយ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"មិនបាន​ដោះស្រាយ​បញ្ហានេះទេឬ?\nចុចដើម្បី​ត្រឡប់"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"មិនមាន​បញ្ហាពាក់ព័ន្ធនឹង​កាមេរ៉ាទេឬ? ចុចដើម្បី​ច្រានចោល។"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"កម្មវិធីមួយចំនួនដំណើរការបានប្រសើរបំផុតក្នុងទិសដៅបញ្ឈរ"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"សាកល្បងជម្រើសមួយក្នុងចំណោមទាំងនេះ ដើម្បីទទួលបានអត្ថប្រយោជន៍ច្រើនបំផុតពីកន្លែងទំនេររបស់អ្នក"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"បង្វិលឧបករណ៍របស់អ្នក ដើម្បីចូលប្រើអេក្រង់ពេញ"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ចុចពីរដងនៅជាប់កម្មវិធីណាមួយ ដើម្បីប្ដូរទីតាំងកម្មវិធីនោះ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"យល់ហើយ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-km/strings_tv.xml b/libs/WindowManager/Shell/res/values-km/strings_tv.xml
index e831516..86bad27 100644
--- a/libs/WindowManager/Shell/res/values-km/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"បិទ PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ពេញអេក្រង់"</string>
     <string name="pip_move" msgid="1544227837964635439">"ផ្លាស់ទី PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"ពង្រីក PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"បង្រួម PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 6edbf13..e91383c 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿವೆಯೇ?\nಮರುಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ಅದನ್ನು ಸರಿಪಡಿಸಲಿಲ್ಲವೇ?\nಹಿಂತಿರುಗಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿಲ್ಲವೇ? ವಜಾಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ಕೆಲವು ಆ್ಯಪ್‌ಗಳು ಪೋರ್ಟ್ರೇಟ್ ಮೋಡ್‌ನಲ್ಲಿ ಅತ್ಯುತ್ತಮವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ನಿಮ್ಮ ಸ್ಥಳಾವಕಾಶದ ಅತಿಹೆಚ್ಚು ಪ್ರಯೋಜನ ಪಡೆಯಲು ಈ ಆಯ್ಕೆಗಳಲ್ಲಿ ಒಂದನ್ನು ಬಳಸಿ ನೋಡಿ"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ಗೆ ಹೋಗಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ತಿರುಗಿಸಿ"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ಆ್ಯಪ್ ಒಂದರ ಸ್ಥಾನವನ್ನು ಬದಲಾಯಿಸಲು ಅದರ ಪಕ್ಕದಲ್ಲಿ ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ಸರಿ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
index 305ef66..3fbfdaa 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP ಮುಚ್ಚಿ"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ಪೂರ್ಣ ಪರದೆ"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP ಅನ್ನು ಸರಿಸಿ"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವನ್ನು ವಿಸ್ತರಿಸಿ"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"ಚಿತ್ರದಲ್ಲಿ ಚಿತ್ರವನ್ನು ಕುಗ್ಗಿಸಿ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 1f8d0b0..104ba3f 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"카메라 문제가 있나요?\n해결하려면 탭하세요."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"일부 앱은 세로 모드에서 가장 잘 작동함"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"공간을 최대한 이용할 수 있도록 이 옵션 중 하나를 시도해 보세요."</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"전체 화면 모드로 전환하려면 기기를 회전하세요."</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"앱 위치를 조정하려면 앱 옆을 두 번 탭하세요."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"확인"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
index 76b0adf..fa8c8980 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP 닫기"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"전체화면"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP 이동"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP 펼치기"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP 접기"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 81eb2d7..8203622 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада маселелер келип чыктыбы?\nОңдоо үчүн таптаңыз"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Оңдолгон жокпу?\nАртка кайтаруу үчүн таптаңыз"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада маселе жокпу? Этибарга албоо үчүн таптаңыз."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Айрым колдонмолорду тигинен иштетүү туура болот"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Иш чөйрөсүнүн бардык мүмкүнчүлүктөрүн пайдалануу үчүн бул параметрлердин бирин колдонуп көрүңүз"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Толук экран режимине өтүү үчүн түзмөктү буруңуз"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Колдонмонун ракурсун өзгөртүү үчүн анын тушуна эки жолу басыңыз"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Түшүндүм"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
index 57b955a..6e2b810 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP\'ти жабуу"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Толук экран"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP\'ти жылдыруу"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP\'ти жайып көрсөтүү"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP\'ти жыйыштыруу"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 3252130..2439678 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ?\nແຕະເພື່ອປັບໃໝ່"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ບໍ່ໄດ້ແກ້ໄຂມັນບໍ?\nແຕະເພື່ອແປງກັບຄືນ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ບໍ່ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ? ແຕະເພື່ອ​ປິດ​ໄວ້."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ແອັບບາງຢ່າງເຮັດວຽກໄດ້ດີທີ່ສຸດໃນໂໝດລວງຕັ້ງ"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ໃຫ້ລອງຕົວເລືອກໃດໜຶ່ງເຫຼົ່ານີ້ເພື່ອໃຊ້ປະໂຫຍດຈາກພື້ນທີ່ຂອງທ່ານໃຫ້ໄດ້ສູງສຸດ"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ໝຸນອຸປະກອນຂອງທ່ານເພື່ອໃຊ້ແບບເຕັມຈໍ"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ແຕະສອງເທື່ອໃສ່ຖັດຈາກແອັບໃດໜຶ່ງເພື່ອຈັດຕຳແໜ່ງຂອງມັນຄືນໃໝ່"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ເຂົ້າໃຈແລ້ວ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
index cbea84e..3d4505d 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"ປິດ PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ເຕັມໜ້າຈໍ"</string>
     <string name="pip_move" msgid="1544227837964635439">"ຍ້າຍ PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"ຂະຫຍາຍ PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"ຫຍໍ້ PIP ລົງ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 70654c7..e2ae643 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Iškilo problemų dėl kameros?\nPalieskite, kad pritaikytumėte iš naujo"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepavyko pataisyti?\nPalieskite, kad grąžintumėte"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Kai kurios programos geriausiai veikia stačiuoju režimu"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Pabandykite naudoti vieną iš šių parinkčių, kad išnaudotumėte visą vietą"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pasukite įrenginį, kad įjungtumėte viso ekrano režimą"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dukart palieskite šalia programos, kad pakeistumėte jos poziciją"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Supratau"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings_tv.xml b/libs/WindowManager/Shell/res/values-lt/strings_tv.xml
index 81716a6..f907055 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Uždaryti PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Visas ekranas"</string>
     <string name="pip_move" msgid="1544227837964635439">"Perkelti PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Iškleisti PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Sutraukti PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 74d1b3f..a77160b 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Vai ir problēmas ar kameru?\nPieskarieties, lai tās novērstu."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Dažas lietotnes vislabāk darbojas portreta režīmā"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Izmēģiniet vienu no šīm iespējām, lai efektīvi izmantotu pieejamo vietu"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Pagrieziet ierīci, lai aktivizētu pilnekrāna režīmu"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Veiciet dubultskārienu blakus lietotnei, lai manītu tās pozīciju"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Labi"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
index 5295cd2..04d9409 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Aizvērt PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pilnekrāna režīms"</string>
     <string name="pip_move" msgid="1544227837964635439">"Pārvietot attēlu attēlā"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Izvērst “Attēls attēlā” logu"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Sakļaut “Attēls attēlā” logu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index be6ed4d..bac0c9e 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми со камерата?\nДопрете за да се совпадне повторно"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не се поправи?\nДопрете за враќање"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нема проблеми со камерата? Допрете за отфрлање."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Некои апликации најдобро работат во режим на портрет"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Испробајте една од опцииве за да го извлечете максимумот од вашиот простор"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ротирајте го уредот за да отворите на цел екран"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Допрете двапати до некоја апликација за да ја преместите"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Сфатив"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings_tv.xml b/libs/WindowManager/Shell/res/values-mk/strings_tv.xml
index fa48a6c..e9ee1388 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Затвори PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Цел екран"</string>
     <string name="pip_move" msgid="1544227837964635439">"Премести PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Прошири ја сликата во слика"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Собери ја сликата во слика"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 14a341b..de0f837 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ക്യാമറ പ്രശ്നങ്ങളുണ്ടോ?\nശരിയാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"അത് പരിഹരിച്ചില്ലേ?\nപുനഃസ്ഥാപിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ക്യാമറാ പ്രശ്നങ്ങളൊന്നുമില്ലേ? നിരസിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ചില ആപ്പുകൾ പോർട്രെയ്റ്റിൽ മികച്ച രീതിയിൽ പ്രവർത്തിക്കുന്നു"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"നിങ്ങളുടെ ഇടം പരമാവധി പ്രയോജനപ്പെടുത്താൻ ഈ ഓപ്ഷനുകളിലൊന്ന് പരീക്ഷിക്കുക"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറാൻ ഈ ഉപകരണം റൊട്ടേറ്റ് ചെയ്യുക"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ഒരു ആപ്പിന്റെ സ്ഥാനം മാറ്റാൻ, അതിന് തൊട്ടടുത്ത് ഡബിൾ ടാപ്പ് ചെയ്യുക"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"മനസ്സിലായി"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings_tv.xml b/libs/WindowManager/Shell/res/values-ml/strings_tv.xml
index 5333757..1ed6b6e 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP അടയ്ക്കുക"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"പൂര്‍ണ്ണ സ്ക്രീന്‍"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP നീക്കുക"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP വികസിപ്പിക്കുക"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP ചുരുക്കുക"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index b59f282..1205306 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерын асуудал гарсан уу?\nДахин тааруулахын тулд товшино уу"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Үүнийг засаагүй юу?\nБуцаахын тулд товшино уу"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерын асуудал байхгүй юу? Хаахын тулд товшино уу."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Зарим апп нь босоо чиглэлд хамгийн сайн ажилладаг"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Орон зайгаа сайтар ашиглахын тулд эдгээр сонголтуудын аль нэгийг туршиж үзээрэй"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Төхөөрөмжөө бүтэн дэлгэцээр үзэхийн тулд эргүүлнэ"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Аппыг дахин байрлуулахын тулд хажууд нь хоёр товшино"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ойлголоо"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings_tv.xml b/libs/WindowManager/Shell/res/values-mn/strings_tv.xml
index ca1d27f..d4a6942 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP-г хаах"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Бүтэн дэлгэц"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP-г зөөх"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP-г дэлгэх"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP-г хураах"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 3d2d6a3..c91d06f 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"कॅमेराशी संबंधित काही समस्या आहेत का?\nपुन्हा फिट करण्यासाठी टॅप करा"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"निराकरण झाले नाही?\nरिव्हर्ट करण्यासाठी कृपया टॅप करा"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"कॅमेराशी संबंधित कोणत्याही समस्या नाहीत का? डिसमिस करण्‍यासाठी टॅप करा."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"काही ॲप्स पोर्ट्रेटमध्ये सर्वोत्तम काम करतात"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"तुमच्या स्पेसचा पुरेपूर वापर करण्यासाठी, यांपैकी एक पर्याय वापरून पहा"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"फुल स्क्रीन करण्यासाठी, तुमचे डिव्हाइस फिरवा"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ॲपची स्थिती पुन्हा बदलण्यासाठी, त्याच्या शेजारी दोनदा टॅप करा"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"समजले"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
index 212bd21..940f983 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP बंद करा"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"फुल स्क्रीन"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP हलवा"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP चा विस्तार करा"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP कोलॅप्स करा"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 4e9a7e9..652a991 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Isu kamera?\nKetik untuk memuatkan semula"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Isu tidak dibetulkan?\nKetik untuk kembali"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tiada isu kamera? Ketik untuk mengetepikan."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sesetengah apl berfungsi paling baik dalam mod potret"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Cuba salah satu daripada pilihan ini untuk memanfaatkan ruang anda sepenuhnya"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Putar peranti anda untuk beralih ke skrin penuh"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Ketik dua kali bersebelahan apl untuk menempatkan semula apl"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings_tv.xml b/libs/WindowManager/Shell/res/values-ms/strings_tv.xml
index ce29126..f4b180c 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Tutup PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Skrin penuh"</string>
     <string name="pip_move" msgid="1544227837964635439">"Alihkan PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Kembangkan PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Kuncupkan PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 449e502..15d182c 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ကင်မရာပြဿနာလား။\nပြင်ဆင်ရန် တို့ပါ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ကောင်းမသွားဘူးလား။\nပြန်ပြောင်းရန် တို့ပါ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ကင်မရာပြဿနာ မရှိဘူးလား။ ပယ်ရန် တို့ပါ။"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"အချို့အက်ပ်များသည် ဒေါင်လိုက်တွင် အကောင်းဆုံးလုပ်ဆောင်သည်"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"သင့်နေရာကို အကောင်းဆုံးအသုံးပြုနိုင်ရန် ဤရွေးစရာများထဲမှ တစ်ခုကို စမ်းကြည့်ပါ"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ဖန်သားပြင်အပြည့်လုပ်ရန် သင့်စက်ကို လှည့်နိုင်သည်"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"အက်ပ်နေရာပြန်ချရန် ၎င်းဘေးတွင် နှစ်ချက်တို့နိုင်သည်"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ရပြီ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-my/strings_tv.xml b/libs/WindowManager/Shell/res/values-my/strings_tv.xml
index 4847742..4b2a5ec 100644
--- a/libs/WindowManager/Shell/res/values-my/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP ကိုပိတ်ပါ"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"မျက်နှာပြင် အပြည့်"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP ရွှေ့ရန်"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP ကို ချဲ့ရန်"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP ကို လျှော့ပြပါ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 2172cc5..9fd42b2 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Har du kameraproblemer?\nTrykk for å tilpasse"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ble ikke problemet løst?\nTrykk for å gå tilbake"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen kameraproblemer? Trykk for å lukke."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Noen apper fungerer best i stående format"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Prøv et av disse alternativene for å få mest mulig ut av plassen din"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Roter enheten for å starte fullskjerm"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dobbelttrykk ved siden av en app for å flytte den"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Greit"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
index 7cef11c..be74eeb 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Lukk PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Fullskjerm"</string>
     <string name="pip_move" msgid="1544227837964635439">"Flytt BIB"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Vis BIB"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Skjul BIB"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index ff01dcd..8dfec88 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"क्यामेरासम्बन्धी समस्या देखियो?\nसमस्या हल गर्न ट्याप गर्नुहोस्"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"समस्या हल भएन?\nपहिलेको जस्तै बनाउन ट्याप गर्नुहोस्"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्यामेरासम्बन्धी कुनै पनि समस्या छैन? खारेज गर्न ट्याप गर्नुहोस्।"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"केही एपहरूले पोर्ट्रेटमा राम्रोसँग काम गर्छन्"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"तपाईं स्क्रिनको अधिकतम ठाउँ प्रयोग गर्न चाहनुहुन्छ भने यीमध्ये कुनै विकल्प प्रयोग गरी हेर्नुहोस्"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"तपाईं फुल स्क्रिन मोड हेर्न चाहनुहुन्छ भने आफ्नो डिभाइस रोटेट गर्नुहोस्"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"तपाईं जुन एपको स्थिति मिलाउन चाहनुहुन्छ सोही एपको छेउमा डबल ट्याप गर्नुहोस्"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"बुझेँ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings_tv.xml b/libs/WindowManager/Shell/res/values-ne/strings_tv.xml
index 684d114..a36cad6 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP लाई बन्द गर्नुहोस्"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"फुल स्क्रिन"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP सार्नुहोस्"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP विन्डो एक्स्पान्ड गर्नु…"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP विन्डो कोल्याप्स गर्नुहोस्"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 428cb3f..8468b04 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Cameraproblemen?\nTik om opnieuw passend te maken."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Is dit geen oplossing?\nTik om terug te zetten."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen cameraproblemen? Tik om te sluiten."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Sommige apps werken het best in de staande stand"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Probeer een van deze opties om optimaal gebruik te maken van je ruimte"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Draai je apparaat om naar volledig scherm te schakelen"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dubbeltik naast een app om deze opnieuw te positioneren"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings_tv.xml b/libs/WindowManager/Shell/res/values-nl/strings_tv.xml
index 8562517..eb7ec60 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP sluiten"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Volledig scherm"</string>
     <string name="pip_move" msgid="1544227837964635439">"SIS verplaatsen"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"SIS uitvouwen"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"SIS samenvouwen"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index f9668a1..a8d8448 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"କ୍ୟାମେରାରେ ସମସ୍ୟା ଅଛି?\nପୁଣି ଫିଟ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ଏହାର ସମାଧାନ ହୋଇନାହିଁ?\nଫେରିଯିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"କ୍ୟାମେରାରେ କିଛି ସମସ୍ୟା ନାହିଁ? ଖାରଜ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"କିଛି ଆପ ପୋର୍ଟ୍ରେଟରେ ସବୁଠାରୁ ଭଲ କାମ କରେ"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ଆପଣଙ୍କ ସ୍ପେସରୁ ଅଧିକ ଲାଭ ପାଇବାକୁ ଏହି ବିକଳ୍ପଗୁଡ଼ିକ ମଧ୍ୟରୁ ଗୋଟିଏ ବ୍ୟବହାର କରି ଦେଖନ୍ତୁ"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ପୂର୍ଣ୍ଣ-ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଆପଣଙ୍କ ଡିଭାଇସକୁ ରୋଟେଟ କରନ୍ତୁ"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ଏକ ଆପକୁ ରିପୋଜିସନ କରିବା ପାଇଁ ଏହା ପାଖରେ ଦୁଇଥର-ଟାପ କରନ୍ତୁ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ବୁଝିଗଲି"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-or/strings_tv.xml b/libs/WindowManager/Shell/res/values-or/strings_tv.xml
index f8bc016..e48199f 100644
--- a/libs/WindowManager/Shell/res/values-or/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍‍"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIPକୁ ମୁଭ କରନ୍ତୁ"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIPକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIPକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 7132597..f99176c 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਸਮੱਸਿਆਵਾਂ ਹਨ?\nਮੁੜ-ਫਿੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ਕੀ ਇਹ ਠੀਕ ਨਹੀਂ ਹੋਈ?\nਵਾਪਸ ਉਹੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਕੋਈ ਸਮੱਸਿਆ ਨਹੀਂ ਹੈ? ਖਾਰਜ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"ਕੁਝ ਐਪਾਂ ਪੋਰਟਰੇਟ ਵਿੱਚ ਬਿਹਤਰ ਕੰਮ ਕਰਦੀਆਂ ਹਨ"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ਆਪਣੀ ਜਗ੍ਹਾ ਦਾ ਵੱਧ ਤੋਂ ਵੱਧ ਲਾਹਾ ਲੈਣ ਲਈ ਇਨ੍ਹਾਂ ਵਿਕਲਪਾਂ ਵਿੱਚੋਂ ਕੋਈ ਇੱਕ ਵਰਤ ਕੇ ਦੇਖੋ"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ਪੂਰੀ-ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਣ ਲਈ ਆਪਣੇ ਡੀਵਾਈਸ ਨੂੰ ਘੁਮਾਓ"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ਕਿਸੇ ਐਪ ਦੀ ਜਗ੍ਹਾ ਬਦਲਣ ਲਈ ਉਸ ਦੇ ਅੱਗੇ ਡਬਲ ਟੈਪ ਕਰੋ"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ਸਮਝ ਲਿਆ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings_tv.xml b/libs/WindowManager/Shell/res/values-pa/strings_tv.xml
index 1667e5f..891107e 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP ਬੰਦ ਕਰੋ"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP ਨੂੰ ਲਿਜਾਓ"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP ਦਾ ਵਿਸਤਾਰ ਕਰੋ"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP ਨੂੰ ਸਮੇਟੋ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index f7f97ef..f2147c0 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemy z aparatem?\nKliknij, aby dopasować"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Naprawa się nie udała?\nKliknij, aby cofnąć"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Brak problemów z aparatem? Kliknij, aby zamknąć"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Niektóre aplikacje działają najlepiej w orientacji pionowej"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Wypróbuj jedną z tych opcji, aby jak najlepiej wykorzystać miejsce"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Obróć urządzenie, aby przejść do pełnego ekranu"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Kliknij dwukrotnie obok aplikacji, aby ją przenieść"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
index 28bf66a..7b5d08a 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Zamknij PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Pełny ekran"</string>
     <string name="pip_move" msgid="1544227837964635439">"Przenieś PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Rozwiń PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Zwiń PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index a3d2ab0..2efc554 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Alguns apps funcionam melhor em modo retrato"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Tente uma destas opções para aproveitar seu espaço ao máximo"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gire o dispositivo para entrar no modo de tela cheia"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes ao lado de um app para reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml
index 27626b8..b669f16 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Tela cheia"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mover picture-in-picture"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Abrir picture-in-picture"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Fechar picture-in-picture"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 86872c8..c68a693 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmara?\nToque aqui para reajustar"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Algumas apps funcionam melhor no modo vertical"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Experimente uma destas opções para aproveitar ao máximo o seu espaço"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rode o dispositivo para ficar em ecrã inteiro"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes junto a uma app para a reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml
index a2010ce..6c1fa59 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Ecrã inteiro"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mover Ecrã no ecrã"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Expandir Ecrã no ecrã"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Reduzir Ecrã no ecrã"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index a3d2ab0..2efc554 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmera?\nToque para ajustar o enquadramento"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"O problema não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Não tem problemas com a câmera? Toque para dispensar."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Alguns apps funcionam melhor em modo retrato"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Tente uma destas opções para aproveitar seu espaço ao máximo"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Gire o dispositivo para entrar no modo de tela cheia"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Toque duas vezes ao lado de um app para reposicionar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Entendi"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings_tv.xml b/libs/WindowManager/Shell/res/values-pt/strings_tv.xml
index 27626b8..b669f16 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Fechar PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Tela cheia"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mover picture-in-picture"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Abrir picture-in-picture"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Fechar picture-in-picture"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 5448e45..804d34f 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Aveți probleme cu camera foto?\nAtingeți pentru a reîncadra"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ați remediat problema?\nAtingeți pentru a reveni"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu aveți probleme cu camera foto? Atingeți pentru a închide."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Unele aplicații funcționează cel mai bine în orientarea portret"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Încercați una dintre aceste opțiuni pentru a profita din plin de spațiu"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotiți dispozitivul pentru a trece în modul ecran complet"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Atingeți de două ori lângă o aplicație pentru a o repoziționa"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
index 18e29a6..8ecf8c5 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Închideți PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Ecran complet"</string>
     <string name="pip_move" msgid="1544227837964635439">"Mutați fereastra PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Extindeți fereastra PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Restrângeți fereastra PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 64e74a2..95bf1cf 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблемы с камерой?\nНажмите, чтобы исправить."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не помогло?\nНажмите, чтобы отменить изменения."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нет проблем с камерой? Нажмите, чтобы закрыть."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Некоторые приложения лучше работают в вертикальном режиме"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Чтобы эффективно использовать экранное пространство, выполните одно из следующих действий:"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Чтобы перейти в полноэкранный режим, поверните устройство."</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Чтобы переместить приложение, нажмите на него дважды."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОК"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings_tv.xml b/libs/WindowManager/Shell/res/values-ru/strings_tv.xml
index d119240..19f7a00 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"\"Кадр в кадре\" – выйти"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Во весь экран"</string>
     <string name="pip_move" msgid="1544227837964635439">"Переместить PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Развернуть PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Свернуть PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 3cdaa72..23dd65a 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"කැමරා ගැටලුද?\nයළි සවි කිරීමට තට්ටු කරන්න"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"එය විසඳුවේ නැතිද?\nප්‍රතිවර්තනය කිරීමට තට්ටු කරන්න"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"කැමරා ගැටලු නොමැතිද? ඉවත දැමීමට තට්ටු කරන්න"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"සමහර යෙදුම් ප්‍රතිමූර්තිය තුළ හොඳින්ම ක්‍රියා කරයි"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ඔබගේ ඉඩෙන් උපරිම ප්‍රයෝජන ගැනීමට මෙම විකල්පවලින් එකක් උත්සාහ කරන්න"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"සම්පූර්ණ තිරයට යාමට ඔබගේ උපාංගය කරකවන්න"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"එය නැවත ස්ථානගත කිරීමට යෙදුමකට යාබදව දෙවරක් තට්ටු කරන්න"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"තේරුණා"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-si/strings_tv.xml b/libs/WindowManager/Shell/res/values-si/strings_tv.xml
index 86769b6..7444369 100644
--- a/libs/WindowManager/Shell/res/values-si/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP වසන්න"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"සම්පූර්ණ තිරය"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP ගෙන යන්න"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP දිග හරින්න"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP හකුළන්න"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index daa2021..a231cac 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s kamerou?\nKlepnutím znova upravte."</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nevyriešilo sa to?\nKlepnutím sa vráťte."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemáte problémy s kamerou? Klepnutím zatvoríte."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Niektoré aplikácie fungujú najlepšie v režime na výšku"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Vyskúšajte jednu z týchto možností a využívajte svoj priestor naplno"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Otočením zariadenia prejdete do režimu celej obrazovky"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvojitým klepnutím vedľa aplikácie zmeníte jej pozíciu"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Dobre"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings_tv.xml b/libs/WindowManager/Shell/res/values-sk/strings_tv.xml
index 6f6ccb7..1a8edf1 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Zavrieť režim PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Celá obrazovka"</string>
     <string name="pip_move" msgid="1544227837964635439">"Presunúť obraz v obraze"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Rozbaliť obraz v obraze"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Zbaliť obraz v obraze"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index b4c7b95..adeaae97 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Težave s fotoaparatom?\nDotaknite se za vnovično prilagoditev"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"To ni odpravilo težave?\nDotaknite se za povrnitev"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nimate težav s fotoaparatom? Dotaknite se za opustitev."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Nekatere aplikacije najbolje delujejo v navpični postavitvi"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Poskusite eno od teh možnosti za čim boljši izkoristek prostora"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Če želite preklopiti v celozaslonski način, zasukajte napravo."</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Dvakrat se dotaknite ob aplikaciji, če jo želite prestaviti."</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"V redu"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
index 837794a..c4c04c2 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Zapri način PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Celozaslonsko"</string>
     <string name="pip_move" msgid="1544227837964635439">"Premakni sliko v sliki"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Razširi sliko v sliki"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Strni sliko v sliki"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 5051351..2839b4b 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Ka probleme me kamerën?\nTrokit për ta ripërshtatur"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nuk u rregullua?\nTrokit për ta rikthyer"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nuk ka probleme me kamerën? Trokit për ta shpërfillur."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Disa aplikacione funksionojnë më mirë në modalitetin vertikal"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Provo një nga këto opsione për ta shfrytëzuar sa më mirë hapësirën"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rrotullo ekranin për të kaluar në ekran të plotë"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Trokit dy herë pranë një aplikacioni për ta ripozicionuar"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"E kuptova"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
index 107870d0..2771b89 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Mbyll PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Ekrani i plotë"</string>
     <string name="pip_move" msgid="1544227837964635439">"Zhvendos PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Zgjero PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Palos PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 96bb48a..9db6b7c 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Имате проблема са камером?\nДодирните да бисте поново уклопили"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Неке апликације најбоље функционишу у усправном режиму"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Испробајте једну од ових опција да бисте на најбољи начин искористили простор"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Ротирајте уређај за приказ преко целог екрана"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Двапут додирните поред апликације да бисте променили њену позицију"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Важи"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
index ee5690b..3244030 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Затвори PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Цео екран"</string>
     <string name="pip_move" msgid="1544227837964635439">"Премести слику у слици"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Прошири слику у слици"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Скупи слику у слици"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 9fa5c19..f6bd554 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problem med kameran?\nTryck för att anpassa på nytt"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Löstes inte problemet?\nTryck för att återställa"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Inga problem med kameran? Tryck för att ignorera."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Vissa appar fungerar bäst i stående läge"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Testa med ett av dessa alternativ för att få ut mest möjliga av ytan"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Rotera skärmen för att gå över till helskärmsläge"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Tryck snabbt två gånger bredvid en app för att flytta den"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings_tv.xml b/libs/WindowManager/Shell/res/values-sv/strings_tv.xml
index 7355adf..842c805 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Stäng PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Helskärm"</string>
     <string name="pip_move" msgid="1544227837964635439">"Flytta BIB"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Utöka bild-i-bild"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Komprimera bild-i-bild"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 8c026f9..f6e55852 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Je, kuna hitilafu za kamera?\nGusa ili urekebishe"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Je, hakuna hitilafu za kamera? Gusa ili uondoe."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Baadhi ya programu hufanya kazi vizuri zaidi zikiwa wima"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Jaribu moja kati ya chaguo hizi ili utumie nafasi ya skrini yako kwa ufanisi"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zungusha kifaa chako ili uende kwenye hali ya skrini nzima"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Gusa mara mbili karibu na programu ili uihamishe"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Nimeelewa"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings_tv.xml b/libs/WindowManager/Shell/res/values-sw/strings_tv.xml
index 0ee2841..8728fd9 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Funga PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Skrini nzima"</string>
     <string name="pip_move" msgid="1544227837964635439">"Kuhamisha PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Panua PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Kunja PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index cb3d138..d8334ad 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"கேமரா தொடர்பான சிக்கல்களா?\nமீண்டும் பொருத்த தட்டவும்"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"சில ஆப்ஸ் \'போர்ட்ரெய்ட்டில்\' சிறப்பாகச் செயல்படும்"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ஸ்பேஸ்களிலிருந்து அதிகப் பலன்களைப் பெற இந்த விருப்பங்களில் ஒன்றைப் பயன்படுத்துங்கள்"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"முழுத்திரைக்குச் செல்ல உங்கள் சாதனத்தைச் சுழற்றவும்"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"ஆப்ஸை இடம் மாற்ற, ஆப்ஸுக்கு அடுத்து இருமுறை தட்டவும்"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"சரி"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings_tv.xml b/libs/WindowManager/Shell/res/values-ta/strings_tv.xml
index 8bcc43b..e325b1a 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIPஐ மூடு"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"முழுத்திரை"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIPபை நகர்த்து"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIPபை விரிவாக்கு"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIPபைச் சுருக்கு"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 7589e70..7330755 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"కెమెరా సమస్యలు ఉన్నాయా?\nరీఫిట్ చేయడానికి ట్యాప్ చేయండి"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"దాని సమస్యను పరిష్కరించలేదా?\nపూర్వస్థితికి మార్చడానికి ట్యాప్ చేయండి"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"కెమెరా సమస్యలు లేవా? తీసివేయడానికి ట్యాప్ చేయండి."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"కొన్ని యాప్‌లు పోర్ట్రెయిట్‌లో ఉత్తమంగా పని చేస్తాయి"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"మీ ప్రదేశాన్ని ఎక్కువగా ఉపయోగించుకోవడానికి ఈ ఆప్షన్‌లలో ఒకదాన్ని ట్రై చేయండి"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"ఫుల్ స్క్రీన్‌కు వెళ్లడానికి మీ పరికరాన్ని తిప్పండి"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"యాప్ స్థానాన్ని మార్చడానికి దాని పక్కన డబుల్-ట్యాప్ చేయండి"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"అర్థమైంది"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-te/strings_tv.xml b/libs/WindowManager/Shell/res/values-te/strings_tv.xml
index 6e80bd7..1381e67 100644
--- a/libs/WindowManager/Shell/res/values-te/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIPని మూసివేయి"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"ఫుల్-స్క్రీన్‌"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIPను తరలించండి"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIPని విస్తరించండి"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIPని కుదించండి"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-television/config.xml b/libs/WindowManager/Shell/res/values-television/config.xml
new file mode 100644
index 0000000..552048e
--- /dev/null
+++ b/libs/WindowManager/Shell/res/values-television/config.xml
@@ -0,0 +1,36 @@
+<?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.
+  -->
+
+<!-- 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">
+
+    <!-- The percentage of the screen width to use for the default width or height of
+         picture-in-picture windows. Regardless of the percent set here, calculated size will never
+         be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
+    <item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.2</item>
+
+    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">
+        24x24
+    </string>
+
+    <!-- The default gravity for the picture-in-picture window.
+         Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
+    <integer name="config_defaultPictureInPictureGravity">0x55</integer>
+</resources>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index d8a33ff..cfee8ea 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"หากพบปัญหากับกล้อง\nแตะเพื่อแก้ไข"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"หากไม่ได้แก้ไข\nแตะเพื่อเปลี่ยนกลับ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"หากไม่พบปัญหากับกล้อง แตะเพื่อปิด"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"บางแอปทำงานได้ดีที่สุดในแนวตั้ง"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"ลองใช้หนึ่งในตัวเลือกเหล่านี้เพื่อให้ได้ประโยชน์สูงสุดจากพื้นที่ว่าง"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"หมุนอุปกรณ์ให้แสดงเต็มหน้าจอ"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"แตะสองครั้งข้างแอปเพื่อเปลี่ยนตำแหน่ง"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"รับทราบ"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-th/strings_tv.xml b/libs/WindowManager/Shell/res/values-th/strings_tv.xml
index b6f6369..6f00018 100644
--- a/libs/WindowManager/Shell/res/values-th/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"ปิด PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"เต็มหน้าจอ"</string>
     <string name="pip_move" msgid="1544227837964635439">"ย้าย PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"ขยาย PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"ยุบ PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 35a58b3..eed624d 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"May mga isyu sa camera?\nI-tap para i-refit"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Hindi ito naayos?\nI-tap para i-revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Walang isyu sa camera? I-tap para i-dismiss."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"May ilang app na pinakamainam gamitin nang naka-portrait"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Subukan ang isa sa mga opsyong ito para masulit ang iyong space"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"I-rotate ang iyong device para mag-full screen"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Mag-double tap sa tabi ng isang app para iposisyon ito ulit"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings_tv.xml b/libs/WindowManager/Shell/res/values-tl/strings_tv.xml
index 71ca230..868b278 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Isara ang PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Full screen"</string>
     <string name="pip_move" msgid="1544227837964635439">"Ilipat ang PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"I-expand ang PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"I-collapse ang PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 8a9fb75..2b4a2d0 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kameranızda sorun mu var?\nDüzeltmek için dokunun"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kameranızda sorun yok mu? Kapatmak için dokunun."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Bazı uygulamalar dikey modda en iyi performansı gösterir"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Alanınızı en verimli şekilde kullanmak için bu seçeneklerden birini deneyin"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Tam ekrana geçmek için cihazınızı döndürün"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Yeniden konumlandırmak için uygulamanın yanına iki kez dokunun"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Anladım"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
index e6ae7f1..9ffad78 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"PIP\'yi kapat"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Tam ekran"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIP\'yi taşı"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP penceresini genişlet"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP penceresini daralt"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index aac9031..c3411a8 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми з камерою?\nНатисніть, щоб пристосувати"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблему не вирішено?\nНатисніть, щоб скасувати зміни"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немає проблем із камерою? Торкніться, щоб закрити."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Деякі додатки найкраще працюють у вертикальній орієнтації"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Щоб максимально ефективно використовувати місце на екрані, спробуйте виконати одну з наведених нижче дій"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Щоб перейти в повноекранний режим, поверніть пристрій"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Щоб перемістити додаток, двічі торкніться області поруч із ним"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"ОK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
index 97e1f09..24c1698 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Закрити PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"На весь екран"</string>
     <string name="pip_move" msgid="1544227837964635439">"Перемістити картинку в картинці"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Розгорнути картинку в картинці"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Згорнути картинку в картинці"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index e3bab32..a31c2be 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"کیمرے کے مسائل؟\nدوبارہ فٹ کرنے کیلئے تھپتھپائیں"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"یہ حل نہیں ہوا؟\nلوٹانے کیلئے تھپتھپائیں"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"کوئی کیمرے کا مسئلہ نہیں ہے؟ برخاست کرنے کیلئے تھپتھپائیں۔"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"کچھ ایپس پورٹریٹ میں بہترین کام کرتی ہیں"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"اپنی اسپیس کا زیادہ سے زیادہ فائدہ اٹھانے کے لیے ان اختیارات میں سے ایک کو آزمائیں"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"پوری اسکرین پر جانے کیلئے اپنا آلہ گھمائیں"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"کسی ایپ کی پوزیشن تبدیل کرنے کے لیے اس کے آگے دو بار تھپتھپائیں"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"سمجھ آ گئی"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings_tv.xml b/libs/WindowManager/Shell/res/values-ur/strings_tv.xml
index 1418570..c05729a 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"‏PIP بند کریں"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"فُل اسکرین"</string>
     <string name="pip_move" msgid="1544227837964635439">"‏PIP کو منتقل کریں"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"‏PIP کو پھیلائیں"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"‏PIP کو سکیڑیں"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 54ec89a..2e32225 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Kamera nosozmi?\nQayta moslash uchun bosing"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tuzatilmadimi?\nQaytarish uchun bosing"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera muammosizmi? Yopish uchun bosing."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Ayrim ilovalar tik holatda ishlashga eng mos"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Muhitdan yanada samarali foydalanish uchun quyidagilardan birini sinang"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Butun ekranda ochish uchun qurilmani buring"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Qayta joylash uchun keyingi ilova ustiga ikki marta bosing"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings_tv.xml b/libs/WindowManager/Shell/res/values-uz/strings_tv.xml
index 31c762e..43ab5ac 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Kadr ichida kadr – chiqish"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Butun ekran"</string>
     <string name="pip_move" msgid="1544227837964635439">"PIPni siljitish"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"PIP funksiyasini yoyish"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"PIP funksiyasini yopish"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index b683702..8f3cffe 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Có vấn đề với máy ảnh?\nHãy nhấn để sửa lỗi"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Không có vấn đề với máy ảnh? Hãy nhấn để đóng."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Một số ứng dụng hoạt động tốt nhất ở chế độ dọc"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Hãy thử một trong các tuỳ chọn sau để tận dụng không gian"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Xoay thiết bị để chuyển sang chế độ toàn màn hình"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Nhấn đúp vào bên cạnh ứng dụng để đặt lại vị trí"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings_tv.xml b/libs/WindowManager/Shell/res/values-vi/strings_tv.xml
index b46cd49..368280c 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Đóng PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Toàn màn hình"</string>
     <string name="pip_move" msgid="1544227837964635439">"Di chuyển PIP (Ảnh trong ảnh)"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Mở rộng PIP (Ảnh trong ảnh)"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Thu gọn PIP (Ảnh trong ảnh)"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index 811d860..19a9d37 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相机有问题?\n点按即可整修"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"没有解决此问题?\n点按即可恢复"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相机没有问题?点按即可忽略。"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"某些应用在纵向模式下才能发挥最佳效果"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"这些选项都有助于您最大限度地利用屏幕空间,不妨从中择一试试"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋转设备即可进入全屏模式"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在某个应用旁边连续点按两次,即可调整它的位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml
index b6fec63..e5d879a 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"关闭画中画"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"全屏"</string>
     <string name="pip_move" msgid="1544227837964635439">"移动画中画窗口"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"展开 PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"收起 PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 2a01714..0c40e96 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題?\n輕按即可修正"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"部分應用程式需要使用直向模式才能發揮最佳效果"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"請嘗試以下選項,充分運用螢幕的畫面空間"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋轉裝置方向即可進入全螢幕模式"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在應用程式旁輕按兩下即可調整位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
index b5d54cb..8ee5f11 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"關閉 PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"全螢幕"</string>
     <string name="pip_move" msgid="1544227837964635439">"移動畫中畫"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"展開畫中畫"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"收合畫中畫"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 292a439..8691352 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"相機有問題嗎?\n輕觸即可修正"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未修正問題嗎?\n輕觸即可還原"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機沒問題嗎?輕觸即可關閉。"</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"某些應用程式在直向模式下才能發揮最佳效果"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"請試試這裡的任一方式,以充分運用螢幕畫面的空間"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"旋轉裝置方向即可進入全螢幕模式"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"在應用程式旁輕觸兩下即可調整位置"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"我知道了"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
index 57db7a8..b23ecde 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"關閉子母畫面"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"全螢幕"</string>
     <string name="pip_move" msgid="1544227837964635439">"移動子母畫面"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"展開子母畫面"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"收合子母畫面"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 389eb08..44ffbc6 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -76,13 +76,9 @@
     <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Izinkinga zekhamera?\nThepha ukuze uyilinganise kabusha"</string>
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Akuyilungisanga?\nThepha ukuze ubuyele"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Azikho izinkinga zekhamera? Thepha ukuze ucashise."</string>
-    <!-- no translation found for letterbox_education_dialog_title (6688664582871779215) -->
-    <skip />
-    <!-- no translation found for letterbox_education_dialog_subtext (4853542518367719562) -->
-    <skip />
-    <!-- no translation found for letterbox_education_screen_rotation_text (5085786687366339027) -->
-    <skip />
-    <!-- no translation found for letterbox_education_reposition_text (1068293354123934727) -->
-    <skip />
+    <string name="letterbox_education_dialog_title" msgid="6688664582871779215">"Amanye ama-app asebenza ngcono uma eme ngobude"</string>
+    <string name="letterbox_education_dialog_subtext" msgid="4853542518367719562">"Zama enye yalezi zinketho ukuze usebenzise isikhala sakho ngokugcwele"</string>
+    <string name="letterbox_education_screen_rotation_text" msgid="5085786687366339027">"Zungezisa idivayisi yakho ukuze uye esikrinini esigcwele"</string>
+    <string name="letterbox_education_reposition_text" msgid="1068293354123934727">"Thepha kabili eduze kwe-app ukuze uyimise kabusha"</string>
     <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ngiyezwa"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings_tv.xml b/libs/WindowManager/Shell/res/values-zu/strings_tv.xml
index 646a488..b14ee99 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings_tv.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings_tv.xml
@@ -22,4 +22,6 @@
     <string name="pip_close" msgid="9135220303720555525">"Vala i-PIP"</string>
     <string name="pip_fullscreen" msgid="7278047353591302554">"Iskrini esigcwele"</string>
     <string name="pip_move" msgid="1544227837964635439">"Hambisa i-PIP"</string>
+    <string name="pip_expand" msgid="7605396312689038178">"Nweba i-PIP"</string>
+    <string name="pip_collapse" msgid="5732233773786896094">"Goqa i-PIP"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 1b8032b..d416c06 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -70,4 +70,30 @@
 
     <!-- Animation duration when exit starting window: reveal app -->
     <integer name="starting_window_app_reveal_anim_duration">266</integer>
+
+    <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
+         These values are in DPs and will be converted to pixel sizes internally. -->
+    <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">
+        16x16
+    </string>
+
+    <!-- The percentage of the screen width to use for the default width or height of
+         picture-in-picture windows. Regardless of the percent set here, calculated size will never
+         be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
+    <item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.23</item>
+
+    <!-- The default aspect ratio for picture-in-picture windows. -->
+    <item name="config_pictureInPictureDefaultAspectRatio" format="float" type="dimen">
+        1.777778
+    </item>
+
+    <!-- This is the limit for the max and min aspect ratio (1 / this value) at which the min size
+         will be used instead of an adaptive size based loosely on area. -->
+    <item name="config_pictureInPictureAspectRatioLimitForMinSize" format="float" type="dimen">
+        1.777778
+    </item>
+
+    <!-- The default gravity for the picture-in-picture window.
+         Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->
+    <integer name="config_defaultPictureInPictureGravity">0x55</integer>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 8a8231d..ad38975 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -18,8 +18,8 @@
     <dimen name="dismiss_circle_size">96dp</dimen>
     <dimen name="dismiss_circle_small">60dp</dimen>
 
-    <!-- The height of the gradient indicating the dismiss edge when moving a PIP. -->
-    <dimen name="floating_dismiss_gradient_height">250dp</dimen>
+    <!-- The height of the gradient indicating the dismiss edge when moving a PIP or bubble. -->
+    <dimen name="floating_dismiss_gradient_height">548dp</dimen>
 
     <!-- The padding around a PiP actions. -->
     <dimen name="pip_action_padding">16dp</dimen>
@@ -129,6 +129,9 @@
     <dimen name="bubble_dismiss_encircle_size">52dp</dimen>
     <!-- Padding around the view displayed when the bubble is expanded -->
     <dimen name="bubble_expanded_view_padding">16dp</dimen>
+    <!-- Padding for the edge of the expanded view that is closest to the edge of the screen used
+         when displaying in landscape on a large screen. -->
+    <dimen name="bubble_expanded_view_largescreen_landscape_padding">128dp</dimen>
     <!-- This should be at least the size of bubble_expanded_view_padding; it is used to include
          a slight touch slop around the expanded view. -->
     <dimen name="bubble_expanded_view_slop">8dp</dimen>
@@ -136,16 +139,21 @@
          If this value changes then R.dimen.bubble_expanded_view_min_height in CtsVerifier
          should also be updated. -->
     <dimen name="bubble_expanded_default_height">180dp</dimen>
-    <!-- On large screens the width of the expanded view is restricted to this size. -->
-    <dimen name="bubble_expanded_view_phone_landscape_overflow_width">412dp</dimen>
+    <!-- The width of the overflow view on large screens or in landscape on phone. -->
+    <dimen name="bubble_expanded_view_overflow_width">380dp</dimen>
     <!-- Inset to apply to the icon in the overflow button. -->
     <dimen name="bubble_overflow_icon_inset">30dp</dimen>
     <!-- Default (and minimum) height of bubble overflow -->
     <dimen name="bubble_overflow_height">480dp</dimen>
     <!-- Bubble overflow padding when there are no bubbles  -->
     <dimen name="bubble_overflow_empty_state_padding">16dp</dimen>
-    <!-- Padding of container for overflow bubbles -->
-    <dimen name="bubble_overflow_padding">15dp</dimen>
+    <!-- Horizontal padding of the overflow container. Total desired padding is 16dp but the items
+         already have 5dp added to each side. -->
+    <dimen name="bubble_overflow_container_padding_horizontal">11dp</dimen>
+    <!-- Horizontal padding between items in the overflow view, half of the desired amount. -->
+    <dimen name="bubble_overflow_item_padding_horizontal">5dp</dimen>
+    <!-- Vertical padding between items in the overflow view, half the desired amount. -->
+    <dimen name="bubble_overflow_item_padding_vertical">16dp</dimen>
     <!-- Padding of label for bubble overflow view -->
     <dimen name="bubble_overflow_text_padding">7dp</dimen>
     <!-- Height of bubble overflow empty state illustration -->
@@ -251,4 +259,14 @@
 
     <!-- The distance of the shift icon when early exit starting window. -->
     <dimen name="starting_surface_early_exit_icon_distance">32dp</dimen>
+
+    <!-- The default minimal size of a PiP task, in both dimensions. -->
+    <dimen name="default_minimal_size_pip_resizable_task">108dp</dimen>
+
+    <!--
+      The overridable minimal size of a PiP task, in both dimensions.
+      Different from default_minimal_size_pip_resizable_task, this is to limit the dimension
+      when the pinned stack size is overridden by app via minWidth/minHeight.
+    -->
+    <dimen name="overridable_minimal_size_pip_resizable_task">48dp</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/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 91ea436..3f8343a 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) {};
     }
 
@@ -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 9b41468..8d5fdfb 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,6 +52,9 @@
  */
 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";
     private static final int PROGRESS_THRESHOLD = SystemProperties
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 241f1a7..d0138a4 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
@@ -47,7 +47,10 @@
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
@@ -131,6 +134,10 @@
     public static final String RIGHT_POSITION = "Right";
     public static final String BOTTOM_POSITION = "Bottom";
 
+    // Should match with PhoneWindowManager
+    private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
+    private static final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
+
     private final Context mContext;
     private final BubblesImpl mImpl = new BubblesImpl();
     private Bubbles.BubbleExpandListener mExpandListener;
@@ -675,6 +682,7 @@
 
         try {
             mAddedToWindowManager = true;
+            registerBroadcastReceiver();
             mBubbleData.getOverflow().initialize(this);
             mWindowManager.addView(mStackView, mWmLayoutParams);
             mStackView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
@@ -717,6 +725,7 @@
 
         try {
             mAddedToWindowManager = false;
+            mContext.unregisterReceiver(mBroadcastReceiver);
             if (mStackView != null) {
                 mWindowManager.removeView(mStackView);
                 mBubbleData.getOverflow().cleanUpExpandedState();
@@ -730,11 +739,34 @@
         }
     }
 
+    private void registerBroadcastReceiver() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        filter.addAction(Intent.ACTION_SCREEN_OFF);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!isStackExpanded()) return; // Nothing to do
+
+            String action = intent.getAction();
+            String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
+            if ((Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
+                    && SYSTEM_DIALOG_REASON_GESTURE_NAV.equals(reason))
+                    || Intent.ACTION_SCREEN_OFF.equals(action)) {
+                mMainExecutor.execute(() -> collapseStack());
+            }
+        }
+    };
+
     /**
      * Called by the BubbleStackView and whenever all bubbles have animated out, and none have been
      * added in the meantime.
      */
-    void onAllBubblesAnimatedOut() {
+    @VisibleForTesting
+    public void onAllBubblesAnimatedOut() {
         if (mStackView != null) {
             mStackView.setVisibility(INVISIBLE);
             removeFromWindowManagerMaybe();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index 5e9d97f..fcd0ed7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -20,11 +20,13 @@
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Color;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.TypedValue;
@@ -58,6 +60,8 @@
     private TextView mEmptyStateTitle;
     private TextView mEmptyStateSubtitle;
     private ImageView mEmptyStateImage;
+    private int mHorizontalMargin;
+    private int mVerticalMargin;
     private BubbleController mController;
     private BubbleOverflowAdapter mAdapter;
     private RecyclerView mRecyclerView;
@@ -77,12 +81,6 @@
             super(context, columns);
         }
 
-//        @Override
-//        public boolean canScrollVertically() {
-//            // TODO (b/162006693): this should be based on items in the list & available height
-//            return true;
-//        }
-
         @Override
         public int getColumnCountForAccessibility(RecyclerView.Recycler recycler,
                 RecyclerView.State state) {
@@ -98,6 +96,17 @@
         }
     }
 
+    private class OverflowItemDecoration extends RecyclerView.ItemDecoration {
+        @Override
+        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
+                @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
+            outRect.left = mHorizontalMargin;
+            outRect.top = mVerticalMargin;
+            outRect.right = mHorizontalMargin;
+            outRect.bottom = mVerticalMargin;
+        }
+    }
+
     public BubbleOverflowContainerView(Context context) {
         this(context, null);
     }
@@ -161,6 +170,9 @@
         final int columns = res.getInteger(R.integer.bubbles_overflow_columns);
         mRecyclerView.setLayoutManager(
                 new OverflowGridLayoutManager(getContext(), columns));
+        if (mRecyclerView.getItemDecorationCount() == 0) {
+            mRecyclerView.addItemDecoration(new OverflowItemDecoration());
+        }
         mAdapter = new BubbleOverflowAdapter(getContext(), mOverflowBubbles,
                 mController::promoteBubbleFromOverflow,
                 mController.getPositioner());
@@ -188,6 +200,13 @@
         final int mode = res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
         final boolean isNightMode = (mode == Configuration.UI_MODE_NIGHT_YES);
 
+        mHorizontalMargin = res.getDimensionPixelSize(
+                R.dimen.bubble_overflow_item_padding_horizontal);
+        mVerticalMargin = res.getDimensionPixelSize(R.dimen.bubble_overflow_item_padding_vertical);
+        if (mRecyclerView != null) {
+            mRecyclerView.invalidateItemDecorations();
+        }
+
         mEmptyStateImage.setImageDrawable(isNightMode
                 ? res.getDrawable(R.drawable.bubble_ic_empty_overflow_dark)
                 : res.getDrawable(R.drawable.bubble_ic_empty_overflow_light));
@@ -277,8 +296,7 @@
     }
 
     @Override
-    public BubbleOverflowAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
-            int viewType) {
+    public BubbleOverflowAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 
         // Set layout for overflow bubble view.
         LinearLayout overflowView = (LinearLayout) LayoutInflater.from(parent.getContext())
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 75b19fb..8a120b9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -67,7 +67,11 @@
     /** The max percent of screen width to use for the flyout on phone. */
     public static final float FLYOUT_MAX_WIDTH_PERCENT = 0.6f;
     /** The percent of screen width that should be used for the expanded view on a large screen. **/
-    public static final float EXPANDED_VIEW_LARGE_SCREEN_WIDTH_PERCENT = 0.72f;
+    private static final float EXPANDED_VIEW_LARGE_SCREEN_LANDSCAPE_WIDTH_PERCENT = 0.48f;
+    /** The percent of screen width that should be used for the expanded view on a large screen. **/
+    private static final float EXPANDED_VIEW_LARGE_SCREEN_PORTRAIT_WIDTH_PERCENT = 0.70f;
+    /** The percent of screen width that should be used for the expanded view on a small tablet. **/
+    private static final float EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT = 0.72f;
 
     private Context mContext;
     private WindowManager mWindowManager;
@@ -77,6 +81,7 @@
     private boolean mImeVisible;
     private int mImeHeight;
     private boolean mIsLargeScreen;
+    private boolean mIsSmallTablet;
 
     private Rect mPositionRect;
     private int mDefaultMaxBubbles;
@@ -86,7 +91,8 @@
 
     private int mExpandedViewMinHeight;
     private int mExpandedViewLargeScreenWidth;
-    private int mExpandedViewLargeScreenInset;
+    private int mExpandedViewLargeScreenInsetClosestEdge;
+    private int mExpandedViewLargeScreenInsetFurthestEdge;
 
     private int mOverflowWidth;
     private int mExpandedViewPadding;
@@ -127,17 +133,26 @@
                 | WindowInsets.Type.statusBars()
                 | WindowInsets.Type.displayCutout());
 
-        mIsLargeScreen = mContext.getResources().getConfiguration().smallestScreenWidthDp >= 600;
+        final Rect bounds = windowMetrics.getBounds();
+        Configuration config = mContext.getResources().getConfiguration();
+        mIsLargeScreen = config.smallestScreenWidthDp >= 600;
+        if (mIsLargeScreen) {
+            float largestEdgeDp = Math.max(config.screenWidthDp, config.screenHeightDp);
+            mIsSmallTablet = largestEdgeDp < 960;
+        } else {
+            mIsSmallTablet = false;
+        }
 
         if (BubbleDebugConfig.DEBUG_POSITIONER) {
             Log.w(TAG, "update positioner:"
                     + " rotation: " + mRotation
                     + " insets: " + insets
                     + " isLargeScreen: " + mIsLargeScreen
-                    + " bounds: " + windowMetrics.getBounds()
+                    + " isSmallTablet: " + mIsSmallTablet
+                    + " bounds: " + bounds
                     + " showingInTaskbar: " + mShowingInTaskbar);
         }
-        updateInternal(mRotation, insets, windowMetrics.getBounds());
+        updateInternal(mRotation, insets, bounds);
     }
 
     /**
@@ -172,15 +187,32 @@
         mSpacingBetweenBubbles = res.getDimensionPixelSize(R.dimen.bubble_spacing);
         mDefaultMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered);
         mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
-        mExpandedViewLargeScreenWidth = (int) (bounds.width()
-                * EXPANDED_VIEW_LARGE_SCREEN_WIDTH_PERCENT);
-        mExpandedViewLargeScreenInset = mIsLargeScreen
-                ? (bounds.width() - mExpandedViewLargeScreenWidth) / 2
-                : mExpandedViewPadding;
-        mOverflowWidth = mIsLargeScreen
-                ? mExpandedViewLargeScreenWidth
-                : res.getDimensionPixelSize(
-                        R.dimen.bubble_expanded_view_phone_landscape_overflow_width);
+        if (mIsSmallTablet) {
+            mExpandedViewLargeScreenWidth = (int) (bounds.width()
+                    * EXPANDED_VIEW_SMALL_TABLET_WIDTH_PERCENT);
+        } else {
+            mExpandedViewLargeScreenWidth = isLandscape()
+                    ? (int) (bounds.width() * EXPANDED_VIEW_LARGE_SCREEN_LANDSCAPE_WIDTH_PERCENT)
+                    : (int) (bounds.width() * EXPANDED_VIEW_LARGE_SCREEN_PORTRAIT_WIDTH_PERCENT);
+        }
+        if (mIsLargeScreen) {
+            if (isLandscape() && !mIsSmallTablet) {
+                mExpandedViewLargeScreenInsetClosestEdge = res.getDimensionPixelSize(
+                        R.dimen.bubble_expanded_view_largescreen_landscape_padding);
+                mExpandedViewLargeScreenInsetFurthestEdge = bounds.width()
+                        - mExpandedViewLargeScreenInsetClosestEdge
+                        - mExpandedViewLargeScreenWidth;
+            } else {
+                final int centeredInset = (bounds.width() - mExpandedViewLargeScreenWidth) / 2;
+                mExpandedViewLargeScreenInsetClosestEdge = centeredInset;
+                mExpandedViewLargeScreenInsetFurthestEdge = centeredInset;
+            }
+        } else {
+            mExpandedViewLargeScreenInsetClosestEdge = mExpandedViewPadding;
+            mExpandedViewLargeScreenInsetFurthestEdge = mExpandedViewPadding;
+        }
+
+        mOverflowWidth = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_overflow_width);
         mPointerWidth = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
         mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
         mPointerMargin = res.getDimensionPixelSize(R.dimen.bubble_pointer_margin);
@@ -313,6 +345,15 @@
         mImeHeight = height;
     }
 
+    private int getExpandedViewLargeScreenInsetFurthestEdge(boolean isOverflow) {
+        if (isOverflow && mIsLargeScreen) {
+            return mScreenRect.width()
+                    - mExpandedViewLargeScreenInsetClosestEdge
+                    - mOverflowWidth;
+        }
+        return mExpandedViewLargeScreenInsetFurthestEdge;
+    }
+
     /**
      * Calculates the padding for the bubble expanded view.
      *
@@ -327,16 +368,21 @@
      */
     public int[] getExpandedViewContainerPadding(boolean onLeft, boolean isOverflow) {
         final int pointerTotalHeight = mPointerHeight - mPointerOverlap;
+        final int expandedViewLargeScreenInsetFurthestEdge =
+                getExpandedViewLargeScreenInsetFurthestEdge(isOverflow);
         if (mIsLargeScreen) {
+            // Note:
+            // If we're in portrait OR if we're a small tablet, then the two insets values will
+            // be equal. If we're landscape and a large tablet, the two values will be different.
             // [left, top, right, bottom]
             mPaddings[0] = onLeft
-                    ? mExpandedViewLargeScreenInset - pointerTotalHeight
-                    : mExpandedViewLargeScreenInset;
+                    ? mExpandedViewLargeScreenInsetClosestEdge - pointerTotalHeight
+                    : expandedViewLargeScreenInsetFurthestEdge;
             mPaddings[1] = 0;
             mPaddings[2] = onLeft
-                    ? mExpandedViewLargeScreenInset
-                    : mExpandedViewLargeScreenInset - pointerTotalHeight;
-            // Overflow doesn't show manage button / get padding from it so add padding here for it
+                    ? expandedViewLargeScreenInsetFurthestEdge
+                    : mExpandedViewLargeScreenInsetClosestEdge - pointerTotalHeight;
+            // Overflow doesn't show manage button / get padding from it so add padding here
             mPaddings[3] = isOverflow ? mExpandedViewPadding : 0;
             return mPaddings;
         } else {
@@ -494,12 +540,13 @@
         float x;
         float y;
         if (showBubblesVertically()) {
+            int inset = mExpandedViewLargeScreenInsetClosestEdge;
             y = rowStart + positionInRow;
             int left = mIsLargeScreen
-                    ? mExpandedViewLargeScreenInset - mExpandedViewPadding - mBubbleSize
+                    ? inset - mExpandedViewPadding - mBubbleSize
                     : mPositionRect.left;
             int right = mIsLargeScreen
-                    ? mPositionRect.right - mExpandedViewLargeScreenInset + mExpandedViewPadding
+                    ? mPositionRect.right - inset + mExpandedViewPadding
                     : mPositionRect.right - mBubbleSize;
             x = state.onLeft
                     ? left
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index c6a68dc..58f79f3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -1608,7 +1608,9 @@
             Log.d(TAG, "addBubble: " + bubble);
         }
 
-        if (getBubbleCount() == 0 && shouldShowStackEdu()) {
+        final boolean firstBubble = getBubbleCount() == 0;
+
+        if (firstBubble && shouldShowStackEdu()) {
             // Override the default stack position if we're showing user education.
             mStackAnimationController.setStackPosition(mPositioner.getDefaultStartPosition());
         }
@@ -1621,7 +1623,7 @@
                 new FrameLayout.LayoutParams(mPositioner.getBubbleSize(),
                         mPositioner.getBubbleSize()));
 
-        if (getBubbleCount() == 0) {
+        if (firstBubble) {
             mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
         }
         // Set the dot position to the opposite of the side the stack is resting on, since the stack
@@ -1652,6 +1654,10 @@
                     bubble.cleanupViews();
                 }
                 updateExpandedView();
+                if (getBubbleCount() == 0 && !isExpanded()) {
+                    // This is the last bubble and the stack is collapsed
+                    updateStackPosition();
+                }
                 logBubbleEvent(bubble, FrameworkStatsLog.BUBBLE_UICHANGED__ACTION__DISMISSED);
                 return;
             }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
index 74672a3..063dac3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/DismissView.kt
@@ -16,11 +16,16 @@
 
 package com.android.wm.shell.bubbles
 
+import android.animation.ObjectAnimator
 import android.content.Context
-import android.graphics.drawable.TransitionDrawable
+import android.graphics.Color
+import android.graphics.drawable.GradientDrawable
+import android.util.IntProperty
 import android.view.Gravity
 import android.view.View
 import android.view.ViewGroup
+import android.view.WindowManager
+import android.view.WindowInsets
 import android.widget.FrameLayout
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY
@@ -28,8 +33,6 @@
 import com.android.wm.shell.R
 import com.android.wm.shell.animation.PhysicsAnimator
 import com.android.wm.shell.common.DismissCircleView
-import android.view.WindowInsets
-import android.view.WindowManager
 
 /*
  * View that handles interactions between DismissCircleView and BubbleStackView.
@@ -41,9 +44,21 @@
 
     private val animator = PhysicsAnimator.getInstance(circle)
     private val spring = PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_LOW_BOUNCY)
-    private val DISMISS_SCRIM_FADE_MS = 200
+    private val DISMISS_SCRIM_FADE_MS = 200L
     private var wm: WindowManager =
             context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+    private var gradientDrawable = createGradient()
+
+    private val GRADIENT_ALPHA: IntProperty<GradientDrawable> =
+            object : IntProperty<GradientDrawable>("alpha") {
+        override fun setValue(d: GradientDrawable, percent: Int) {
+            d.alpha = percent
+        }
+        override fun get(d: GradientDrawable): Int {
+            return d.alpha
+        }
+    }
+
     init {
         setLayoutParams(LayoutParams(
             ViewGroup.LayoutParams.MATCH_PARENT,
@@ -53,8 +68,7 @@
         setClipToPadding(false)
         setClipChildren(false)
         setVisibility(View.INVISIBLE)
-        setBackgroundResource(
-            R.drawable.floating_dismiss_gradient_transition)
+        setBackgroundDrawable(gradientDrawable)
 
         val targetSize: Int = resources.getDimensionPixelSize(R.dimen.dismiss_circle_size)
         addView(circle, LayoutParams(targetSize, targetSize,
@@ -71,7 +85,11 @@
         if (isShowing) return
         isShowing = true
         setVisibility(View.VISIBLE)
-        (getBackground() as TransitionDrawable).startTransition(DISMISS_SCRIM_FADE_MS)
+        val alphaAnim = ObjectAnimator.ofInt(gradientDrawable, GRADIENT_ALPHA,
+                gradientDrawable.alpha, 255)
+        alphaAnim.setDuration(DISMISS_SCRIM_FADE_MS)
+        alphaAnim.start()
+
         animator.cancel()
         animator
             .spring(DynamicAnimation.TRANSLATION_Y, 0f, spring)
@@ -85,7 +103,10 @@
     fun hide() {
         if (!isShowing) return
         isShowing = false
-        (getBackground() as TransitionDrawable).reverseTransition(DISMISS_SCRIM_FADE_MS)
+        val alphaAnim = ObjectAnimator.ofInt(gradientDrawable, GRADIENT_ALPHA,
+                gradientDrawable.alpha, 0)
+        alphaAnim.setDuration(DISMISS_SCRIM_FADE_MS)
+        alphaAnim.start()
         animator
             .spring(DynamicAnimation.TRANSLATION_Y, height.toFloat(),
                 spring)
@@ -93,6 +114,13 @@
             .start()
     }
 
+    /**
+     * Cancels the animator for the dismiss target.
+     */
+    fun cancelAnimators() {
+        animator.cancel()
+    }
+
     fun updateResources() {
         updatePadding()
         layoutParams.height = resources.getDimensionPixelSize(
@@ -104,6 +132,20 @@
         circle.requestLayout()
     }
 
+    private fun createGradient(): GradientDrawable {
+        val gradientColor = context.resources.getColor(android.R.color.system_neutral1_900)
+        val alpha = 0.7f * 255
+        val gradientColorWithAlpha = Color.argb(alpha.toInt(),
+                Color.red(gradientColor),
+                Color.green(gradientColor),
+                Color.blue(gradientColor))
+        val gd = GradientDrawable(
+                GradientDrawable.Orientation.BOTTOM_TOP,
+                intArrayOf(gradientColorWithAlpha, Color.TRANSPARENT))
+        gd.setAlpha(0)
+        return gd
+    }
+
     private fun updatePadding() {
         val insets: WindowInsets = wm.getCurrentWindowMetrics().getWindowInsets()
         val navInset = insets.getInsetsIgnoringVisibility(
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 9384e2b..d22fb50 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
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.os.RemoteException;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
@@ -36,6 +37,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 /**
  * This module deals with display rotations coming from WM. When WM starts a rotation: after it has
@@ -245,8 +247,8 @@
         }
     }
 
-    private void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
-            List<Rect> unrestricted) {
+    private void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
+            Set<Rect> unrestricted) {
         synchronized (mDisplays) {
             if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) {
                 Slog.w(TAG, "Skipping onKeepClearAreasChanged on unknown"
@@ -323,7 +325,8 @@
         public void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
                 List<Rect> unrestricted) {
             mMainExecutor.execute(() -> {
-                DisplayController.this.onKeepClearAreasChanged(displayId, restricted, unrestricted);
+                DisplayController.this.onKeepClearAreasChanged(displayId,
+                        new ArraySet<>(restricted), new ArraySet<>(unrestricted));
             });
         }
     }
@@ -364,7 +367,7 @@
         /**
          * Called when keep-clear areas on a display have changed.
          */
-        default void onKeepClearAreasChanged(int displayId, List<Rect> restricted,
-                List<Rect> unrestricted) {}
+        default void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
+                Set<Rect> unrestricted) {}
     }
 }
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 8a482fb..b52c8d1 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
@@ -502,16 +502,24 @@
 
         if (!mBounds1.equals(mWinBounds1) || !task1.token.equals(mWinToken1)) {
             wct.setBounds(task1.token, mBounds1);
+            wct.setSmallestScreenWidthDp(task1.token, getSmallestWidthDp(mBounds1));
             mWinBounds1.set(mBounds1);
             mWinToken1 = task1.token;
         }
         if (!mBounds2.equals(mWinBounds2) || !task2.token.equals(mWinToken2)) {
             wct.setBounds(task2.token, mBounds2);
+            wct.setSmallestScreenWidthDp(task2.token, getSmallestWidthDp(mBounds2));
             mWinBounds2.set(mBounds2);
             mWinToken2 = task2.token;
         }
     }
 
+    private int getSmallestWidthDp(Rect bounds) {
+        final int minWidth = Math.min(bounds.width(), bounds.height());
+        final float density = mContext.getResources().getDisplayMetrics().density;
+        return (int) (minWidth / density);
+    }
+
     /**
      * Shift configuration bounds to prevent client apps get configuration changed or relaunch. And
      * restore shifted configuration bounds if it's no longer shifted.
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 4f16042..1e934c5 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;
@@ -68,6 +67,7 @@
             PipTransitionController pipTransitionController,
             TvPipNotificationController tvPipNotificationController,
             TaskStackListenerImpl taskStackListener,
+            DisplayController displayController,
             WindowManagerShellWrapper windowManagerShellWrapper,
             @ShellMainThread ShellExecutor mainExecutor) {
         return Optional.of(
@@ -81,6 +81,7 @@
                         pipMediaController,
                         tvPipNotificationController,
                         taskStackListener,
+                        displayController,
                         windowManagerShellWrapper,
                         mainExecutor));
     }
@@ -161,15 +162,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 c94f3d1..0362b3f 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
@@ -699,7 +699,10 @@
             Context context,
             @ShellMainThread ShellExecutor shellExecutor
     ) {
-        return Optional.of(
-                new BackAnimationController(shellExecutor, context));
+        if (BackAnimationController.IS_ENABLED) {
+            return Optional.of(
+                    new BackAnimationController(shellExecutor, context));
+        }
+        return Optional.empty();
     }
 }
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/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 e29dde2..797df41 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
@@ -32,6 +32,7 @@
 import android.util.TypedValue;
 import android.view.Gravity;
 
+import com.android.wm.shell.R;
 import com.android.wm.shell.common.DisplayLayout;
 
 import java.io.PrintWriter;
@@ -76,15 +77,15 @@
     protected void reloadResources(Context context) {
         final Resources res = context.getResources();
         mDefaultAspectRatio = res.getFloat(
-                com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio);
+                R.dimen.config_pictureInPictureDefaultAspectRatio);
         mDefaultStackGravity = res.getInteger(
-                com.android.internal.R.integer.config_defaultPictureInPictureGravity);
+                R.integer.config_defaultPictureInPictureGravity);
         mDefaultMinSize = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.default_minimal_size_pip_resizable_task);
+                R.dimen.default_minimal_size_pip_resizable_task);
         mOverridableMinSize = res.getDimensionPixelSize(
-                com.android.internal.R.dimen.overridable_minimal_size_pip_resizable_task);
+                R.dimen.overridable_minimal_size_pip_resizable_task);
         final String screenEdgeInsetsDpString = res.getString(
-                com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets);
+                R.string.config_defaultPictureInPictureScreenEdgeInsets);
         final Size screenEdgeInsetsDp = !screenEdgeInsetsDpString.isEmpty()
                 ? Size.parseSize(screenEdgeInsetsDpString)
                 : null;
@@ -96,9 +97,9 @@
         mMaxAspectRatio = res.getFloat(
                 com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
         mDefaultSizePercent = res.getFloat(
-                com.android.internal.R.dimen.config_pictureInPictureDefaultSizePercent);
+                R.dimen.config_pictureInPictureDefaultSizePercent);
         mMaxAspectRatioForMinSize = res.getFloat(
-                com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
+                R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
         mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
     }
 
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 bebf2ca..ddcd4bd 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
@@ -28,14 +28,16 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.RemoteException;
-import android.util.Log;
+import android.util.ArraySet;
 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;
@@ -43,6 +45,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 import java.util.function.Consumer;
 
 /**
@@ -90,6 +93,24 @@
     private int mShelfHeight;
     /** Whether the user has resized the PIP manually. */
     private boolean mHasUserResizedPip;
+    /**
+     * Areas defined by currently visible apps that they prefer to keep clear from overlays such as
+     * the PiP. Restricted areas may only move the PiP a limited amount from its anchor position.
+     * The system will try to respect these areas, but when not possible will ignore them.
+     *
+     * @see android.view.View#setPreferKeepClearRects
+     */
+    private final Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>();
+    /**
+     * Areas defined by currently visible apps holding
+     * {@link android.Manifest.permission#SET_UNRESTRICTED_KEEP_CLEAR_AREAS} that they prefer to
+     * keep clear from overlays such as the PiP.
+     * Unrestricted areas can move the PiP farther than restricted areas, and the system will try
+     * harder to respect these areas.
+     *
+     * @see android.view.View#setPreferKeepClearRects
+     */
+    private final Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>();
 
     private @Nullable Runnable mOnMinimalSizeChangeCallback;
     private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback;
@@ -203,7 +224,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);
         }
     }
 
@@ -367,6 +389,25 @@
         }
     }
 
+    /** Set the keep clear areas onscreen. The PiP should ideally not cover them. */
+    public void setKeepClearAreas(@NonNull Set<Rect> restrictedAreas,
+            @NonNull Set<Rect> unrestrictedAreas) {
+        mRestrictedKeepClearAreas.clear();
+        mRestrictedKeepClearAreas.addAll(restrictedAreas);
+        mUnrestrictedKeepClearAreas.clear();
+        mUnrestrictedKeepClearAreas.addAll(unrestrictedAreas);
+    }
+
+    @NonNull
+    public Set<Rect> getRestrictedKeepClearAreas() {
+        return mRestrictedKeepClearAreas;
+    }
+
+    @NonNull
+    public Set<Rect> getUnrestrictedKeepClearAreas() {
+        return mUnrestrictedKeepClearAreas;
+    }
+
     /**
      * Initialize states when first entering PiP.
      */
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..b266189 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
@@ -63,7 +63,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 +72,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 +81,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 +133,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 +248,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 +260,6 @@
             @NonNull PipAnimationController pipAnimationController,
             @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
             @NonNull PipTransitionController pipTransitionController,
-            Optional<LegacySplitScreenController> legacySplitScreenOptional,
             Optional<SplitScreenController> splitScreenOptional,
             @NonNull DisplayController displayController,
             @NonNull PipUiEventLogger pipUiEventLogger,
@@ -283,7 +282,6 @@
         mPipAnimationController = pipAnimationController;
         mPipUiEventLoggerLogger = pipUiEventLogger;
         mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
-        mLegacySplitScreenOptional = legacySplitScreenOptional;
         mSplitScreenOptional = splitScreenOptional;
         mTaskOrganizer = shellTaskOrganizer;
         mMainExecutor = mainExecutor;
@@ -356,12 +354,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 +405,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;
         }
 
@@ -489,20 +501,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 +548,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 +579,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 +589,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 +627,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 +686,6 @@
 
     private void onEndOfSwipePipToHomeTransition() {
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
-            mSwipePipToHomeOverlay = null;
             return;
         }
 
@@ -763,7 +777,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 +803,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 +816,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 +840,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 +912,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 +934,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 +982,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 +1103,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 +1118,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 +1157,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 +1193,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 +1275,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 +1289,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 +1435,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 +1503,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 +1536,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 91615fe..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;
@@ -84,6 +85,7 @@
     private final Optional<SplitScreenController> mSplitScreenOptional;
     private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
     private Transitions.TransitionFinishCallback mFinishCallback;
+    private SurfaceControl.Transaction mFinishTransaction;
     private final Rect mExitDestinationBounds = new Rect();
     @Nullable
     private IBinder mExitTransition;
@@ -150,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
@@ -166,25 +168,33 @@
             if (mFinishCallback != null) {
                 mFinishCallback.onTransitionFinished(null, null);
                 mFinishCallback = null;
+                mFinishTransaction = null;
                 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="
@@ -197,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.
@@ -209,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.
@@ -267,7 +278,8 @@
     public void onFinishResize(TaskInfo taskInfo, Rect destinationBounds,
             @PipAnimationController.TransitionDirection int direction,
             @Nullable SurfaceControl.Transaction tx) {
-        if (isInPipDirection(direction)) {
+        final boolean enteringPip = isInPipDirection(direction);
+        if (enteringPip) {
             mPipTransitionState.setTransitionState(ENTERED_PIP);
         }
         // If there is an expected exit transition, then the exit will be "merged" into this
@@ -279,6 +291,20 @@
             if (tx != null) {
                 wct.setBoundsChangeTransaction(taskInfo.token, tx);
             }
+            final SurfaceControl leash = mPipOrganizer.getSurfaceControl();
+            final int displayRotation = taskInfo.getConfiguration().windowConfiguration
+                    .getDisplayRotation();
+            if (enteringPip && mInFixedRotation && mEndFixedRotation != displayRotation
+                    && leash != null && leash.isValid()) {
+                // Launcher may update the Shelf height during the animation, which will update the
+                // destination bounds. Because this is in fixed rotation, We need to make sure the
+                // finishTransaction is using the updated bounds in the display rotation.
+                final Rect displayBounds = mPipBoundsState.getDisplayBounds();
+                final Rect finishBounds = new Rect(destinationBounds);
+                rotateBounds(finishBounds, displayBounds, mEndFixedRotation, displayRotation);
+                mSurfaceTransactionHelper.crop(mFinishTransaction, leash, finishBounds);
+            }
+            mFinishTransaction = null;
             mFinishCallback.onTransitionFinished(wct, null /* callback */);
             mFinishCallback = null;
         }
@@ -290,6 +316,7 @@
         if (mFinishCallback == null) return;
         mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
         mFinishCallback = null;
+        mFinishTransaction = null;
     }
 
     @Override
@@ -303,7 +330,7 @@
     }
 
     @Nullable
-    private TransitionInfo.Change findCurrentPipChange(@NonNull TransitionInfo info) {
+    private TransitionInfo.Change findCurrentPipTaskChange(@NonNull TransitionInfo info) {
         if (mCurrentPipTaskToken == null) {
             return null;
         }
@@ -331,11 +358,33 @@
             @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;
 
         // Check if it is Shell rotation.
         if (Transitions.SHELL_TRANSITIONS_ROTATION) {
@@ -352,7 +401,7 @@
             if (displayRotationChange != null) {
                 // Exiting PIP to fullscreen with orientation change.
                 startExpandAndRotationAnimation(info, startTransaction, finishTransaction,
-                        displayRotationChange, pipChange);
+                        displayRotationChange, taskInfo, pipChange);
                 return;
             }
         }
@@ -393,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());
 
@@ -439,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)
@@ -465,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);
     }
 
@@ -526,6 +574,7 @@
         if (mFinishCallback != null) {
             mFinishCallback.onTransitionFinished(null /* wct */, null /* callback */);
             mFinishCallback = null;
+            mFinishTransaction = null;
             throw new RuntimeException("Previous callback not called, aborting entering PIP.");
         }
 
@@ -549,6 +598,7 @@
 
         mPipTransitionState.setTransitionState(PipTransitionState.ENTERING_PIP);
         mFinishCallback = finishCallback;
+        mFinishTransaction = finishTransaction;
         final int endRotation = mInFixedRotation ? mEndFixedRotation : enterPip.getEndRotation();
         return startEnterAnimation(enterPip.getTaskInfo(), enterPip.getLeash(),
                 startTransaction, finishTransaction, enterPip.getStartRotation(),
@@ -582,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
@@ -596,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;
         }
@@ -656,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(
@@ -688,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);
@@ -704,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();
             }
@@ -712,7 +773,7 @@
         }
         mHasFadeOut = false;
         mCurrentPipTaskToken = null;
-        mPipOrganizer.onExitPipFinished(prevPipChange.getTaskInfo());
+        mPipOrganizer.onExitPipFinished(prevPipTaskChange.getTaskInfo());
     }
 
     private void updatePipForUnhandledTransition(@NonNull TransitionInfo.Change pipChange,
@@ -736,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 915c593..3115f8a 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
@@ -20,27 +20,20 @@
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.Insets;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
-import android.graphics.drawable.TransitionDrawable;
-import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.SurfaceControl;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.view.WindowManager;
-import android.widget.FrameLayout;
 
 import androidx.annotation.NonNull;
-import androidx.dynamicanimation.animation.DynamicAnimation;
-import androidx.dynamicanimation.animation.SpringForce;
 
 import com.android.wm.shell.R;
-import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.DismissView;
 import com.android.wm.shell.common.DismissCircleView;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
@@ -56,9 +49,6 @@
     /* The multiplier to apply scale the target size by when applying the magnetic field radius */
     private static final float MAGNETIC_FIELD_RADIUS_MULTIPLIER = 1.25f;
 
-    /** Duration of the dismiss scrim fading in/out. */
-    private static final int DISMISS_TRANSITION_DURATION_MS = 200;
-
     /**
      * MagnetizedObject wrapper for PIP. This allows the magnetic target library to locate and move
      * PIP.
@@ -69,7 +59,7 @@
      * Container for the dismiss circle, so that it can be animated within the container via
      * translation rather than within the WindowManager via slow layout animations.
      */
-    private ViewGroup mTargetViewContainer;
+    private DismissView mTargetViewContainer;
 
     /** Circle view used to render the dismiss target. */
     private DismissCircleView mTargetView;
@@ -79,16 +69,6 @@
      */
     private MagnetizedObject.MagneticTarget mMagneticTarget;
 
-    /**
-     * PhysicsAnimator instance for animating the dismiss target in/out.
-     */
-    private PhysicsAnimator<View> mMagneticTargetAnimator;
-
-    /** Default configuration to use for springing the dismiss target in/out. */
-    private final PhysicsAnimator.SpringConfig mTargetSpringConfig =
-            new PhysicsAnimator.SpringConfig(
-                    SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
-
     // Allow dragging the PIP to a location to close it
     private boolean mEnableDismissDragToEdge;
 
@@ -125,12 +105,8 @@
             cleanUpDismissTarget();
         }
 
-        mTargetView = new DismissCircleView(mContext);
-        mTargetViewContainer = new FrameLayout(mContext);
-        mTargetViewContainer.setBackgroundDrawable(
-                mContext.getDrawable(R.drawable.floating_dismiss_gradient_transition));
-        mTargetViewContainer.setClipChildren(false);
-        mTargetViewContainer.addView(mTargetView);
+        mTargetViewContainer = new DismissView(mContext);
+        mTargetView = mTargetViewContainer.getCircle();
         mTargetViewContainer.setOnApplyWindowInsetsListener((view, windowInsets) -> {
             if (!windowInsets.equals(mWindowInsets)) {
                 mWindowInsets = windowInsets;
@@ -187,7 +163,6 @@
             }
         });
 
-        mMagneticTargetAnimator = PhysicsAnimator.getInstance(mTargetView);
     }
 
     @Override
@@ -213,19 +188,13 @@
         if (mTargetView == null) {
             return;
         }
+        if (mTargetViewContainer != null) {
+            mTargetViewContainer.updateResources();
+        }
 
         final Resources res = mContext.getResources();
         mTargetSize = res.getDimensionPixelSize(R.dimen.dismiss_circle_size);
         mDismissAreaHeight = res.getDimensionPixelSize(R.dimen.floating_dismiss_gradient_height);
-        final WindowInsets insets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();
-        final Insets navInset = insets.getInsetsIgnoringVisibility(
-                WindowInsets.Type.navigationBars());
-        final FrameLayout.LayoutParams newParams =
-                new FrameLayout.LayoutParams(mTargetSize, mTargetSize);
-        newParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-        newParams.bottomMargin = navInset.bottom + mContext.getResources().getDimensionPixelSize(
-                R.dimen.floating_dismiss_bottom_margin);
-        mTargetView.setLayoutParams(newParams);
 
         // Set the magnetic field radius equal to the target size from the center of the target
         setMagneticFieldRadiusPercent(mMagneticFieldRadiusPercent);
@@ -261,7 +230,7 @@
     /** Adds the magnetic target view to the WindowManager so it's ready to be animated in. */
     public void createOrUpdateDismissTarget() {
         if (!mTargetViewContainer.isAttachedToWindow()) {
-            mMagneticTargetAnimator.cancel();
+            mTargetViewContainer.cancelAnimators();
 
             mTargetViewContainer.setVisibility(View.INVISIBLE);
             mTargetViewContainer.getViewTreeObserver().removeOnPreDrawListener(this);
@@ -312,18 +281,8 @@
         createOrUpdateDismissTarget();
 
         if (mTargetViewContainer.getVisibility() != View.VISIBLE) {
-            mTargetView.setTranslationY(mTargetViewContainer.getHeight());
-            mTargetViewContainer.setVisibility(View.VISIBLE);
             mTargetViewContainer.getViewTreeObserver().addOnPreDrawListener(this);
-
-            // Cancel in case we were in the middle of animating it out.
-            mMagneticTargetAnimator.cancel();
-            mMagneticTargetAnimator
-                    .spring(DynamicAnimation.TRANSLATION_Y, 0f, mTargetSpringConfig)
-                    .start();
-
-            ((TransitionDrawable) mTargetViewContainer.getBackground()).startTransition(
-                    DISMISS_TRANSITION_DURATION_MS);
+            mTargetViewContainer.show();
         }
     }
 
@@ -332,16 +291,7 @@
         if (!mEnableDismissDragToEdge) {
             return;
         }
-
-        mMagneticTargetAnimator
-                .spring(DynamicAnimation.TRANSLATION_Y,
-                        mTargetViewContainer.getHeight(),
-                        mTargetSpringConfig)
-                .withEndActions(() -> mTargetViewContainer.setVisibility(View.GONE))
-                .start();
-
-        ((TransitionDrawable) mTargetViewContainer.getBackground()).reverseTransition(
-                DISMISS_TRANSITION_DURATION_MS);
+        mTargetViewContainer.hide();
     }
 
     /**
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..e57abc2 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,7 +142,8 @@
             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
@@ -165,7 +167,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..f3789fd 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;
 
@@ -354,8 +355,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 +370,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 +555,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 +676,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 +690,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/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/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS
new file mode 100644
index 0000000..85441af
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/OWNERS
@@ -0,0 +1,2 @@
+# WM shell sub-module TV pip owner
+galinap@google.com
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 5069180..3c830e0 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
@@ -37,6 +37,7 @@
 
 import com.android.wm.shell.R;
 import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TaskStackListenerCallback;
@@ -50,12 +51,14 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
 
 /**
  * Manages the picture-in-picture (PIP) UI and states.
  */
 public class TvPipController implements PipTransitionController.PipTransitionCallback,
-        TvPipMenuController.Delegate, TvPipNotificationController.Delegate {
+        TvPipMenuController.Delegate, TvPipNotificationController.Delegate,
+        DisplayController.OnDisplaysChangedListener {
     private static final String TAG = "TvPipController";
     static final boolean DEBUG = false;
 
@@ -112,6 +115,7 @@
             PipMediaController pipMediaController,
             TvPipNotificationController pipNotificationController,
             TaskStackListenerImpl taskStackListener,
+            DisplayController displayController,
             WindowManagerShellWrapper wmShell,
             ShellExecutor mainExecutor) {
         return new TvPipController(
@@ -124,6 +128,7 @@
                 pipMediaController,
                 pipNotificationController,
                 taskStackListener,
+                displayController,
                 wmShell,
                 mainExecutor).mImpl;
     }
@@ -138,6 +143,7 @@
             PipMediaController pipMediaController,
             TvPipNotificationController pipNotificationController,
             TaskStackListenerImpl taskStackListener,
+            DisplayController displayController,
             WindowManagerShellWrapper wmShell,
             ShellExecutor mainExecutor) {
         mContext = context;
@@ -163,6 +169,7 @@
 
         registerTaskStackListenerCallback(taskStackListener);
         registerWmShellPinnedStackListener(wmShell);
+        displayController.addDisplayWindowListener(this);
     }
 
     private void onConfigurationChanged(Configuration newConfig) {
@@ -253,6 +260,15 @@
         return mTvPipBoundsState.getTvFixedPipOrientation();
     }
 
+    @Override
+    public void onKeepClearAreasChanged(int displayId, Set<Rect> restricted,
+            Set<Rect> unrestricted) {
+        if (mTvPipBoundsState.getDisplayId() == displayId) {
+            mTvPipBoundsState.setKeepClearAreas(restricted, unrestricted);
+            movePinnedStack();
+        }
+    }
+
     /**
      * Animate to the updated position of the PiP based on the state and position of the PiP.
      */
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/MainStage.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
index 082fe92..22dd9b9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/MainStage.java
@@ -18,7 +18,6 @@
 
 import android.annotation.Nullable;
 import android.content.Context;
-import android.graphics.Rect;
 import android.view.SurfaceSession;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
@@ -49,14 +48,13 @@
         return mIsActive;
     }
 
-    void activate(Rect rootBounds, WindowContainerTransaction wct, boolean includingTopTask) {
+    void activate(WindowContainerTransaction wct, boolean includingTopTask) {
         if (mIsActive) return;
 
         final WindowContainerToken rootToken = mRootTaskInfo.token;
-        wct.setBounds(rootToken, rootBounds)
-                // Moving the root task to top after the child tasks were re-parented , or the root
-                // task cannot be visible and focused.
-                .reorder(rootToken, true /* onTop */);
+        // Moving the root task to top after the child tasks were re-parented , or the root
+        // task cannot be visible and focused.
+        wct.reorder(rootToken, true /* onTop */);
         if (includingTopTask) {
             wct.reparentTasks(
                     null /* currentParent */,
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 62e4e97..9e53593 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
@@ -354,8 +354,8 @@
         mSplitLayout.setDivideRatio(splitRatio);
         // Build a request WCT that will launch both apps such that task 0 is on the main stage
         // while task 1 is on the side stage.
-        mMainStage.activate(getMainStageBounds(), wct, false /* reparent */);
-        mSideStage.setBounds(getSideStageBounds(), wct);
+        mMainStage.activate(wct, false /* reparent */);
+        updateWindowBounds(mSplitLayout, wct);
 
         // Make sure the launch options will put tasks in the corresponding split roots
         addActivityOptions(mainOptions, mMainStage);
@@ -470,13 +470,14 @@
 
         mSplitLayout.setDivideRatio(splitRatio);
         if (mMainStage.isActive()) {
-            mMainStage.moveToTop(getMainStageBounds(), wct);
+            mMainStage.moveToTop(wct);
         } else {
             // Build a request WCT that will launch both apps such that task 0 is on the main stage
             // while task 1 is on the side stage.
-            mMainStage.activate(getMainStageBounds(), wct, false /* reparent */);
+            mMainStage.activate(wct, false /* reparent */);
         }
-        mSideStage.moveToTop(getSideStageBounds(), wct);
+        mSideStage.moveToTop(wct);
+        updateWindowBounds(mSplitLayout, wct);
 
         // Make sure the launch options will put tasks in the corresponding split roots
         addActivityOptions(mainOptions, mMainStage);
@@ -774,13 +775,15 @@
             setSideStagePosition(startPosition, wct);
             mSideStage.addTask(taskInfo, wct);
         }
-        mMainStage.activate(getMainStageBounds(), wct, true /* includingTopTask */);
-        mSideStage.moveToTop(getSideStageBounds(), wct);
+        mMainStage.activate(wct, true /* includingTopTask */);
+        mSideStage.moveToTop(wct);
+        updateWindowBounds(mSplitLayout, wct);
     }
 
     void finishEnterSplitScreen(SurfaceControl.Transaction t) {
         mSplitLayout.init();
         setDividerVisibility(true, t);
+        updateSurfaceBounds(mSplitLayout, t);
         setSplitsVisible(true);
         mShouldUpdateRecents = true;
         updateRecentTasksSplitPair();
@@ -997,10 +1000,9 @@
                 // Exit to side stage if main stage no longer has children.
                 exitSplitScreen(mSideStage, EXIT_REASON_APP_FINISHED);
             }
-        } else if (isSideStage) {
+        } else if (isSideStage && !mMainStage.isActive()) {
             final WindowContainerTransaction wct = new WindowContainerTransaction();
             mSplitLayout.init();
-            // Make sure the main stage is active.
             prepareEnterSplitScreen(wct);
             mSyncQueue.queue(wct);
             mSyncQueue.runInSync(t -> {
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 612bb93..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
@@ -53,8 +53,8 @@
  * Base class that handle common task org. related for split-screen stages.
  * Note that this class and its sub-class do not directly perform hierarchy operations.
  * They only serve to hold a collection of tasks and provide APIs like
- * {@link #setBounds(Rect, WindowContainerTransaction)} for the centralized {@link StageCoordinator}
- * to perform operations in-sync with other containers.
+ * {@link #addTask(ActivityManager.RunningTaskInfo, WindowContainerTransaction)} for the centralized
+ * {@link StageCoordinator} to perform hierarchy operations in-sync with other containers.
  *
  * @see StageCoordinator
  */
@@ -294,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);
         }
@@ -324,13 +334,9 @@
         wct.reparent(task.token, mRootTaskInfo.token, true /* onTop*/);
     }
 
-    void moveToTop(Rect rootBounds, WindowContainerTransaction wct) {
+    void moveToTop(WindowContainerTransaction wct) {
         final WindowContainerToken rootToken = mRootTaskInfo.token;
-        wct.setBounds(rootToken, rootBounds).reorder(rootToken, true /* onTop */);
-    }
-
-    void setBounds(Rect bounds, WindowContainerTransaction wct) {
-        wct.setBounds(mRootTaskInfo.token, bounds);
+        wct.reorder(rootToken, true /* onTop */);
     }
 
     void reorderChild(int taskId, boolean onTop, WindowContainerTransaction wct) {
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/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 025bcad..f0fb69f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -18,8 +18,8 @@
 
 import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
+import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
 
 import static com.android.wm.shell.startingsurface.StartingSurfaceDrawer.MAX_ANIMATION_DURATION;
@@ -69,6 +69,7 @@
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.launcher3.icons.BaseIconFactory;
 import com.android.launcher3.icons.IconProvider;
+import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.TransactionPool;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 
@@ -115,8 +116,10 @@
     private final Handler mSplashscreenWorkerHandler;
     @VisibleForTesting
     final ColorCache mColorCache;
+    private final ShellExecutor mSplashScreenExecutor;
 
-    SplashscreenContentDrawer(Context context, IconProvider iconProvider, TransactionPool pool) {
+    SplashscreenContentDrawer(Context context, IconProvider iconProvider, TransactionPool pool,
+            ShellExecutor splashScreenExecutor) {
         mContext = context;
         mIconProvider = iconProvider;
         mTransactionPool = pool;
@@ -129,6 +132,7 @@
         shellSplashscreenWorkerThread.start();
         mSplashscreenWorkerHandler = shellSplashscreenWorkerThread.getThreadHandler();
         mColorCache = new ColorCache(mContext, mSplashscreenWorkerHandler);
+        mSplashScreenExecutor = splashScreenExecutor;
     }
 
     /**
@@ -266,7 +270,7 @@
                 .overlayDrawable(legacyDrawable)
                 .chooseStyle(suggestType)
                 .setUiThreadInitConsumer(uiThreadInitConsumer)
-                .setAllowHandleEmpty(info.allowHandleEmptySplashScreen())
+                .setAllowHandleSolidColor(info.allowHandleSolidColorSplashScreen())
                 .build();
     }
 
@@ -363,7 +367,7 @@
         private Drawable[] mFinalIconDrawables;
         private int mFinalIconSize = mIconSize;
         private Consumer<Runnable> mUiThreadInitTask;
-        private boolean mAllowHandleEmpty;
+        private boolean mAllowHandleSolidColor;
 
         StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) {
             mContext = context;
@@ -390,15 +394,15 @@
             return this;
         }
 
-        StartingWindowViewBuilder setAllowHandleEmpty(boolean allowHandleEmpty) {
-            mAllowHandleEmpty = allowHandleEmpty;
+        StartingWindowViewBuilder setAllowHandleSolidColor(boolean allowHandleSolidColor) {
+            mAllowHandleSolidColor = allowHandleSolidColor;
             return this;
         }
 
         SplashScreenView build() {
             Drawable iconDrawable;
-            final int animationDuration;
-            if (mSuggestType == STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
+            final long animationDuration;
+            if (mSuggestType == STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN
                     || mSuggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN) {
                 // empty or legacy splash screen case
                 animationDuration = 0;
@@ -455,8 +459,8 @@
                         iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
             } else {
                 mFinalIconDrawables = SplashscreenIconDrawableFactory.makeIconDrawable(
-                        mTmpAttrs.mIconBgColor, mThemeColor,
-                        iconDrawable, mDefaultIconSize, mFinalIconSize, mSplashscreenWorkerHandler);
+                        mTmpAttrs.mIconBgColor, mThemeColor, iconDrawable, mDefaultIconSize,
+                        mFinalIconSize, mSplashscreenWorkerHandler, mSplashScreenExecutor);
             }
         }
 
@@ -516,7 +520,7 @@
         }
 
         private SplashScreenView fillViewWithIcon(int iconSize, @Nullable Drawable[] iconDrawable,
-                int animationDuration, Consumer<Runnable> uiThreadInitTask) {
+                long animationDuration, Consumer<Runnable> uiThreadInitTask) {
             Drawable foreground = null;
             Drawable background = null;
             if (iconDrawable != null) {
@@ -534,7 +538,7 @@
                     .setCenterViewDrawable(foreground)
                     .setAnimationDurationMillis(animationDuration)
                     .setUiThreadInitConsumer(uiThreadInitTask)
-                    .setAllowHandleEmpty(mAllowHandleEmpty);
+                    .setAllowHandleSolidColor(mAllowHandleSolidColor);
 
             if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
                     && mTmpAttrs.mBrandingImage != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
index 54281e0..fdd5a15 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java
@@ -18,9 +18,7 @@
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
 
-import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.annotation.ColorInt;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -36,6 +34,8 @@
 import android.graphics.Rect;
 import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.Animatable;
+import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Trace;
@@ -44,6 +44,9 @@
 import android.window.SplashScreenView;
 
 import com.android.internal.R;
+import com.android.wm.shell.common.ShellExecutor;
+
+import java.util.function.LongConsumer;
 
 /**
  * Creating a lightweight Drawable object used for splash screen.
@@ -60,14 +63,15 @@
      */
     static Drawable[] makeIconDrawable(@ColorInt int backgroundColor, @ColorInt int themeColor,
             @NonNull Drawable foregroundDrawable, int srcIconSize, int iconSize,
-            Handler splashscreenWorkerHandler) {
+            Handler splashscreenWorkerHandler, ShellExecutor splashScreenExecutor) {
         Drawable foreground;
         Drawable background = null;
         boolean drawBackground =
                 backgroundColor != Color.TRANSPARENT && backgroundColor != themeColor;
 
         if (foregroundDrawable instanceof Animatable) {
-            foreground = new AnimatableIconAnimateListener(foregroundDrawable);
+            foreground = new AnimatableIconAnimateListener(foregroundDrawable,
+                    splashScreenExecutor);
         } else if (foregroundDrawable instanceof AdaptiveIconDrawable) {
             // If the icon is Adaptive, we already use the icon background.
             drawBackground = false;
@@ -266,14 +270,37 @@
      */
     public static class AnimatableIconAnimateListener extends AdaptiveForegroundDrawable
             implements SplashScreenView.IconAnimateListener {
-        private Animatable mAnimatableIcon;
-        private Animator mIconAnimator;
+        private final Animatable mAnimatableIcon;
         private boolean mAnimationTriggered;
         private AnimatorListenerAdapter mJankMonitoringListener;
+        private boolean mRunning;
+        private long mDuration;
+        private LongConsumer mStartListener;
+        private final ShellExecutor mSplashScreenExecutor;
 
-        AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable) {
+        AnimatableIconAnimateListener(@NonNull Drawable foregroundDrawable,
+                ShellExecutor splashScreenExecutor) {
             super(foregroundDrawable);
-            mForegroundDrawable.setCallback(mCallback);
+            Callback callback = new Callback() {
+                @Override
+                public void invalidateDrawable(@NonNull Drawable who) {
+                    invalidateSelf();
+                }
+
+                @Override
+                public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what,
+                        long when) {
+                    scheduleSelf(what, when);
+                }
+
+                @Override
+                public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
+                    unscheduleSelf(what);
+                }
+            };
+            mForegroundDrawable.setCallback(callback);
+            mSplashScreenExecutor = splashScreenExecutor;
+            mAnimatableIcon = (Animatable) mForegroundDrawable;
         }
 
         @Override
@@ -282,83 +309,68 @@
         }
 
         @Override
-        public boolean prepareAnimate(long duration, Runnable startListener) {
-            mAnimatableIcon = (Animatable) mForegroundDrawable;
-            mIconAnimator = ValueAnimator.ofInt(0, 1);
-            mIconAnimator.setDuration(duration);
-            mIconAnimator.addListener(new Animator.AnimatorListener() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    if (startListener != null) {
-                        startListener.run();
-                    }
-                    try {
-                        if (mJankMonitoringListener != null) {
-                            mJankMonitoringListener.onAnimationStart(animation);
-                        }
-                        mAnimatableIcon.start();
-                    } catch (Exception ex) {
-                        Log.e(TAG, "Error while running the splash screen animated icon", ex);
-                        animation.cancel();
-                    }
-                }
+        public void prepareAnimate(long duration, LongConsumer startListener) {
+            stopAnimation();
+            mDuration = duration;
+            mStartListener = startListener;
+        }
 
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mAnimatableIcon.stop();
-                    if (mJankMonitoringListener != null) {
-                        mJankMonitoringListener.onAnimationEnd(animation);
-                    }
+        private void startAnimation() {
+            if (mJankMonitoringListener != null) {
+                mJankMonitoringListener.onAnimationStart(null);
+            }
+            try {
+                mAnimatableIcon.start();
+            } catch (Exception ex) {
+                Log.e(TAG, "Error while running the splash screen animated icon", ex);
+                mRunning = false;
+                if (mJankMonitoringListener != null) {
+                    mJankMonitoringListener.onAnimationCancel(null);
                 }
+                if (mStartListener != null) {
+                    mStartListener.accept(mDuration);
+                }
+                return;
+            }
+            long animDuration = mDuration;
+            if (mAnimatableIcon instanceof AnimatedVectorDrawable
+                    && ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration() > 0) {
+                animDuration = ((AnimatedVectorDrawable) mAnimatableIcon).getTotalDuration();
+            } else if (mAnimatableIcon instanceof AnimationDrawable
+                    && ((AnimationDrawable) mAnimatableIcon).getTotalDuration() > 0) {
+                animDuration = ((AnimationDrawable) mAnimatableIcon).getTotalDuration();
+            }
+            mRunning = true;
+            mSplashScreenExecutor.executeDelayed(this::stopAnimation, animDuration);
+            if (mStartListener != null) {
+                mStartListener.accept(Math.max(animDuration, 0));
+            }
+        }
 
-                @Override
-                public void onAnimationCancel(Animator animation) {
-                    mAnimatableIcon.stop();
-                    if (mJankMonitoringListener != null) {
-                        mJankMonitoringListener.onAnimationCancel(animation);
-                    }
-                }
-
-                @Override
-                public void onAnimationRepeat(Animator animation) {
-                    // do not repeat
-                    mAnimatableIcon.stop();
-                }
-            });
-            return true;
+        private void onAnimationEnd() {
+            mAnimatableIcon.stop();
+            if (mJankMonitoringListener != null) {
+                mJankMonitoringListener.onAnimationEnd(null);
+            }
+            mStartListener = null;
+            mRunning = false;
         }
 
         @Override
         public void stopAnimation() {
-            if (mIconAnimator != null && mIconAnimator.isRunning()) {
-                mIconAnimator.end();
+            if (mRunning) {
+                mSplashScreenExecutor.removeCallbacks(this::stopAnimation);
+                onAnimationEnd();
                 mJankMonitoringListener = null;
             }
         }
 
-        private final Callback mCallback = new Callback() {
-            @Override
-            public void invalidateDrawable(@NonNull Drawable who) {
-                invalidateSelf();
-            }
-
-            @Override
-            public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
-                scheduleSelf(what, when);
-            }
-
-            @Override
-            public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
-                unscheduleSelf(what);
-            }
-        };
-
         private void ensureAnimationStarted() {
             if (mAnimationTriggered) {
                 return;
             }
-            if (mIconAnimator != null && !mIconAnimator.isRunning()) {
-                mIconAnimator.start();
+            if (!mRunning) {
+                startAnimation();
             }
             mAnimationTriggered = true;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index 3442699..04d6ef7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -148,7 +148,8 @@
         mContext = context;
         mDisplayManager = mContext.getSystemService(DisplayManager.class);
         mSplashScreenExecutor = splashScreenExecutor;
-        mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconProvider, pool);
+        mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconProvider, pool,
+                mSplashScreenExecutor);
         mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance());
         mWindowManagerGlobal = WindowManagerGlobal.getInstance();
         mDisplayManager.getDisplay(DEFAULT_DISPLAY);
@@ -364,6 +365,12 @@
                 final StartingWindowRecord record = mStartingWindowRecords.get(taskId);
                 final SplashScreenView contentView = viewSupplier.get();
                 record.mBGColor = contentView.getInitBackgroundColor();
+            } else {
+                // release the icon view host
+                final SplashScreenView contentView = viewSupplier.get();
+                if (contentView.getSurfaceHost() != null) {
+                    SplashScreenView.releaseIconHost(contentView.getSurfaceHost());
+                }
             }
         } catch (RuntimeException e) {
             // don't crash if something else bad happens, for example a
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
index 487eb70..fbc9923 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java
@@ -16,10 +16,10 @@
 package com.android.wm.shell.startingsurface;
 
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
+import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
 
 import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
@@ -155,7 +155,7 @@
 
     private static boolean isSplashScreenType(@StartingWindowType int suggestionType) {
         return suggestionType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
-                || suggestionType == STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
+                || suggestionType == STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN
                 || suggestionType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
index 51a48a2..51722c4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java
@@ -17,10 +17,10 @@
 package com.android.wm.shell.startingsurface.phone;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT;
+import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_DRAWN;
@@ -29,7 +29,7 @@
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
-import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;
+import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN;
 
 import android.window.StartingWindowInfo;
 import android.window.TaskSnapshot;
@@ -51,8 +51,8 @@
         final boolean processRunning = (parameter & TYPE_PARAMETER_PROCESS_RUNNING) != 0;
         final boolean allowTaskSnapshot = (parameter & TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT) != 0;
         final boolean activityCreated = (parameter & TYPE_PARAMETER_ACTIVITY_CREATED) != 0;
-        final boolean useEmptySplashScreen =
-                (parameter & TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN) != 0;
+        final boolean isSolidColorSplashScreen =
+                (parameter & TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN) != 0;
         final boolean legacySplashScreen =
                 ((parameter & TYPE_PARAMETER_LEGACY_SPLASH_SCREEN) != 0);
         final boolean activityDrawn = (parameter & TYPE_PARAMETER_ACTIVITY_DRAWN) != 0;
@@ -65,16 +65,16 @@
                         + "processRunning=%b, "
                         + "allowTaskSnapshot=%b, "
                         + "activityCreated=%b, "
-                        + "useEmptySplashScreen=%b, "
+                        + "isSolidColorSplashScreen=%b, "
                         + "legacySplashScreen=%b, "
                         + "activityDrawn=%b, "
                         + "topIsHome=%b",
                 newTask, taskSwitch, processRunning, allowTaskSnapshot, activityCreated,
-                useEmptySplashScreen, legacySplashScreen, activityDrawn, topIsHome);
+                isSolidColorSplashScreen, legacySplashScreen, activityDrawn, topIsHome);
 
         if (!topIsHome) {
             if (!processRunning || newTask || (taskSwitch && !activityCreated)) {
-                return getSplashscreenType(useEmptySplashScreen, legacySplashScreen);
+                return getSplashscreenType(isSolidColorSplashScreen, legacySplashScreen);
             }
         }
 
@@ -84,19 +84,20 @@
                     return STARTING_WINDOW_TYPE_SNAPSHOT;
                 }
                 if (!topIsHome) {
-                    return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
+                    return STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
                 }
             }
             if (!activityDrawn && !topIsHome) {
-                return getSplashscreenType(useEmptySplashScreen, legacySplashScreen);
+                return getSplashscreenType(isSolidColorSplashScreen, legacySplashScreen);
             }
         }
         return STARTING_WINDOW_TYPE_NONE;
     }
 
-    private static int getSplashscreenType(boolean emptySplashScreen, boolean legacySplashScreen) {
-        return emptySplashScreen
-                ? STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN
+    private static int getSplashscreenType(boolean solidColorSplashScreen,
+            boolean legacySplashScreen) {
+        return solidColorSplashScreen
+                ? STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN
                 : legacySplashScreen
                         ? STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
                         : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/tv/TvStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/tv/TvStartingWindowTypeAlgorithm.java
index 6e7dec5..74fe8fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/tv/TvStartingWindowTypeAlgorithm.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/tv/TvStartingWindowTypeAlgorithm.java
@@ -16,7 +16,7 @@
 
 package com.android.wm.shell.startingsurface.tv;
 
-import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
+import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
 
 import android.window.StartingWindowInfo;
 
@@ -30,6 +30,6 @@
     @Override
     public int getSuggestedWindowType(StartingWindowInfo windowInfo) {
         // For now we want to always show empty splash screens on TV.
-        return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN;
+        return STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN;
     }
 }
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 5af1530..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
@@ -26,6 +26,7 @@
 import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
+import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
 import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE_DRAWABLE;
 import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION;
 import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE;
@@ -156,9 +157,8 @@
     private BroadcastReceiver mEnterpriseResourceUpdatedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            boolean isDrawable = intent.getBooleanExtra(
-                    EXTRA_RESOURCE_TYPE_DRAWABLE, /* default= */ false);
-            if (!isDrawable) {
+            if (intent.getIntExtra(EXTRA_RESOURCE_TYPE, /* default= */ -1)
+                    != EXTRA_RESOURCE_TYPE_DRAWABLE) {
                 return;
             }
             updateEnterpriseThumbnailDrawable();
@@ -348,12 +348,13 @@
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
             final TransitionInfo.Change change = info.getChanges().get(i);
             final boolean isTask = change.getTaskInfo() != null;
+            boolean isSeamlessDisplayChange = false;
 
             if (change.getMode() == TRANSIT_CHANGE && (change.getFlags() & FLAG_IS_DISPLAY) != 0) {
                 if (info.getType() == TRANSIT_CHANGE) {
-                    boolean isSeamless = isRotationSeamless(info, mDisplayController);
+                    isSeamlessDisplayChange = isRotationSeamless(info, mDisplayController);
                     final int anim = getRotationAnimation(info);
-                    if (!(isSeamless || anim == ROTATION_ANIMATION_JUMPCUT)) {
+                    if (!(isSeamlessDisplayChange || anim == ROTATION_ANIMATION_JUMPCUT)) {
                         mRotationAnimation = new ScreenRotationAnimation(mContext, mSurfaceSession,
                                 mTransactionPool, startTransaction, change, info.getRootLeash(),
                                 anim);
@@ -387,6 +388,8 @@
                 startTransaction.setPosition(change.getLeash(),
                         change.getEndAbsBounds().left - info.getRootOffset().x,
                         change.getEndAbsBounds().top - info.getRootOffset().y);
+                // Seamless display transition doesn't need to animate.
+                if (isSeamlessDisplayChange) continue;
                 if (isTask) {
                     // Skip non-tasks since those usually have null bounds.
                     startTransaction.setWindowCrop(change.getLeash(),
@@ -405,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();
@@ -726,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;
@@ -767,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/apppairs/AppPairsTestSupportPairNonResizeableApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestSupportPairNonResizeableApps.kt
index 65eb9aa..57bcbc0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestSupportPairNonResizeableApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTestSupportPairNonResizeableApps.kt
@@ -17,6 +17,7 @@
 package com.android.wm.shell.flicker.apppairs
 
 import android.platform.test.annotations.Presubmit
+import android.view.Display
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -24,6 +25,7 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group1
 import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.traces.common.WindowManagerConditionsFactory
 import com.android.wm.shell.flicker.appPairsDividerIsVisibleAtEnd
 import com.android.wm.shell.flicker.helpers.AppPairsHelper
 import com.android.wm.shell.flicker.helpers.MultiWindowHelper.Companion.resetMultiWindowConfig
@@ -60,7 +62,18 @@
                 // TODO pair apps through normal UX flow
                 executeShellCommand(
                         composePairsCommand(primaryTaskId, nonResizeableTaskId, pair = true))
-                nonResizeableApp?.run { wmHelper.waitForFullScreenApp(nonResizeableApp.component) }
+                val waitConditions = mutableListOf(
+                    WindowManagerConditionsFactory.isWindowVisible(primaryApp.component),
+                    WindowManagerConditionsFactory.isLayerVisible(primaryApp.component),
+                    WindowManagerConditionsFactory.isAppTransitionIdle(Display.DEFAULT_DISPLAY))
+
+                nonResizeableApp?.let {
+                    waitConditions.add(
+                        WindowManagerConditionsFactory.isWindowVisible(nonResizeableApp.component))
+                    waitConditions.add(
+                        WindowManagerConditionsFactory.isLayerVisible(nonResizeableApp.component))
+                }
+                wmHelper.waitFor(*waitConditions.toTypedArray())
             }
         }
 
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/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
index 0f00ede..cc5b9f9 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/ImeAppHelper.kt
@@ -62,7 +62,7 @@
         if (wmHelper == null) {
             device.waitForIdle()
         } else {
-            require(wmHelper.waitImeShown()) { "IME did not appear" }
+            wmHelper.waitImeShown()
         }
     }
 
@@ -79,7 +79,7 @@
             if (wmHelper == null) {
                 uiDevice.waitForIdle()
             } else {
-                require(wmHelper.waitImeGone()) { "IME did did not close" }
+                wmHelper.waitImeGone()
             }
         } else {
             // While pressing the back button should close the IME on TV as well, it may also lead
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
index 7e232ea..e9d438a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/helpers/PipAppHelper.kt
@@ -58,17 +58,27 @@
         }
     }
 
-    /** {@inheritDoc}  */
-    override fun launchViaIntent(
+    /**
+     * Launches the app through an intent instead of interacting with the launcher and waits
+     * until the app window is in PIP mode
+     */
+    @JvmOverloads
+    fun launchViaIntentAndWaitForPip(
         wmHelper: WindowManagerStateHelper,
-        expectedWindowName: String,
-        action: String?,
+        expectedWindowName: String = "",
+        action: String? = null,
         stringExtras: Map<String, String>
     ) {
-        super.launchViaIntent(wmHelper, expectedWindowName, action, stringExtras)
-        wmHelper.waitPipShown()
+        launchViaIntentAndWaitShown(wmHelper, expectedWindowName, action, stringExtras,
+            waitConditions = arrayOf(WindowManagerStateHelper.pipShownCondition))
     }
 
+    /**
+     * Expand the PIP window back to full screen via intent and wait until the app is visible
+     */
+    fun exitPipToFullScreenViaIntent(wmHelper: WindowManagerStateHelper) =
+        launchViaIntentAndWaitShown(wmHelper)
+
     private fun focusOnObject(selector: BySelector): Boolean {
         // We expect all the focusable UI elements to be arranged in a way so that it is possible
         // to "cycle" over all them by clicking the D-Pad DOWN button, going back up to "the top"
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index f2c5093..274d34b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -64,7 +64,18 @@
      * Defines the transition used to run the test
      */
     override val transition: FlickerBuilder.() -> Unit
-        get() = buildTransition(eachRun = true, stringExtras = emptyMap()) {
+        get() = {
+            setupAndTeardown(this)
+            setup {
+                eachRun {
+                    pipApp.launchViaIntent(wmHelper)
+                }
+            }
+            teardown {
+                eachRun {
+                    pipApp.exit(wmHelper)
+                }
+            }
             transitions {
                 pipApp.clickEnterPipButton(wmHelper)
             }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
index 4f98b70..e2d0834 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
@@ -74,7 +74,7 @@
                 // This will bring PipApp to fullscreen
                 pipApp.expandPipWindowToApp(wmHelper)
                 // Wait until the other app is no longer visible
-                wmHelper.waitForSurfaceAppeared(testApp.component.toWindowName())
+                wmHelper.waitForSurfaceAppeared(testApp.component)
             }
         }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index e00d749..3fe6f02 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -72,9 +72,9 @@
             }
             transitions {
                 // This will bring PipApp to fullscreen
-                pipApp.launchViaIntent(wmHelper)
+                pipApp.exitPipToFullScreenViaIntent(wmHelper)
                 // Wait until the other app is no longer visible
-                wmHelper.waitForSurfaceAppeared(testApp.component.toWindowName())
+                wmHelper.waitForWindowSurfaceDisappeared(testApp.component)
             }
         }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
index bb66f7b..8d542c8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipTransition.kt
@@ -56,13 +56,6 @@
                 .sendBroadcast(createIntentWithAction(broadcastAction))
         }
 
-        fun requestOrientationForPip(orientation: Int) {
-            instrumentation.context.sendBroadcast(
-                    createIntentWithAction(Components.PipActivity.ACTION_SET_REQUESTED_ORIENTATION)
-                    .putExtra(Components.PipActivity.EXTRA_PIP_ORIENTATION, orientation.toString())
-            )
-        }
-
         companion object {
             // Corresponds to ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
             @JvmStatic
@@ -122,15 +115,14 @@
 
             setup {
                 test {
-                    removeAllTasksButHome()
                     if (!eachRun) {
-                        pipApp.launchViaIntent(wmHelper, stringExtras = stringExtras)
+                        pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
                         wmHelper.waitPipShown()
                     }
                 }
                 eachRun {
                     if (eachRun) {
-                        pipApp.launchViaIntent(wmHelper, stringExtras = stringExtras)
+                        pipApp.launchViaIntentAndWaitForPip(wmHelper, stringExtras = stringExtras)
                         wmHelper.waitPipShown()
                     }
                 }
@@ -145,7 +137,6 @@
                     if (!eachRun) {
                         pipApp.exit(wmHelper)
                     }
-                    removeAllTasksButHome()
                 }
             }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
index d65388b..f7384e74 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
@@ -25,11 +25,14 @@
 import com.android.server.wm.flicker.FlickerTestParameterFactory
 import com.android.server.wm.flicker.annotation.Group4
 import com.android.server.wm.flicker.dsl.FlickerBuilder
+import com.android.server.wm.flicker.helpers.setRotation
+import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen
 import com.android.server.wm.flicker.helpers.WindowUtils
 import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import com.android.server.wm.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
 import com.android.wm.shell.flicker.pip.PipTransition.BroadcastActionTrigger.Companion.ORIENTATION_LANDSCAPE
+import com.android.wm.shell.flicker.testapp.Components
 import com.android.wm.shell.flicker.testapp.Components.FixedActivity.EXTRA_FIXED_ORIENTATION
-import com.android.wm.shell.flicker.testapp.Components.PipActivity.EXTRA_ENTER_PIP
 import org.junit.Assume
 import org.junit.Before
 import org.junit.FixMethodOrder
@@ -39,7 +42,7 @@
 import org.junit.runners.Parameterized
 
 /**
- * Test Pip with orientation changes.
+ * Test exiting Pip with orientation changes.
  * To run this test: `atest WMShellFlickerTests:SetRequestedOrientationWhilePinnedTest`
  */
 @RequiresDevice
@@ -61,30 +64,41 @@
 
     override val transition: FlickerBuilder.() -> Unit
         get() = {
-            setupAndTeardown(this)
-
             setup {
+                test {
+                    removeAllTasksButHome()
+                    device.wakeUpAndGoToHomeScreen()
+                }
                 eachRun {
-                    // Launch the PiP activity fixed as landscape
+                    // Launch the PiP activity fixed as landscape.
                     pipApp.launchViaIntent(wmHelper, stringExtras = mapOf(
-                        EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString(),
-                        EXTRA_ENTER_PIP to "true"))
+                        EXTRA_FIXED_ORIENTATION to ORIENTATION_LANDSCAPE.toString()))
+                    // Enter PiP.
+                    broadcastActionTrigger.doAction(Components.PipActivity.ACTION_ENTER_PIP)
+                    wmHelper.waitPipShown()
+                    wmHelper.waitForRotation(Surface.ROTATION_0)
+                    wmHelper.waitForAppTransitionIdle()
+                    // System bar may fade out during fixed rotation.
+                    wmHelper.waitForNavBarStatusBarVisible()
                 }
             }
             teardown {
                 eachRun {
                     pipApp.exit(wmHelper)
+                    setRotation(Surface.ROTATION_0)
+                }
+                test {
+                    removeAllTasksButHome()
                 }
             }
             transitions {
-                // Request that the orientation is set to landscape
-                broadcastActionTrigger.requestOrientationForPip(ORIENTATION_LANDSCAPE)
-
-                // Launch the activity back into fullscreen and
-                // ensure that it is now in landscape
+                // Launch the activity back into fullscreen and ensure that it is now in landscape
                 pipApp.launchViaIntent(wmHelper)
                 wmHelper.waitForFullScreenApp(pipApp.component)
                 wmHelper.waitForRotation(Surface.ROTATION_90)
+                wmHelper.waitForAppTransitionIdle()
+                // System bar may fade out during fixed rotation.
+                wmHelper.waitForNavBarStatusBarVisible()
             }
         }
 
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTestShellTransit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTestShellTransit.kt
index 36e2804..8d764a8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTestShellTransit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTestShellTransit.kt
@@ -29,6 +29,10 @@
 import org.junit.runners.MethodSorters
 import org.junit.runners.Parameterized
 
+/**
+ * Test exiting Pip with orientation changes.
+ * To run this test: `atest WMShellFlickerTests:SetRequestedOrientationWhilePinnedTestShellTransit`
+ */
 @RequiresDevice
 @RunWith(Parameterized::class)
 @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index 83d5f04..daec336 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -28,8 +28,10 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.app.ActivityManager;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.window.WindowContainerTransaction;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -38,6 +40,7 @@
 import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
+import com.android.wm.shell.TestRunningTaskInfoBuilder;
 import com.android.wm.shell.common.DisplayImeController;
 
 import org.junit.Before;
@@ -56,6 +59,7 @@
     @Mock SplitWindowManager.ParentContainerCallbacks mCallbacks;
     @Mock DisplayImeController mDisplayImeController;
     @Mock ShellTaskOrganizer mTaskOrganizer;
+    @Mock WindowContainerTransaction mWct;
     @Captor ArgumentCaptor<Runnable> mRunnableCaptor;
     private SplitLayout mSplitLayout;
 
@@ -149,6 +153,16 @@
         verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
     }
 
+    @Test
+    public void testApplyTaskChanges_updatesSmallestScreenWidthDp() {
+        final ActivityManager.RunningTaskInfo task1 = new TestRunningTaskInfoBuilder().build();
+        final ActivityManager.RunningTaskInfo task2 = new TestRunningTaskInfoBuilder().build();
+        mSplitLayout.applyTaskChanges(mWct, task1, task2);
+
+        verify(mWct).setSmallestScreenWidthDp(eq(task1.token), anyInt());
+        verify(mWct).setSmallestScreenWidthDp(eq(task2.token), anyInt());
+    }
+
     private void waitDividerFlingFinished() {
         verify(mSplitLayout).flingDividePosition(anyInt(), anyInt(), mRunnableCaptor.capture());
         mRunnableCaptor.getValue().run();
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/pip/PipBoundsAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
index 90f898a..0059846 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsAlgorithmTest.java
@@ -29,6 +29,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayLayout;
 
@@ -72,16 +73,16 @@
     private void initializeMockResources() {
         final TestableResources res = mContext.getOrCreateTestableResources();
         res.addOverride(
-                com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio,
+                R.dimen.config_pictureInPictureDefaultAspectRatio,
                 DEFAULT_ASPECT_RATIO);
         res.addOverride(
-                com.android.internal.R.integer.config_defaultPictureInPictureGravity,
+                R.integer.config_defaultPictureInPictureGravity,
                 Gravity.END | Gravity.BOTTOM);
         res.addOverride(
-                com.android.internal.R.dimen.default_minimal_size_pip_resizable_task,
+                R.dimen.default_minimal_size_pip_resizable_task,
                 DEFAULT_MIN_EDGE_SIZE);
         res.addOverride(
-                com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets,
+                R.string.config_defaultPictureInPictureScreenEdgeInsets,
                 "16x16");
         res.addOverride(
                 com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio,
@@ -107,7 +108,7 @@
     public void onConfigurationChanged_reloadResources() {
         final float newDefaultAspectRatio = (DEFAULT_ASPECT_RATIO + MAX_ASPECT_RATIO) / 2;
         final TestableResources res = mContext.getOrCreateTestableResources();
-        res.addOverride(com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio,
+        res.addOverride(R.dimen.config_pictureInPictureDefaultAspectRatio,
                 newDefaultAspectRatio);
 
         mPipBoundsAlgorithm.onConfigurationChanged(mContext);
@@ -463,7 +464,7 @@
     private void overrideDefaultAspectRatio(float aspectRatio) {
         final TestableResources res = mContext.getOrCreateTestableResources();
         res.addOverride(
-                com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio,
+                R.dimen.config_pictureInPictureDefaultAspectRatio,
                 aspectRatio);
         mPipBoundsAlgorithm.onConfigurationChanged(mContext);
     }
@@ -471,7 +472,7 @@
     private void overrideDefaultStackGravity(int stackGravity) {
         final TestableResources res = mContext.getOrCreateTestableResources();
         res.addOverride(
-                com.android.internal.R.integer.config_defaultPictureInPictureGravity,
+                R.integer.config_defaultPictureInPictureGravity,
                 stackGravity);
         mPipBoundsAlgorithm.onConfigurationChanged(mContext);
     }
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/splitscreen/MainStageTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
index c972067..0639ad5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/MainStageTests.java
@@ -67,8 +67,7 @@
 
     @Test
     public void testActiveDeactivate() {
-        mMainStage.activate(mRootTaskInfo.configuration.windowConfiguration.getBounds(), mWct,
-                true /* reparent */);
+        mMainStage.activate(mWct, true /* reparent */);
         assertThat(mMainStage.isActive()).isTrue();
 
         mMainStage.deactivate(mWct);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index 59c377a..19d2a7e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -44,7 +44,6 @@
 
 import android.annotation.NonNull;
 import android.app.ActivityManager;
-import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.view.SurfaceControl;
@@ -421,8 +420,7 @@
                 mock(SurfaceControl.Transaction.class),
                 mock(SurfaceControl.Transaction.class),
                 mock(Transitions.TransitionFinishCallback.class));
-        mMainStage.activate(new Rect(0, 0, 100, 100), new WindowContainerTransaction(),
-                true /* includingTopTask */);
+        mMainStage.activate(new WindowContainerTransaction(), true /* includingTopTask */);
     }
 
     private boolean containsSplitEnter(@NonNull WindowContainerTransaction wct) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 099987a..a6ee8ff 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -41,6 +41,7 @@
 
 import android.app.ActivityManager;
 import android.graphics.Rect;
+import android.view.SurfaceControl;
 import android.window.DisplayAreaInfo;
 import android.window.WindowContainerTransaction;
 
@@ -112,7 +113,7 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mStageCoordinator = spy(createStageCoordinator(/* splitLayout */ null));
+        mStageCoordinator = spy(createStageCoordinator(mSplitLayout));
         doNothing().when(mStageCoordinator).updateActivityOptions(any(), anyInt());
 
         when(mSplitLayout.getBounds1()).thenReturn(mBounds1);
@@ -158,6 +159,9 @@
 
     @Test
     public void testDisplayAreaAppeared_initializesUnfoldControllers() {
+        // Create a stage coordinator with null split layout to test layout init flow.
+        mStageCoordinator = createStageCoordinator(null /* splitLayout */);
+
         mStageCoordinator.onDisplayAreaAppeared(mock(DisplayAreaInfo.class));
 
         verify(mMainUnfoldController).init();
@@ -166,7 +170,6 @@
 
     @Test
     public void testLayoutChanged_topLeftSplitPosition_updatesUnfoldStageBounds() {
-        mStageCoordinator = createStageCoordinator(mSplitLayout);
         mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null);
         clearInvocations(mMainUnfoldController, mSideUnfoldController);
 
@@ -179,7 +182,6 @@
 
     @Test
     public void testLayoutChanged_bottomRightSplitPosition_updatesUnfoldStageBounds() {
-        mStageCoordinator = createStageCoordinator(mSplitLayout);
         mStageCoordinator.setSideStagePosition(SPLIT_POSITION_BOTTOM_OR_RIGHT, null);
         clearInvocations(mMainUnfoldController, mSideUnfoldController);
 
@@ -293,6 +295,13 @@
         assertEquals(mStageCoordinator.getMainStagePosition(), SPLIT_POSITION_BOTTOM_OR_RIGHT);
     }
 
+    @Test
+    public void testFinishEnterSplitScreen_applySurfaceLayout() {
+        mStageCoordinator.finishEnterSplitScreen(new SurfaceControl.Transaction());
+
+        verify(mSplitLayout).applySurfaceChanges(any(), any(), any(), any(), any());
+    }
+
     private StageCoordinator createStageCoordinator(SplitLayout splitLayout) {
         return new SplitTestUtils.TestStageCoordinator(mContext, DEFAULT_DISPLAY,
                 mSyncQueue, mRootTDAOrganizer, mTaskOrganizer, mMainStage, mSideStage,
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/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/storage/IMountService.cpp b/libs/storage/IMountService.cpp
index fd6e6e9..055dbb2 100644
--- a/libs/storage/IMountService.cpp
+++ b/libs/storage/IMountService.cpp
@@ -442,14 +442,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);
diff --git a/libs/storage/include/storage/IMountService.h b/libs/storage/include/storage/IMountService.h
index 2463e02..5b07318 100644
--- a/libs/storage/include/storage/IMountService.h
+++ b/libs/storage/include/storage/IMountService.h
@@ -64,8 +64,8 @@
     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;
diff --git a/location/java/android/location/SatellitePvt.java b/location/java/android/location/SatellitePvt.java
index f140c68..f3e1508 100644
--- a/location/java/android/location/SatellitePvt.java
+++ b/location/java/android/location/SatellitePvt.java
@@ -144,8 +144,8 @@
     private final ClockInfo mClockInfo;
     private final double mIonoDelayMeters;
     private final double mTropoDelayMeters;
-    private final long mTimeOfClock;
-    private final long mTimeOfEphemeris;
+    private final long mTimeOfClockSeconds;
+    private final long mTimeOfEphemerisSeconds;
     private final int mIssueOfDataClock;
     private final int mIssueOfDataEphemeris;
     @EphemerisSource
@@ -457,8 +457,8 @@
             @Nullable ClockInfo clockInfo,
             double ionoDelayMeters,
             double tropoDelayMeters,
-            long timeOfClock,
-            long timeOfEphemeris,
+            long timeOfClockSeconds,
+            long timeOfEphemerisSeconds,
             int issueOfDataClock,
             int issueOfDataEphemeris,
             @EphemerisSource int ephemerisSource) {
@@ -468,8 +468,8 @@
         mClockInfo = clockInfo;
         mIonoDelayMeters = ionoDelayMeters;
         mTropoDelayMeters = tropoDelayMeters;
-        mTimeOfClock = timeOfClock;
-        mTimeOfEphemeris = timeOfEphemeris;
+        mTimeOfClockSeconds = timeOfClockSeconds;
+        mTimeOfEphemerisSeconds = timeOfEphemerisSeconds;
         mIssueOfDataClock = issueOfDataClock;
         mIssueOfDataEphemeris = issueOfDataEphemeris;
         mEphemerisSource = ephemerisSource;
@@ -545,31 +545,31 @@
     }
 
     /**
-     * Time of Clock.
+     * Time of Clock in seconds.
      *
      * <p>The value is in seconds since GPS epoch, regardless of the constellation.
      *
      * <p>The value is not encoded as in GPS ICD200 documentation.
      *
-     * <p>This field is valid if {@link #hasTimeOfClock()} is true.
+     * <p>This field is valid if {@link #hasTimeOfClockSeconds()} is true.
      */
     @IntRange(from = 0)
-    public long getTimeOfClock() {
-        return mTimeOfClock;
+    public long getTimeOfClockSeconds() {
+        return mTimeOfClockSeconds;
     }
 
     /**
-     * Time of ephemeris.
+     * Time of ephemeris in seconds.
      *
      * <p>The value is in seconds since GPS epoch, regardless of the constellation.
      *
      * <p>The value is not encoded as in GPS ICD200 documentation.
      *
-     * <p>This field is valid if {@link #hasTimeOfEphemeris()} is true.
+     * <p>This field is valid if {@link #hasTimeOfEphemerisSeconds()} is true.
      */
     @IntRange(from = 0)
-    public long getTimeOfEphemeris() {
-        return mTimeOfEphemeris;
+    public long getTimeOfEphemerisSeconds() {
+        return mTimeOfEphemerisSeconds;
     }
 
     /**
@@ -607,13 +607,13 @@
         return (mFlags & HAS_ISSUE_OF_DATA_EPHEMERIS) != 0;
     }
 
-    /** Returns {@code true} if {@link #getTimeOfClock()} ()} is valid. */
-    public boolean hasTimeOfClock() {
+    /** Returns {@code true} if {@link #getTimeOfClockSeconds()} ()} is valid. */
+    public boolean hasTimeOfClockSeconds() {
         return (mFlags & HAS_TIME_OF_CLOCK) != 0;
     }
 
-    /** Returns {@code true} if {@link #getTimeOfEphemeris()} is valid. */
-    public boolean hasTimeOfEphemeris() {
+    /** Returns {@code true} if {@link #getTimeOfEphemerisSeconds()} is valid. */
+    public boolean hasTimeOfEphemerisSeconds() {
         return (mFlags & HAS_TIME_OF_EPHEMERIS) != 0;
     }
 
@@ -671,8 +671,8 @@
         parcel.writeParcelable(mClockInfo, flags);
         parcel.writeDouble(mIonoDelayMeters);
         parcel.writeDouble(mTropoDelayMeters);
-        parcel.writeLong(mTimeOfClock);
-        parcel.writeLong(mTimeOfEphemeris);
+        parcel.writeLong(mTimeOfClockSeconds);
+        parcel.writeLong(mTimeOfEphemerisSeconds);
         parcel.writeInt(mIssueOfDataClock);
         parcel.writeInt(mIssueOfDataEphemeris);
         parcel.writeInt(mEphemerisSource);
@@ -687,8 +687,8 @@
                 + ", ClockInfo=" + mClockInfo
                 + ", IonoDelayMeters=" + mIonoDelayMeters
                 + ", TropoDelayMeters=" + mTropoDelayMeters
-                + ", TimeOfClock=" + mTimeOfClock
-                + ", TimeOfEphemeris=" + mTimeOfEphemeris
+                + ", TimeOfClockSeconds=" + mTimeOfClockSeconds
+                + ", TimeOfEphemerisSeconds=" + mTimeOfEphemerisSeconds
                 + ", IssueOfDataClock=" + mIssueOfDataClock
                 + ", IssueOfDataEphemeris=" + mIssueOfDataEphemeris
                 + ", EphemerisSource=" + mEphemerisSource
@@ -709,8 +709,8 @@
         @Nullable private ClockInfo mClockInfo;
         private double mIonoDelayMeters;
         private double mTropoDelayMeters;
-        private long mTimeOfClock;
-        private long mTimeOfEphemeris;
+        private long mTimeOfClockSeconds;
+        private long mTimeOfEphemerisSeconds;
         private int mIssueOfDataClock;
         private int mIssueOfDataEphemeris;
         @EphemerisSource
@@ -796,13 +796,13 @@
          *
          * <p>The value is not encoded as in GPS ICD200 documentation.
          *
-         * @param timeOfClock time of clock (seconds)
+         * @param timeOfClockSeconds time of clock (seconds)
          * @return builder object
          */
         @NonNull
-        public Builder setTimeOfClock(@IntRange(from = 0) long timeOfClock) {
-            Preconditions.checkArgumentNonnegative(timeOfClock);
-            mTimeOfClock = timeOfClock;
+        public Builder setTimeOfClockSeconds(@IntRange(from = 0) long timeOfClockSeconds) {
+            Preconditions.checkArgumentNonnegative(timeOfClockSeconds);
+            mTimeOfClockSeconds = timeOfClockSeconds;
             mFlags = (byte) (mFlags | HAS_TIME_OF_CLOCK);
             return this;
         }
@@ -814,13 +814,13 @@
          *
          * <p>The value is not encoded as in GPS ICD200 documentation.
          *
-         * @param timeOfEphemeris time of ephemeris (seconds)
+         * @param timeOfEphemerisSeconds time of ephemeris (seconds)
          * @return builder object
          */
         @NonNull
-        public Builder setTimeOfEphemeris(@IntRange(from = 0) int timeOfEphemeris) {
-            Preconditions.checkArgumentNonnegative(timeOfEphemeris);
-            mTimeOfEphemeris = timeOfEphemeris;
+        public Builder setTimeOfEphemerisSeconds(@IntRange(from = 0) long timeOfEphemerisSeconds) {
+            Preconditions.checkArgumentNonnegative(timeOfEphemerisSeconds);
+            mTimeOfEphemerisSeconds = timeOfEphemerisSeconds;
             mFlags = (byte) (mFlags | HAS_TIME_OF_EPHEMERIS);
             return this;
         }
@@ -879,7 +879,8 @@
         @NonNull
         public SatellitePvt build() {
             return new SatellitePvt(mFlags, mPositionEcef, mVelocityEcef, mClockInfo,
-                    mIonoDelayMeters, mTropoDelayMeters, mTimeOfClock, mTimeOfEphemeris,
+                    mIonoDelayMeters, mTropoDelayMeters, mTimeOfClockSeconds,
+                    mTimeOfEphemerisSeconds,
                     mIssueOfDataClock, mIssueOfDataEphemeris,
                     mEphemerisSource);
         }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 6e695e6..432196c 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -91,7 +91,6 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 /**
  * AudioManager provides access to volume and ringer mode control.
@@ -5625,27 +5624,33 @@
      * Note that the information may be imprecise when the implementation
      * cannot distinguish whether a particular device is enabled.
      *
-     * {@hide}
+     * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
+     *             will have multi-bit device types.
+     *             Prefer to use {@link #getDevicesForAttributes()} instead,
+     *             noting that getDevicesForStream() has a few small discrepancies
+     *             for better volume handling.
+     * @hide
      */
     @UnsupportedAppUsage
+    @Deprecated
     public int getDevicesForStream(int streamType) {
         switch (streamType) {
-        case STREAM_VOICE_CALL:
-        case STREAM_SYSTEM:
-        case STREAM_RING:
-        case STREAM_MUSIC:
-        case STREAM_ALARM:
-        case STREAM_NOTIFICATION:
-        case STREAM_DTMF:
-        case STREAM_ACCESSIBILITY:
-            final IAudioService service = getService();
-            try {
-                return service.getDevicesForStream(streamType);
-            } catch (RemoteException e) {
-                throw e.rethrowFromSystemServer();
-            }
-        default:
-            return 0;
+            case STREAM_VOICE_CALL:
+            case STREAM_SYSTEM:
+            case STREAM_RING:
+            case STREAM_MUSIC:
+            case STREAM_ALARM:
+            case STREAM_NOTIFICATION:
+            case STREAM_DTMF:
+            case STREAM_ACCESSIBILITY:
+                final IAudioService service = getService();
+                try {
+                    return service.getDeviceMaskForStream(streamType);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            default:
+                return 0;
         }
     }
 
@@ -8349,105 +8354,118 @@
     }
 
     /**
-     * Add UID's that can be considered as assistant.
+     * Add UIDs that can be considered as assistant.
      *
-     * @param assistantUids UID's of the services that can be considered as assistant.
+     * @param assistantUids UIDs of the services that can be considered as assistant.
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public void addAssistantServicesUids(@NonNull List<Integer> assistantUids) {
+    public void addAssistantServicesUids(@NonNull int[] assistantUids) {
         try {
-            getService().addAssistantServicesUids(assistantUids.stream()
-                    .mapToInt(Integer::intValue).toArray());
+            getService().addAssistantServicesUids(assistantUids);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Remove UID's that can be considered as assistant.
+     * Remove UIDs that can be considered as assistant.
      *
-     * @param assistantUids UID'S of the services that should be remove.
+     * @param assistantUids UIDs of the services that should be remove.
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public void removeAssistantServicesUids(@NonNull List<Integer> assistantUids) {
+    public void removeAssistantServicesUids(@NonNull int[] assistantUids) {
         try {
-            getService().removeAssistantServicesUids(assistantUids.stream()
-                    .mapToInt(Integer::intValue).toArray());
+            getService().removeAssistantServicesUids(assistantUids);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Get the list of assistants UIDs that been added with the
-     * {@link #addAssistantServicesUids(List)} (List)} and not yet removed with
-     * {@link #removeAssistantServicesUids(List)}
+     * Get the assistants UIDs that been added with the
+     * {@link #addAssistantServicesUids(int[])} and not yet removed with
+     * {@link #removeAssistantServicesUids(int[])}
      *
-     * @return list of assistants UID's
+     * @return array of assistants UIDs
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public @NonNull List<Integer> getAssistantServicesUids() {
+    public @NonNull int[] getAssistantServicesUids() {
         try {
             int[] uids = getService().getAssistantServicesUids();
-            return Arrays.stream(uids).boxed().collect(Collectors.toList());
+            return Arrays.copyOf(uids, uids.length);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Sets UID's that can be considered as active assistant. Calling the API with a new list will
-     * overwrite previous list. If the list of UIDs is empty then no UID will be considered active.
-     * In this manner calling the API with an empty list will remove all UID's previously set.
+     * Sets UIDs that can be considered as active assistant. Calling the API with a new array will
+     * overwrite previous UIDs. If the array of UIDs is empty then no UID will be considered active.
+     * In this manner calling the API with an empty array will remove all UIDs previously set.
      *
-     * @param assistantUids UID'S of the services that can be considered active assistant. Can be
-     * an empty list, for this no UID will be considered active.
+     * @param assistantUids UIDs of the services that can be considered active assistant. Can be
+     * an empty array, for this no UID will be considered active.
      *
      * <p> Note that during audio service crash reset and after boot up the list of active assistant
-     * UID's will be reset to an empty list (i.e. no UID will be considered as an active assistant).
+     * UIDs will be reset to an empty list (i.e. no UID will be considered as an active assistant).
      * Just after user switch the list of active assistant will also reset to empty.
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public void setActiveAssistantServiceUids(@NonNull List<Integer>  assistantUids) {
+    public void setActiveAssistantServiceUids(@NonNull int[]  assistantUids) {
         try {
-            getService().setActiveAssistantServiceUids(assistantUids.stream()
-                    .mapToInt(Integer::intValue).toArray());
+            getService().setActiveAssistantServiceUids(assistantUids);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Get the list of active assistant UIDs last set with the
-     * {@link #setActiveAssistantServiceUids(List)}
+     * Get active assistant UIDs last set with the
+     * {@link #setActiveAssistantServiceUids(int[])}
      *
-     * @return list of active assistants UID's
+     * @return array of active assistants UIDs
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
-    public @NonNull List<Integer> getActiveAssistantServicesUids() {
+    public @NonNull int[] getActiveAssistantServicesUids() {
         try {
             int[] uids = getService().getActiveAssistantServiceUids();
-            return Arrays.stream(uids).boxed().collect(Collectors.toList());
+            return Arrays.copyOf(uids, uids.length);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
     }
 
+    /**
+     * 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/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 6cacebb..acb34b5 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -29,6 +29,7 @@
 import android.media.audio.common.AidlConversion;
 import android.media.audiofx.AudioEffect;
 import android.media.audiopolicy.AudioMix;
+import android.media.audiopolicy.AudioProductStrategy;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.Parcel;
@@ -47,6 +48,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.TreeSet;
 
 /* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET
  * TO UPDATE THE CORRESPONDING NATIVE GLUE AND AudioManager.java.
@@ -1655,9 +1657,63 @@
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static native boolean getMasterMute();
-    /** @hide */
+    /** @hide
+     * Only used (unsupported) for legacy apps.
+     * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
+     *             will have multi-bit device types.
+     *             Use {@link AudioManager#getDevicesForAttributes(AudioAttributes)} instead.
+     */
     @UnsupportedAppUsage
-    public static native int getDevicesForStream(int stream);
+    @Deprecated
+    public static int getDevicesForStream(int stream) {
+        final AudioAttributes attr =
+                AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
+        return getDeviceMaskFromSet(generateAudioDeviceTypesSet(
+                getDevicesForAttributes(attr, true /* forVolume */)));
+    }
+
+    /** @hide
+     * Conversion from a device set to a bit mask.
+     *
+     * Legacy compatibility method (use a device list instead of a bit mask).
+     * Conversion to bit mask skips multi-bit (S and later) internal device types
+     * (e.g. AudioSystem.DEVICE_OUT* or AudioManager.DEVICE_OUT*) for legacy
+     * compatibility reasons.  Legacy apps will not understand these new device types
+     * and it will raise false matches with old device types.
+     */
+    public static int getDeviceMaskFromSet(@NonNull Set<Integer> deviceSet) {
+        int deviceMask = DEVICE_NONE; // zero.
+        int deviceInChecksum = DEVICE_BIT_IN;
+        for (Integer device : deviceSet) {
+            if ((device & (device - 1) & ~DEVICE_BIT_IN) != 0) {
+                Log.v(TAG, "getDeviceMaskFromSet skipping multi-bit device value " + device);
+                continue;
+            }
+            deviceMask |= device;
+            deviceInChecksum &= device;
+        }
+        // Validate that deviceSet is either ALL input devices or ALL output devices.
+        // We check that the "OR" of all the DEVICE_BIT_INs == the "AND" of all DEVICE_BIT_INs.
+        if (!deviceSet.isEmpty() && deviceInChecksum != (deviceMask & DEVICE_BIT_IN)) {
+            Log.e(TAG, "getDeviceMaskFromSet: Invalid set: " + deviceSetToString(deviceSet));
+        }
+        return deviceMask;
+    }
+
+    /** @hide */
+    @NonNull
+    public static String deviceSetToString(@NonNull Set<Integer> devices) {
+        int n = 0;
+        StringBuilder sb = new StringBuilder();
+        for (Integer device : devices) {
+            if (n++ > 0) {
+                sb.append(", ");
+            }
+            sb.append(AudioSystem.getDeviceName(device));
+            sb.append("(" + Integer.toHexString(device) + ")");
+        }
+        return sb.toString();
+    }
 
     /**
      * @hide
@@ -1668,13 +1724,14 @@
      *   otherwise (typically one device, except for duplicated paths).
      */
     public static @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
-            @NonNull AudioAttributes attributes) {
+            @NonNull AudioAttributes attributes, boolean forVolume) {
         Objects.requireNonNull(attributes);
         final AudioDeviceAttributes[] devices = new AudioDeviceAttributes[MAX_DEVICE_ROUTING];
-        final int res = getDevicesForAttributes(attributes, devices);
+        final int res = getDevicesForAttributes(attributes, devices, forVolume);
         final ArrayList<AudioDeviceAttributes> routeDevices = new ArrayList<>();
         if (res != SUCCESS) {
-            Log.e(TAG, "error " + res + " in getDevicesForAttributes for " + attributes);
+            Log.e(TAG, "error " + res + " in getDevicesForAttributes attributes: " + attributes
+                    + " forVolume: " + forVolume);
             return routeDevices;
         }
 
@@ -1693,7 +1750,8 @@
     private static final int MAX_DEVICE_ROUTING = 4;
 
     private static native int getDevicesForAttributes(@NonNull AudioAttributes aa,
-                                                      @NonNull AudioDeviceAttributes[] devices);
+                                                      @NonNull AudioDeviceAttributes[] devices,
+                                                      boolean forVolume);
 
     /** @hide returns true if master mono is enabled. */
     public static native boolean getMasterMono();
@@ -2250,18 +2308,15 @@
 
     /**
      * @hide
-     * Return a set of audio device types from a bit mask audio device type, which may
+     * Return a set of audio device types from a list of audio device attributes, which may
      * represent multiple audio device types.
-     * FIXME: Remove this when getting ride of bit mask usage of audio device types.
      */
-    public static Set<Integer> generateAudioDeviceTypesSet(int types) {
-        Set<Integer> deviceTypes = new HashSet<>();
-        Set<Integer> allDeviceTypes =
-                (types & DEVICE_BIT_IN) == 0 ? DEVICE_OUT_ALL_SET : DEVICE_IN_ALL_SET;
-        for (int deviceType : allDeviceTypes) {
-            if ((types & deviceType) == deviceType) {
-                deviceTypes.add(deviceType);
-            }
+    @NonNull
+    public static Set<Integer> generateAudioDeviceTypesSet(
+            @NonNull List<AudioDeviceAttributes> deviceList) {
+        Set<Integer> deviceTypes = new TreeSet<>();
+        for (AudioDeviceAttributes device : deviceList) {
+            deviceTypes.add(device.getInternalType());
         }
         return deviceTypes;
     }
@@ -2272,7 +2327,7 @@
      */
     public static Set<Integer> intersectionAudioDeviceTypes(
             @NonNull Set<Integer> a, @NonNull Set<Integer> b) {
-        Set<Integer> intersection = new HashSet<>(a);
+        Set<Integer> intersection = new TreeSet<>(a);
         intersection.retainAll(b);
         return intersection;
     }
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index d702eb9..bdbb740 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -360,7 +360,7 @@
 
     boolean isMusicActive(in boolean remotely);
 
-    int getDevicesForStream(in int streamType);
+    int getDeviceMaskForStream(in int streamType);
 
     int[] getAvailableCommunicationDeviceIds();
 
@@ -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/ImageWriter.java b/media/java/android/media/ImageWriter.java
index e0f04a1..9f52bf1 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -108,7 +108,6 @@
     private long mUsage = HardwareBuffer.USAGE_CPU_WRITE_OFTEN;
     private @HardwareBuffer.Format int mHardwareBufferFormat;
     private @NamedDataSpace int mDataSpace;
-    private boolean mUseLegacyImageFormat;
 
     // Field below is used by native code, do not access or modify.
     private int mWriterFormat;
@@ -257,7 +256,6 @@
                 + ", maxImages: " + maxImages);
         }
 
-        mUseLegacyImageFormat = useLegacyImageFormat;
         // Note that the underlying BufferQueue is working in synchronous mode
         // to avoid dropping any buffers.
         mNativeContext = nativeInit(new WeakReference<>(this), surface, maxImages, width, height,
@@ -334,12 +332,21 @@
             int hardwareBufferFormat, int dataSpace, int width, int height, long usage) {
         mMaxImages = maxImages;
         mUsage = usage;
-        mHardwareBufferFormat = hardwareBufferFormat;
-        mDataSpace = dataSpace;
-        int publicFormat = PublicFormatUtils.getPublicFormat(hardwareBufferFormat, dataSpace);
+        int imageFormat;
+        // if useSurfaceImageFormatInfo is true, imageFormat will be set to UNKNOWN
+        // and retrieve corresponding hardwareBufferFormat and dataSpace here.
+        if (useSurfaceImageFormatInfo) {
+            imageFormat = ImageFormat.UNKNOWN;
+            mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
+            mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
+        } else {
+            imageFormat = PublicFormatUtils.getPublicFormat(hardwareBufferFormat, dataSpace);
+            mHardwareBufferFormat = hardwareBufferFormat;
+            mDataSpace = dataSpace;
+        }
 
         initializeImageWriter(surface, maxImages, useSurfaceImageFormatInfo, false,
-                publicFormat, hardwareBufferFormat, dataSpace, width, height, usage);
+                imageFormat, hardwareBufferFormat, dataSpace, width, height, usage);
     }
 
     /**
@@ -884,27 +891,17 @@
         private @HardwareBuffer.Format int mHardwareBufferFormat = HardwareBuffer.RGBA_8888;
         private @NamedDataSpace int mDataSpace = DataSpace.DATASPACE_UNKNOWN;
         private boolean mUseSurfaceImageFormatInfo = true;
-        // set this as true temporarily now as a workaround to get correct format
-        // when using surface format by default without overriding the image format
-        // in the builder pattern
-        private boolean mUseLegacyImageFormat = true;
+        private boolean mUseLegacyImageFormat = false;
 
         /**
          * Constructs a new builder for {@link ImageWriter}.
          *
-         * <p>Uses {@code surface} input parameter to retrieve image format, hal format
-         * and hal dataspace value for default. </p>
-         *
          * @param surface The destination Surface this writer produces Image data into.
          *
          * @throws IllegalArgumentException if the surface is already abandoned.
          */
         public Builder(@NonNull Surface surface) {
             mSurface = surface;
-            // retrieve format from surface
-            mImageFormat = SurfaceUtils.getSurfaceFormat(surface);
-            mDataSpace = SurfaceUtils.getSurfaceDataspace(surface);
-            mHardwareBufferFormat = PublicFormatUtils.getHalFormat(mImageFormat);
         }
 
         /**
@@ -1058,11 +1055,6 @@
             mWidth = writer.mWidth;
             mHeight = writer.mHeight;
             mDataSpace = writer.mDataSpace;
-
-            if (!mOwner.mUseLegacyImageFormat) {
-                mFormat = PublicFormatUtils.getPublicFormat(
-                    mOwner.mHardwareBufferFormat, mDataSpace);
-            }
         }
 
         @Override
@@ -1083,7 +1075,7 @@
         public int getFormat() {
             throwISEIfImageIsInvalid();
 
-            if (mOwner.mUseLegacyImageFormat && mFormat == -1) {
+            if (mFormat == -1) {
                 mFormat = nativeGetFormat(mDataSpace);
             }
             return mFormat;
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 311476c..47e402f 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,68 @@
                 .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<>();
+        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 +1143,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 +1169,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 +1180,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 +1229,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 +1248,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 +1277,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 +1365,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 +1379,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 +1427,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 +1441,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 +1450,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 +1463,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 +1478,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 +1535,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 +1587,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 +1625,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 +1662,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 +1672,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 +1730,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 +1753,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 +1805,8 @@
             }
 
             synchronized (mLock) {
-                return routeIds.stream().map(mRoutes::get)
+                return routeIds.stream()
+                        .map(mRoutes::get)
                         .filter(Objects::nonNull)
                         .collect(Collectors.toList());
             }
@@ -1799,7 +1841,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 +1871,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 +1898,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 +1927,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 +2017,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 +2047,6 @@
                 return;
             }
 
-
             RoutingController oldController;
             if (oldSession.isSystemSession()) {
                 mSystemController.setRoutingSessionInfo(
@@ -2041,8 +2069,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 +2111,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 cb85109..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,10 +79,13 @@
             RANGE_WITHIN_REACH
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface RangeZone {}
+    public @interface RangeZone {
+    }
 
     /**
      * Gets a human-readable string of the range zone.
+     *
+     * @hide
      */
     @NonNull
     public static String rangeZoneToString(@RangeZone int rangeZone) {
@@ -100,16 +105,26 @@
         }
     }
 
-    @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);
 
-    public NearbyDevice(@NonNull String mediaRoute2Id, int rangeZone) {
+    @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) {
         mMediaRoute2Id = mediaRoute2Id;
         mRangeZone = rangeZone;
     }
 
     private NearbyDevice(@NonNull Parcel in) {
-        mMediaRoute2Id = in.readString();
+        mMediaRoute2Id = in.readString8();
         mRangeZone = in.readInt();
     }
 
@@ -126,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/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 5259c4f..4dde5e8 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -29,7 +29,9 @@
 import android.os.RemoteException;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.ContentRecordingSession;
 import android.view.Surface;
+import android.view.WindowManagerGlobal;
 
 import java.util.Map;
 
@@ -106,16 +108,12 @@
         if (isSecure) {
             flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
         }
-        Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
-                TYPE_APPLICATION, null /* options */);
-        final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
-                height, dpi, windowContext.getWindowContextToken());
-        builder.setFlags(flags);
+        final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
+                height, dpi).setFlags(flags);
         if (surface != null) {
             builder.setSurface(surface);
         }
-        VirtualDisplay virtualDisplay = createVirtualDisplay(builder.build(), callback, handler,
-                windowContext);
+        VirtualDisplay virtualDisplay = createVirtualDisplay(builder, callback, handler);
         return virtualDisplay;
     }
 
@@ -145,38 +143,16 @@
     public VirtualDisplay createVirtualDisplay(@NonNull String name,
             int width, int height, int dpi, int flags, @Nullable Surface surface,
             @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
-        Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(),
-                TYPE_APPLICATION, null /* options */);
-        final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width,
-                height, dpi, windowContext.getWindowContextToken());
-        builder.setFlags(flags);
+        final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
+                height, dpi).setFlags(flags);
         if (surface != null) {
             builder.setSurface(surface);
         }
-        VirtualDisplay virtualDisplay = createVirtualDisplay(builder.build(), callback, handler,
-                windowContext);
+        VirtualDisplay virtualDisplay = createVirtualDisplay(builder, callback, handler);
         return virtualDisplay;
     }
 
     /**
-     * Constructs a {@link VirtualDisplayConfig.Builder}, which will mirror the contents of a
-     * DisplayArea. The DisplayArea to mirror is from the DisplayArea the caller is launched on.
-     *
-     * @param name   The name of the virtual display, must be non-empty.
-     * @param width  The width of the virtual display in pixels. Must be greater than 0.
-     * @param height The height of the virtual display in pixels. Must be greater than 0.
-     * @param dpi    The density of the virtual display in dpi. Must be greater than 0.
-     * @return a config representing a VirtualDisplay
-     */
-    private VirtualDisplayConfig.Builder buildMirroredVirtualDisplay(@NonNull String name,
-            int width, int height, int dpi, IBinder windowContextToken) {
-        final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
-                height, dpi);
-        builder.setWindowTokenClientToMirror(windowContextToken);
-        return builder;
-    }
-
-    /**
      * Creates a {@link android.hardware.display.VirtualDisplay} to capture the
      * contents of the screen.
      *
@@ -186,18 +162,52 @@
      * @param handler The {@link android.os.Handler} on which the callback should be invoked, or
      *                null if the callback should be invoked on the calling thread's main
      *                {@link android.os.Looper}.
-     * @param windowContext the WindowContext associated with the caller.
      *
      * @see android.hardware.display.VirtualDisplay
      * @hide
      */
     @Nullable
-    public VirtualDisplay createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig,
-            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler,
-            Context windowContext) {
-        DisplayManager dm = mContext.getSystemService(DisplayManager.class);
-        return dm.createVirtualDisplay(this, virtualDisplayConfig, callback, handler,
-                windowContext);
+    public VirtualDisplay createVirtualDisplay(
+            @NonNull VirtualDisplayConfig.Builder virtualDisplayConfig,
+            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
+        try {
+            final Context windowContext = mContext.createWindowContext(
+                    mContext.getDisplayNoVerify(),
+                    TYPE_APPLICATION, null /* options */);
+            final IBinder windowContextToken = windowContext.getWindowContextToken();
+            virtualDisplayConfig.setWindowManagerMirroring(true);
+            final DisplayManager dm = mContext.getSystemService(DisplayManager.class);
+            final VirtualDisplay virtualDisplay = dm.createVirtualDisplay(this,
+                    virtualDisplayConfig.build(),
+                    callback, handler, windowContext);
+            setSession(windowContextToken, virtualDisplay);
+            return virtualDisplay;
+        } catch (RemoteException e) {
+            // Can not capture if WMS is not accessible, so bail out.
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Updates the {@link ContentRecordingSession} describing the recording taking place on this
+     * {@link VirtualDisplay}.
+     *
+     * @throws RemoteException if updating the session on the server failed.
+     */
+    private void setSession(@NonNull IBinder windowContextToken,
+            @Nullable VirtualDisplay virtualDisplay)
+            throws RemoteException {
+        if (virtualDisplay == null) {
+            // Not able to set up a new VirtualDisplay.
+            return;
+        }
+        // Identify the VirtualDisplay that will be hosting the recording.
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
+                windowContextToken);
+        session.setDisplayId(virtualDisplay.getDisplay().getDisplayId());
+        // TODO(b/216625226) handle task recording.
+        // Successfully set up, so save the current session details.
+        WindowManagerGlobal.getWindowManagerService().setContentRecordingSession(session);
     }
 
     /**
diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS
index 7e7335d..9ca3910 100644
--- a/media/java/android/media/projection/OWNERS
+++ b/media/java/android/media/projection/OWNERS
@@ -1 +1,2 @@
 michaelwr@google.com
+santoscordon@google.com
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/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index 57730ac..52b00b7 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -986,7 +986,7 @@
             if (DEBUG) {
                 Log.d(TAG, "notifyContentAllowed");
             }
-            notifyContentAllowed();
+            onContentAllowed();
         }
 
         void notifyContentBlocked(TvContentRating rating) {
diff --git a/media/jni/soundpool/Stream.cpp b/media/jni/soundpool/Stream.cpp
index 50bb79c..9ed8770 100644
--- a/media/jni/soundpool/Stream.cpp
+++ b/media/jni/soundpool/Stream.cpp
@@ -15,6 +15,7 @@
  */
 
 //#define LOG_NDEBUG 0
+#include <utility>
 #define LOG_TAG "SoundPool::Stream"
 #include <utils/Log.h>
 #include <android/content/AttributionSourceState.h>
@@ -309,13 +310,11 @@
     }
     if (mAudioTrack == nullptr) {
         // mToggle toggles each time a track is started on a given stream.
-        // The toggle is concatenated with the Stream address and passed to AudioTrack
-        // as callback user data. This enables the detection of callbacks received from the old
+        // This enables the detection of callbacks received from the old
         // audio track while the new one is being started and avoids processing them with
         // wrong audio audio buffer size  (mAudioBufferSize)
         auto toggle = mToggle ^ 1;
         // NOLINTNEXTLINE(performance-no-int-to-ptr)
-        void* userData = reinterpret_cast<void*>((uintptr_t)this | toggle);
         audio_channel_mask_t soundChannelMask = sound->getChannelMask();
         // When sound contains a valid channel mask, use it as is.
         // Otherwise, use stream count to calculate channel mask.
@@ -327,10 +326,11 @@
         android::content::AttributionSourceState attributionSource;
         attributionSource.packageName = mStreamManager->getOpPackageName();
         attributionSource.token = sp<BBinder>::make();
+        mCallback =  sp<StreamCallback>::make(this, toggle),
         // TODO b/182469354 make consistent with AudioRecord, add util for native source
         mAudioTrack = new AudioTrack(streamType, sampleRate, sound->getFormat(),
                 channelMask, sound->getIMemory(), AUDIO_OUTPUT_FLAG_FAST,
-                staticCallback, userData,
+                mCallback,
                 0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
                 AudioTrack::TRANSFER_DEFAULT,
                 nullptr /*offloadInfo*/, attributionSource,
@@ -375,16 +375,55 @@
     mStreamID = nextStreamID;  // prefer this to be the last, as it is an atomic sync point
 }
 
-/* static */
-void Stream::staticCallback(int event, void* user, void* info)
-{
-    const auto userAsInt = (uintptr_t)user;
-    // NOLINTNEXTLINE(performance-no-int-to-ptr)
-    auto stream = reinterpret_cast<Stream*>(userAsInt & ~1);
-    stream->callback(event, info, int(userAsInt & 1), 0 /* tries */);
+int Stream::getCorrespondingStreamID() {
+    std::lock_guard lock(mLock);
+    return static_cast<int>(mAudioTrack ? mStreamID : getPairStream()->mStreamID);
+}
+size_t Stream::StreamCallback::onMoreData(const AudioTrack::Buffer&) {
+    ALOGW("%s streamID %d Unexpected EVENT_MORE_DATA for static track",
+            __func__, mStream->getCorrespondingStreamID());
+    return 0;
 }
 
-void Stream::callback(int event, void* info, int toggle, int tries)
+void Stream::StreamCallback::onUnderrun() {
+    ALOGW("%s streamID %d Unexpected EVENT_UNDERRUN for static track",
+            __func__, mStream->getCorrespondingStreamID());
+}
+
+void Stream::StreamCallback::onLoopEnd(int32_t) {
+    ALOGV("%s streamID %d EVENT_LOOP_END", __func__, mStream->getCorrespondingStreamID());
+}
+
+void Stream::StreamCallback::onMarker(uint32_t) {
+    ALOGW("%s streamID %d Unexpected EVENT_MARKER for static track",
+            __func__, mStream->getCorrespondingStreamID());
+}
+
+void Stream::StreamCallback::onNewPos(uint32_t) {
+    ALOGW("%s streamID %d Unexpected EVENT_NEW_POS for static track",
+            __func__, mStream->getCorrespondingStreamID());
+}
+
+void Stream::StreamCallback::onBufferEnd() {
+    mStream->onBufferEnd(mToggle, 0);
+}
+
+void Stream::StreamCallback::onNewIAudioTrack() {
+    ALOGV("%s streamID %d NEW_IAUDIOTRACK", __func__, mStream->getCorrespondingStreamID());
+}
+
+void Stream::StreamCallback::onStreamEnd() {
+    ALOGW("%s streamID %d Unexpected EVENT_STREAM_END for static track",
+            __func__, mStream->getCorrespondingStreamID());
+}
+
+size_t Stream::StreamCallback::onCanWriteMoreData(const AudioTrack::Buffer&) {
+    ALOGW("%s streamID %d Unexpected EVENT_CAN_WRITE_MORE_DATA for static track",
+            __func__, mStream->getCorrespondingStreamID());
+    return 0;
+}
+
+void Stream::onBufferEnd(int toggle, int tries)
 {
     int32_t activeStreamIDToRestart = 0;
     {
@@ -400,7 +439,7 @@
             if (tries < 3) {
                 lock.unlock();
                 ALOGV("%s streamID %d going to pair stream", __func__, (int)mStreamID);
-                getPairStream()->callback(event, info, toggle, tries + 1);
+                getPairStream()->onBufferEnd(toggle, tries + 1);
             } else {
                 ALOGW("%s streamID %d cannot find track", __func__, (int)mStreamID);
             }
@@ -410,31 +449,10 @@
             ALOGD("%s streamID %d wrong toggle", __func__, (int)mStreamID);
             return;
         }
-        switch (event) {
-        case AudioTrack::EVENT_MORE_DATA:
-            ALOGW("%s streamID %d Invalid EVENT_MORE_DATA for static track",
-                    __func__, (int)mStreamID);
-            break;
-        case AudioTrack::EVENT_UNDERRUN:
-            ALOGW("%s streamID %d Invalid EVENT_UNDERRUN for static track",
-                    __func__, (int)mStreamID);
-            break;
-        case AudioTrack::EVENT_BUFFER_END:
-            ALOGV("%s streamID %d EVENT_BUFFER_END", __func__, (int)mStreamID);
-            if (mState != IDLE) {
-                activeStreamIDToRestart = mStreamID;
-                mStopTimeNs = systemTime();
-            }
-            break;
-        case AudioTrack::EVENT_LOOP_END:
-            ALOGV("%s streamID %d EVENT_LOOP_END", __func__, (int)mStreamID);
-            break;
-        case AudioTrack::EVENT_NEW_IAUDIOTRACK:
-            ALOGV("%s streamID %d NEW_IAUDIOTRACK", __func__, (int)mStreamID);
-            break;
-        default:
-            ALOGW("%s streamID %d Invalid event %d", __func__, (int)mStreamID, event);
-            break;
+        ALOGV("%s streamID %d EVENT_BUFFER_END", __func__, (int)mStreamID);
+        if (mState != IDLE) {
+            activeStreamIDToRestart = mStreamID;
+            mStopTimeNs = systemTime();
         }
     } // lock ends here.  This is on the callback thread, no need to be precise.
     if (activeStreamIDToRestart > 0) {
diff --git a/media/jni/soundpool/Stream.h b/media/jni/soundpool/Stream.h
index aa0eef5..0054eec 100644
--- a/media/jni/soundpool/Stream.h
+++ b/media/jni/soundpool/Stream.h
@@ -124,6 +124,35 @@
     // This never changes.  See top of header.
     Stream* getPairStream() const;
 
+    // Stream ID of ourselves, or the pair depending on who holds the AudioTrack
+    int getCorrespondingStreamID();
+
+protected:
+    // AudioTrack callback interface implementation
+    class StreamCallback : public AudioTrack::IAudioTrackCallback {
+      public:
+        StreamCallback(Stream * stream, bool toggle) : mStream(stream), mToggle(toggle) {}
+        size_t onMoreData(const AudioTrack::Buffer& buffer) override;
+        void onUnderrun() override;
+        void onLoopEnd(int32_t loopsRemaining) override;
+        void onMarker(uint32_t markerPosition) override;
+        void onNewPos(uint32_t newPos) override;
+        void onBufferEnd() override;
+        void onNewIAudioTrack() override;
+        void onStreamEnd() override;
+        size_t onCanWriteMoreData(const AudioTrack::Buffer& buffer) override;
+
+        // Holding a raw ptr is technically unsafe, but, Stream objects persist
+        // through the lifetime of the StreamManager through the use of a
+        // unique_ptr<Stream[]>. Ensuring lifetime will cause us to give up
+        // locality as well as pay RefBase/sp performance cost, which we are
+        // unwilling to do. Non-owning refs to unique_ptrs are idiomatically raw
+        // ptrs, as below.
+        Stream * const mStream;
+        const bool mToggle;
+    };
+
+    sp<StreamCallback> mCallback;
 private:
     // garbage is used to release tracks and data outside of any lock.
     void play_l(const std::shared_ptr<Sound>& sound, int streamID,
@@ -133,9 +162,7 @@
     void setVolume_l(float leftVolume, float rightVolume) REQUIRES(mLock);
 
     // For use with AudioTrack callback.
-    static void staticCallback(int event, void* user, void* info);
-    void callback(int event, void* info, int toggle, int tries)
-            NO_THREAD_SAFETY_ANALYSIS; // uses unique_lock
+    void onBufferEnd(int toggle, int tries) NO_THREAD_SAFETY_ANALYSIS;
 
     // StreamManager should be set on construction and not changed.
     // release mLock before calling into StreamManager
diff --git a/media/jni/tuner/FilterClient.cpp b/media/jni/tuner/FilterClient.cpp
index 959e756..bd960e7 100644
--- a/media/jni/tuner/FilterClient.cpp
+++ b/media/jni/tuner/FilterClient.cpp
@@ -262,6 +262,7 @@
 
     if (mTunerFilter != nullptr) {
         Status s = mTunerFilter->getQueueDesc(&aidlMqDesc);
+        res = ClientHelper::getServiceSpecificErrorCode(s);
         if (s.isOk()) {
             mFilterMQ = new (nothrow) AidlMQ(aidlMqDesc, false/*resetPointer*/);
             EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterMQEventFlag);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BluetoothProfileConnectionInfoTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BluetoothProfileConnectionInfoTest.java
deleted file mode 100644
index f23794b..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BluetoothProfileConnectionInfoTest.java
+++ /dev/null
@@ -1,72 +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.mediaframeworktest.unit;
-
-import static org.junit.Assert.assertEquals;
-
-import android.bluetooth.BluetoothProfile;
-import android.media.BluetoothProfileConnectionInfo;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class BluetoothProfileConnectionInfoTest {
-
-    @Test
-    public void testCoverageA2dp() {
-        final boolean supprNoisy = false;
-        final int volume = 42;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createA2dpInfo(supprNoisy, volume);
-        assertEquals(info.getProfile(), BluetoothProfile.A2DP);
-        assertEquals(info.isSuppressNoisyIntent(), supprNoisy);
-        assertEquals(info.getVolume(), volume);
-    }
-
-    @Test
-    public void testCoverageA2dpSink() {
-        final int volume = 42;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createA2dpSinkInfo(volume);
-        assertEquals(info.getProfile(), BluetoothProfile.A2DP_SINK);
-        assertEquals(info.getVolume(), volume);
-    }
-
-    @Test
-    public void testCoveragehearingAid() {
-        final boolean supprNoisy = true;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createHearingAidInfo(supprNoisy);
-        assertEquals(info.getProfile(), BluetoothProfile.HEARING_AID);
-        assertEquals(info.isSuppressNoisyIntent(), supprNoisy);
-    }
-
-    @Test
-    public void testCoverageLeAudio() {
-        final boolean supprNoisy = false;
-        final boolean isLeOutput = true;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createLeAudioInfo(supprNoisy, isLeOutput);
-        assertEquals(info.getProfile(), BluetoothProfile.LE_AUDIO);
-        assertEquals(info.isSuppressNoisyIntent(), supprNoisy);
-        assertEquals(info.isLeOutput(), isLeOutput);
-    }
-}
-
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index 0c36051..65428de 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -48,6 +48,7 @@
     static APerformanceHintManager* create(sp<IHintManager> iHintManager);
 
     sp<IHintManager> mHintManager;
+    const sp<IBinder> mToken = sp<BBinder>::make();
     const int64_t mPreferredRateNanos;
 };
 
@@ -119,11 +120,10 @@
 
 APerformanceHintSession* APerformanceHintManager::createSession(
         const int32_t* threadIds, size_t size, int64_t initialTargetWorkDurationNanos) {
-    sp<IBinder> token = sp<BBinder>::make();
     std::vector<int32_t> tids(threadIds, threadIds + size);
     sp<IHintSession> session;
     binder::Status ret =
-            mHintManager->createHintSession(token, tids, initialTargetWorkDurationNanos, &session);
+            mHintManager->createHintSession(mToken, tids, initialTargetWorkDurationNanos, &session);
     if (!ret.isOk() || !session) {
         return nullptr;
     }
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/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 6eff629..1ebdc27 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -17,18 +17,15 @@
 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
 #include <android/native_window.h>
 #include <android/surface_control.h>
-#include <surface_control_private.h>
-
 #include <configstore/Utils.h>
-
 #include <gui/HdrMetadata.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 #include <gui/SurfaceControl.h>
-
+#include <private/android/choreographer.h>
+#include <surface_control_private.h>
 #include <ui/DynamicDisplayInfo.h>
-
 #include <utils/Timers.h>
 
 using namespace android::hardware::configstore;
@@ -671,7 +668,7 @@
 void ASurfaceTransaction_setFrameTimeline(ASurfaceTransaction* aSurfaceTransaction,
                                           AVsyncId vsyncId) {
     CHECK_NOT_NULL(aSurfaceTransaction);
-    // TODO(b/210043506): Get start time from platform.
+    const auto startTime = AChoreographer_getStartTimeNanosForVsyncId(vsyncId);
     ASurfaceTransaction_to_Transaction(aSurfaceTransaction)
-            ->setFrameTimelineInfo({.vsyncId = vsyncId, .startTimeNanos = 0});
+            ->setFrameTimelineInfo({.vsyncId = vsyncId, .startTimeNanos = startTime});
 }
diff --git a/obex/Android.bp b/obex/Android.bp
index 37e7f76..d89d41d 100644
--- a/obex/Android.bp
+++ b/obex/Android.bp
@@ -44,6 +44,8 @@
     ],
 }
 
+// No longer used. Only kept because the ObexPacket class is a public API.
+// The library has been migrated to platform/external/obex.
 java_sdk_library {
     name: "javax.obex",
     srcs: ["javax/**/*.java"],
diff --git a/obex/javax/obex/ApplicationParameter.java b/obex/javax/obex/ApplicationParameter.java
deleted file mode 100644
index 16770a1a..0000000
--- a/obex/javax/obex/ApplicationParameter.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-/**
- * @hide
- */
-public final class ApplicationParameter {
-
-    private byte[] mArray;
-
-    private int mLength;
-
-    private int mMaxLength = 1000;
-
-    public static class TRIPLET_TAGID {
-        public static final byte ORDER_TAGID = 0x01;
-
-        public static final byte SEARCH_VALUE_TAGID = 0x02;
-
-        public static final byte SEARCH_ATTRIBUTE_TAGID = 0x03;
-
-        // if equals to "0", PSE only reply number of contacts
-        public static final byte MAXLISTCOUNT_TAGID = 0x04;
-
-        public static final byte LISTSTARTOFFSET_TAGID = 0x05;
-
-        public static final byte PROPERTY_SELECTOR_TAGID = 0x06;
-
-        public static final byte FORMAT_TAGID = 0x07;
-
-        // only used if max list count = 0
-        public static final byte PHONEBOOKSIZE_TAGID = 0x08;
-
-        // only used in "mch" in response
-        public static final byte NEWMISSEDCALLS_TAGID = 0x09;
-
-        public static final byte SUPPORTEDFEATURE_TAGID = 0x10;
-
-        public static final byte PRIMARYVERSIONCOUNTER_TAGID = 0x0A;
-
-        public static final byte SECONDARYVERSIONCOUNTER_TAGID = 0x0B;
-
-        public static final byte VCARDSELECTOR_TAGID = 0x0C;
-
-        public static final byte DATABASEIDENTIFIER_TAGID = 0x0D;
-
-        public static final byte VCARDSELECTOROPERATOR_TAGID = 0x0E;
-
-        public static final byte RESET_NEW_MISSED_CALLS_TAGID = 0x0F;
-    }
-
-    public static class TRIPLET_VALUE {
-        public static class ORDER {
-            public static final byte ORDER_BY_INDEX = 0x00;
-
-            public static final byte ORDER_BY_ALPHANUMERIC = 0x01;
-
-            public static final byte ORDER_BY_PHONETIC = 0x02;
-        }
-
-        public static class SEARCHATTRIBUTE {
-            public static final byte SEARCH_BY_NAME = 0x00;
-
-            public static final byte SEARCH_BY_NUMBER = 0x01;
-
-            public static final byte SEARCH_BY_SOUND = 0x02;
-        }
-
-        public static class FORMAT {
-            public static final byte VCARD_VERSION_21 = 0x00;
-
-            public static final byte VCARD_VERSION_30 = 0x01;
-        }
-    }
-
-    public static class TRIPLET_LENGTH {
-        public static final byte ORDER_LENGTH = 1;
-
-        public static final byte SEARCH_ATTRIBUTE_LENGTH = 1;
-
-        public static final byte MAXLISTCOUNT_LENGTH = 2;
-
-        public static final byte LISTSTARTOFFSET_LENGTH = 2;
-
-        public static final byte PROPERTY_SELECTOR_LENGTH = 8;
-
-        public static final byte FORMAT_LENGTH = 1;
-
-        public static final byte PHONEBOOKSIZE_LENGTH = 2;
-
-        public static final byte NEWMISSEDCALLS_LENGTH = 1;
-
-        public static final byte SUPPORTEDFEATURE_LENGTH = 4;
-
-        public static final byte PRIMARYVERSIONCOUNTER_LENGTH = 16;
-
-        public static final byte SECONDARYVERSIONCOUNTER_LENGTH = 16;
-
-        public static final byte VCARDSELECTOR_LENGTH = 8;
-
-        public static final byte DATABASEIDENTIFIER_LENGTH = 16;
-
-        public static final byte VCARDSELECTOROPERATOR_LENGTH = 1;
-
-        public static final byte RESETNEWMISSEDCALLS_LENGTH = 1;
-    }
-
-    public ApplicationParameter() {
-        mArray = new byte[mMaxLength];
-        mLength = 0;
-    }
-
-    public void addAPPHeader(byte tag, byte len, byte[] value) {
-        if ((mLength + len + 2) > mMaxLength) {
-            byte[] array_tmp = new byte[mLength + 4 * len];
-            System.arraycopy(mArray, 0, array_tmp, 0, mLength);
-            mArray = array_tmp;
-            mMaxLength = mLength + 4 * len;
-        }
-        mArray[mLength++] = tag;
-        mArray[mLength++] = len;
-        System.arraycopy(value, 0, mArray, mLength, len);
-        mLength += len;
-    }
-
-    public byte[] getAPPparam() {
-        byte[] para = new byte[mLength];
-        System.arraycopy(mArray, 0, para, 0, mLength);
-        return para;
-    }
-}
diff --git a/obex/javax/obex/Authenticator.java b/obex/javax/obex/Authenticator.java
deleted file mode 100644
index ec226fb..0000000
--- a/obex/javax/obex/Authenticator.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-/**
- * This interface provides a way to respond to authentication challenge and
- * authentication response headers. When a client or server receives an
- * authentication challenge or authentication response header, the
- * <code>onAuthenticationChallenge()</code> or
- * <code>onAuthenticationResponse()</code> will be called, respectively, by the
- * implementation.
- * <P>
- * For more information on how the authentication procedure works in OBEX,
- * please review the IrOBEX specification at <A
- * HREF="http://www.irda.org">http://www.irda.org</A>.
- * <P>
- * <STRONG>Authentication Challenges</STRONG>
- * <P>
- * When a client or server receives an authentication challenge header, the
- * <code>onAuthenticationChallenge()</code> method will be invoked by the OBEX
- * API implementation. The application will then return the user name (if
- * needed) and password via a <code>PasswordAuthentication</code> object. The
- * password in this object is not sent in the authentication response. Instead,
- * the 16-byte challenge received in the authentication challenge is combined
- * with the password returned from the <code>onAuthenticationChallenge()</code>
- * method and passed through the MD5 hash algorithm. The resulting value is sent
- * in the authentication response along with the user name if it was provided.
- * <P>
- * <STRONG>Authentication Responses</STRONG>
- * <P>
- * When a client or server receives an authentication response header, the
- * <code>onAuthenticationResponse()</code> method is invoked by the API
- * implementation with the user name received in the authentication response
- * header. (The user name will be <code>null</code> if no user name was provided
- * in the authentication response header.) The application must determine the
- * correct password. This value should be returned from the
- * <code>onAuthenticationResponse()</code> method. If the authentication request
- * should fail without the implementation checking the password,
- * <code>null</code> should be returned by the application. (This is needed for
- * reasons like not recognizing the user name, etc.) If the returned value is
- * not <code>null</code>, the OBEX API implementation will combine the password
- * returned from the <code>onAuthenticationResponse()</code> method and
- * challenge sent via the authentication challenge, apply the MD5 hash
- * algorithm, and compare the result to the response hash received in the
- * authentication response header. If the values are not equal, an
- * <code>IOException</code> will be thrown if the client requested
- * authentication. If the server requested authentication, the
- * <code>onAuthenticationFailure()</code> method will be called on the
- * <code>ServerRequestHandler</code> that failed authentication. The connection
- * is <B>not</B> closed if authentication failed.
- * @hide
- */
-public interface Authenticator {
-
-    /**
-     * Called when a client or a server receives an authentication challenge
-     * header. It should respond to the challenge with a
-     * <code>PasswordAuthentication</code> that contains the correct user name
-     * and password for the challenge.
-     * @param description the description of which user name and password should
-     *        be used; if no description is provided in the authentication
-     *        challenge or the description is encoded in an encoding scheme that
-     *        is not supported, an empty string will be provided
-     * @param isUserIdRequired <code>true</code> if the user ID is required;
-     *        <code>false</code> if the user ID is not required
-     * @param isFullAccess <code>true</code> if full access to the server will
-     *        be granted; <code>false</code> if read only access will be granted
-     * @return a <code>PasswordAuthentication</code> object containing the user
-     *         name and password used for authentication
-     */
-    PasswordAuthentication onAuthenticationChallenge(String description, boolean isUserIdRequired,
-            boolean isFullAccess);
-
-    /**
-     * Called when a client or server receives an authentication response
-     * header. This method will provide the user name and expect the correct
-     * password to be returned.
-     * @param userName the user name provided in the authentication response; may
-     *        be <code>null</code>
-     * @return the correct password for the user name provided; if
-     *         <code>null</code> is returned then the authentication request
-     *         failed
-     */
-    byte[] onAuthenticationResponse(byte[] userName);
-}
diff --git a/obex/javax/obex/BaseStream.java b/obex/javax/obex/BaseStream.java
deleted file mode 100644
index 022ad4f..0000000
--- a/obex/javax/obex/BaseStream.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.IOException;
-
-/**
- * This interface defines the methods needed by a parent that uses the
- * PrivateInputStream and PrivateOutputStream objects defined in this package.
- * @hide
- */
-public interface BaseStream {
-
-    /**
-     * Verifies that this object is still open.
-     * @throws IOException if the object is closed
-     */
-    void ensureOpen() throws IOException;
-
-    /**
-     * Verifies that additional information may be sent. In other words, the
-     * operation is not done.
-     * @throws IOException if the operation is completed
-     */
-    void ensureNotDone() throws IOException;
-
-    /**
-     * Continues the operation since there is no data to read.
-     * @param sendEmpty <code>true</code> if the operation should send an empty
-     *        packet or not send anything if there is no data to send
-     * @param inStream <code>true</code> if the stream is input stream or is
-     *        output stream
-     * @return <code>true</code> if the operation was completed;
-     *         <code>false</code> if no operation took place
-     * @throws IOException if an IO error occurs
-     */
-    boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException;
-
-    /**
-     * Called when the output or input stream is closed.
-     * @param inStream <code>true</code> if the input stream is closed;
-     *        <code>false</code> if the output stream is closed
-     * @throws IOException if an IO error occurs
-     */
-    void streamClosed(boolean inStream) throws IOException;
-}
diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java
deleted file mode 100644
index c627dfb..0000000
--- a/obex/javax/obex/ClientOperation.java
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Copyright (c) 2015 The Android Open Source Project
- * Copyright (C) 2015 Samsung LSI
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.ByteArrayOutputStream;
-
-import android.util.Log;
-
-/**
- * This class implements the <code>Operation</code> interface. It will read and
- * write data via puts and gets.
- * @hide
- */
-public final class ClientOperation implements Operation, BaseStream {
-
-    private static final String TAG = "ClientOperation";
-
-    private static final boolean V = ObexHelper.VDBG;
-
-    private ClientSession mParent;
-
-    private boolean mInputOpen;
-
-    private PrivateInputStream mPrivateInput;
-
-    private boolean mPrivateInputOpen;
-
-    private PrivateOutputStream mPrivateOutput;
-
-    private boolean mPrivateOutputOpen;
-
-    private String mExceptionMessage;
-
-    private int mMaxPacketSize;
-
-    private boolean mOperationDone;
-
-    private boolean mGetOperation;
-
-    private boolean mGetFinalFlag;
-
-    private HeaderSet mRequestHeader;
-
-    private HeaderSet mReplyHeader;
-
-    private boolean mEndOfBodySent;
-
-    private boolean mSendBodyHeader = true;
-    // A latch - when triggered, there is not way back ;-)
-    private boolean mSrmActive = false;
-
-    // Assume SRM disabled - until support is confirmed
-    // by the server
-    private boolean mSrmEnabled = false;
-    // keep waiting until final-bit is received in request
-    // to handle the case where the SRM enable header is in
-    // a different OBEX packet than the SRMP header.
-    private boolean mSrmWaitingForRemote = true;
-
-
-    /**
-     * Creates new OperationImpl to read and write data to a server
-     * @param maxSize the maximum packet size
-     * @param p the parent to this object
-     * @param type <code>true</code> if this is a get request;
-     *        <code>false</code. if this is a put request
-     * @param header the header to set in the initial request
-     * @throws IOException if the an IO error occurred
-     */
-    public ClientOperation(int maxSize, ClientSession p, HeaderSet header, boolean type)
-            throws IOException {
-
-        mParent = p;
-        mEndOfBodySent = false;
-        mInputOpen = true;
-        mOperationDone = false;
-        mMaxPacketSize = maxSize;
-        mGetOperation = type;
-        mGetFinalFlag = false;
-
-        mPrivateInputOpen = false;
-        mPrivateOutputOpen = false;
-        mPrivateInput = null;
-        mPrivateOutput = null;
-
-        mReplyHeader = new HeaderSet();
-
-        mRequestHeader = new HeaderSet();
-
-        int[] headerList = header.getHeaderList();
-
-        if (headerList != null) {
-
-            for (int i = 0; i < headerList.length; i++) {
-                mRequestHeader.setHeader(headerList[i], header.getHeader(headerList[i]));
-            }
-        }
-
-        if ((header).mAuthChall != null) {
-            mRequestHeader.mAuthChall = new byte[(header).mAuthChall.length];
-            System.arraycopy((header).mAuthChall, 0, mRequestHeader.mAuthChall, 0,
-                    (header).mAuthChall.length);
-        }
-
-        if ((header).mAuthResp != null) {
-            mRequestHeader.mAuthResp = new byte[(header).mAuthResp.length];
-            System.arraycopy((header).mAuthResp, 0, mRequestHeader.mAuthResp, 0,
-                    (header).mAuthResp.length);
-
-        }
-
-        if ((header).mConnectionID != null) {
-            mRequestHeader.mConnectionID = new byte[4];
-            System.arraycopy((header).mConnectionID, 0, mRequestHeader.mConnectionID, 0,
-                    4);
-
-        }
-    }
-
-    /**
-     * Allows to set flag which will force GET to be always sent as single packet request with
-     * final flag set. This is to improve compatibility with some profiles, i.e. PBAP which
-     * require requests to be sent this way.
-     */
-    public void setGetFinalFlag(boolean flag) {
-        mGetFinalFlag = flag;
-    }
-
-    /**
-     * Sends an ABORT message to the server. By calling this method, the
-     * corresponding input and output streams will be closed along with this
-     * object.
-     * @throws IOException if the transaction has already ended or if an OBEX
-     *         server called this method
-     */
-    public synchronized void abort() throws IOException {
-        ensureOpen();
-        //no compatible with sun-ri
-        if ((mOperationDone) && (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE)) {
-            throw new IOException("Operation has already ended");
-        }
-
-        mExceptionMessage = "Operation aborted";
-        if ((!mOperationDone) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
-            mOperationDone = true;
-            /*
-             * Since we are not sending any headers or returning any headers then
-             * we just need to write and read the same bytes
-             */
-            mParent.sendRequest(ObexHelper.OBEX_OPCODE_ABORT, null, mReplyHeader, null, false);
-
-            if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_OK) {
-                throw new IOException("Invalid response code from server");
-            }
-
-            mExceptionMessage = null;
-        }
-
-        close();
-    }
-
-    /**
-     * Retrieves the response code retrieved from the server. Response codes are
-     * defined in the <code>ResponseCodes</code> interface.
-     * @return the response code retrieved from the server
-     * @throws IOException if an error occurred in the transport layer during
-     *         the transaction; if this method is called on a
-     *         <code>HeaderSet</code> object created by calling
-     *         <code>createHeaderSet</code> in a <code>ClientSession</code>
-     *         object
-     */
-    public synchronized int getResponseCode() throws IOException {
-        if ((mReplyHeader.responseCode == -1)
-                || (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
-            validateConnection();
-        }
-
-        return mReplyHeader.responseCode;
-    }
-
-    /**
-     * This method will always return <code>null</code>
-     * @return <code>null</code>
-     */
-    public String getEncoding() {
-        return null;
-    }
-
-    /**
-     * Returns the type of content that the resource connected to is providing.
-     * E.g. if the connection is via HTTP, then the value of the content-type
-     * header field is returned.
-     * @return the content type of the resource that the URL references, or
-     *         <code>null</code> if not known
-     */
-    public String getType() {
-        try {
-            return (String)mReplyHeader.getHeader(HeaderSet.TYPE);
-        } catch (IOException e) {
-            if(V) Log.d(TAG, "Exception occured - returning null",e);
-            return null;
-        }
-    }
-
-    /**
-     * Returns the length of the content which is being provided. E.g. if the
-     * connection is via HTTP, then the value of the content-length header field
-     * is returned.
-     * @return the content length of the resource that this connection's URL
-     *         references, or -1 if the content length is not known
-     */
-    public long getLength() {
-        try {
-            Long temp = (Long)mReplyHeader.getHeader(HeaderSet.LENGTH);
-
-            if (temp == null) {
-                return -1;
-            } else {
-                return temp.longValue();
-            }
-        } catch (IOException e) {
-            if(V) Log.d(TAG,"Exception occured - returning -1",e);
-            return -1;
-        }
-    }
-
-    /**
-     * Open and return an input stream for a connection.
-     * @return an input stream
-     * @throws IOException if an I/O error occurs
-     */
-    public InputStream openInputStream() throws IOException {
-
-        ensureOpen();
-
-        if (mPrivateInputOpen)
-            throw new IOException("no more input streams available");
-        if (mGetOperation) {
-            // send the GET request here
-            validateConnection();
-        } else {
-            if (mPrivateInput == null) {
-                mPrivateInput = new PrivateInputStream(this);
-            }
-        }
-
-        mPrivateInputOpen = true;
-
-        return mPrivateInput;
-    }
-
-    /**
-     * Open and return a data input stream for a connection.
-     * @return an input stream
-     * @throws IOException if an I/O error occurs
-     */
-    public DataInputStream openDataInputStream() throws IOException {
-        return new DataInputStream(openInputStream());
-    }
-
-    /**
-     * Open and return an output stream for a connection.
-     * @return an output stream
-     * @throws IOException if an I/O error occurs
-     */
-    public OutputStream openOutputStream() throws IOException {
-
-        ensureOpen();
-        ensureNotDone();
-
-        if (mPrivateOutputOpen)
-            throw new IOException("no more output streams available");
-
-        if (mPrivateOutput == null) {
-            // there are 3 bytes operation headers and 3 bytes body headers //
-            mPrivateOutput = new PrivateOutputStream(this, getMaxPacketSize());
-        }
-
-        mPrivateOutputOpen = true;
-
-        return mPrivateOutput;
-    }
-
-    public int getMaxPacketSize() {
-        return mMaxPacketSize - 6 - getHeaderLength();
-    }
-
-    public int getHeaderLength() {
-        // OPP may need it
-        byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false);
-        return headerArray.length;
-    }
-
-    /**
-     * Open and return a data output stream for a connection.
-     * @return an output stream
-     * @throws IOException if an I/O error occurs
-     */
-    public DataOutputStream openDataOutputStream() throws IOException {
-        return new DataOutputStream(openOutputStream());
-    }
-
-    /**
-     * Closes the connection and ends the transaction
-     * @throws IOException if the operation has already ended or is closed
-     */
-    public void close() throws IOException {
-        mInputOpen = false;
-        mPrivateInputOpen = false;
-        mPrivateOutputOpen = false;
-        mParent.setRequestInactive();
-    }
-
-    /**
-     * Returns the headers that have been received during the operation.
-     * Modifying the object returned has no effect on the headers that are sent
-     * or retrieved.
-     * @return the headers received during this <code>Operation</code>
-     * @throws IOException if this <code>Operation</code> has been closed
-     */
-    public HeaderSet getReceivedHeader() throws IOException {
-        ensureOpen();
-
-        return mReplyHeader;
-    }
-
-    /**
-     * Specifies the headers that should be sent in the next OBEX message that
-     * is sent.
-     * @param headers the headers to send in the next message
-     * @throws IOException if this <code>Operation</code> has been closed or the
-     *         transaction has ended and no further messages will be exchanged
-     * @throws IllegalArgumentException if <code>headers</code> was not created
-     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
-     * @throws NullPointerException if <code>headers</code> is <code>null</code>
-     */
-    public void sendHeaders(HeaderSet headers) throws IOException {
-        ensureOpen();
-        if (mOperationDone) {
-            throw new IOException("Operation has already exchanged all data");
-        }
-
-        if (headers == null) {
-            throw new IOException("Headers may not be null");
-        }
-
-        int[] headerList = headers.getHeaderList();
-        if (headerList != null) {
-            for (int i = 0; i < headerList.length; i++) {
-                mRequestHeader.setHeader(headerList[i], headers.getHeader(headerList[i]));
-            }
-        }
-    }
-
-    /**
-     * Verifies that additional information may be sent. In other words, the
-     * operation is not done.
-     * @throws IOException if the operation is completed
-     */
-    public void ensureNotDone() throws IOException {
-        if (mOperationDone) {
-            throw new IOException("Operation has completed");
-        }
-    }
-
-    /**
-     * Verifies that the connection is open and no exceptions should be thrown.
-     * @throws IOException if an exception needs to be thrown
-     */
-    public void ensureOpen() throws IOException {
-        mParent.ensureOpen();
-
-        if (mExceptionMessage != null) {
-            throw new IOException(mExceptionMessage);
-        }
-        if (!mInputOpen) {
-            throw new IOException("Operation has already ended");
-        }
-    }
-
-    /**
-     * Verifies that the connection is open and the proper data has been read.
-     * @throws IOException if an IO error occurs
-     */
-    private void validateConnection() throws IOException {
-        ensureOpen();
-
-        // Make sure that a response has been recieved from remote
-        // before continuing
-        if (mPrivateInput == null || mReplyHeader.responseCode == -1) {
-            startProcessing();
-        }
-    }
-
-    /**
-     * Sends a request to the client of the specified type.
-     * This function will enable SRM and set SRM active if the server
-     * response allows this.
-     * @param opCode the request code to send to the client
-     * @return <code>true</code> if there is more data to send;
-     *         <code>false</code> if there is no more data to send
-     * @throws IOException if an IO error occurs
-     */
-    private boolean sendRequest(int opCode) throws IOException {
-        boolean returnValue = false;
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        int bodyLength = -1;
-        byte[] headerArray = ObexHelper.createHeader(mRequestHeader, true);
-        if (mPrivateOutput != null) {
-            bodyLength = mPrivateOutput.size();
-        }
-
-        /*
-         * Determine if there is space to add a body request.  At present
-         * this method checks to see if there is room for at least a 17
-         * byte body header.  This number needs to be at least 6 so that
-         * there is room for the header ID and length and the reply ID and
-         * length, but it is a waste of resources if we can't send much of
-         * the body.
-         */
-        final int MINIMUM_BODY_LENGTH = 3;
-        if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length + MINIMUM_BODY_LENGTH)
-                > mMaxPacketSize) {
-            int end = 0;
-            int start = 0;
-            // split & send the headerArray in multiple packets.
-
-            while (end != headerArray.length) {
-                //split the headerArray
-
-                end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketSize
-                        - ObexHelper.BASE_PACKET_LENGTH);
-                // can not split
-                if (end == -1) {
-                    mOperationDone = true;
-                    abort();
-                    mExceptionMessage = "Header larger then can be sent in a packet";
-                    mInputOpen = false;
-
-                    if (mPrivateInput != null) {
-                        mPrivateInput.close();
-                    }
-
-                    if (mPrivateOutput != null) {
-                        mPrivateOutput.close();
-                    }
-                    throw new IOException("OBEX Packet exceeds max packet size");
-                }
-
-                byte[] sendHeader = new byte[end - start];
-                System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length);
-                if (!mParent.sendRequest(opCode, sendHeader, mReplyHeader, mPrivateInput, false)) {
-                    return false;
-                }
-
-                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
-                    return false;
-                }
-
-                start = end;
-            }
-
-            // Enable SRM if it should be enabled
-            checkForSrm();
-
-            if (bodyLength > 0) {
-                return true;
-            } else {
-                return false;
-            }
-        } else {
-            /* All headers will fit into a single package */
-            if(mSendBodyHeader == false) {
-                /* As we are not to send any body data, set the FINAL_BIT */
-                opCode |= ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK;
-            }
-            out.write(headerArray);
-        }
-
-        if (bodyLength > 0) {
-            /*
-             * Determine if we can send the whole body or just part of
-             * the body.  Remember that there is the 3 bytes for the
-             * response message and 3 bytes for the header ID and length
-             */
-            if (bodyLength > (mMaxPacketSize - headerArray.length - 6)) {
-                returnValue = true;
-
-                bodyLength = mMaxPacketSize - headerArray.length - 6;
-            }
-
-            byte[] body = mPrivateOutput.readBytes(bodyLength);
-
-            /*
-             * Since this is a put request if the final bit is set or
-             * the output stream is closed we need to send the 0x49
-             * (End of Body) otherwise, we need to send 0x48 (Body)
-             */
-            if ((mPrivateOutput.isClosed()) && (!returnValue) && (!mEndOfBodySent)
-                    && ((opCode & ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK) != 0)) {
-                out.write(HeaderSet.END_OF_BODY);
-                mEndOfBodySent = true;
-            } else {
-                out.write(HeaderSet.BODY);
-            }
-
-            bodyLength += 3;
-            out.write((byte)(bodyLength >> 8));
-            out.write((byte)bodyLength);
-
-            if (body != null) {
-                out.write(body);
-            }
-        }
-
-        if (mPrivateOutputOpen && bodyLength <= 0 && !mEndOfBodySent) {
-            // only 0x82 or 0x83 can send 0x49
-            if ((opCode & ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK) == 0) {
-                out.write(HeaderSet.BODY);
-            } else {
-                out.write(HeaderSet.END_OF_BODY);
-                mEndOfBodySent = true;
-            }
-
-            bodyLength = 3;
-            out.write((byte)(bodyLength >> 8));
-            out.write((byte)bodyLength);
-        }
-
-        if (out.size() == 0) {
-            if (!mParent.sendRequest(opCode, null, mReplyHeader, mPrivateInput, mSrmActive)) {
-                return false;
-            }
-            // Enable SRM if it should be enabled
-            checkForSrm();
-            return returnValue;
-        }
-        if ((out.size() > 0)
-                && (!mParent.sendRequest(opCode, out.toByteArray(),
-                        mReplyHeader, mPrivateInput, mSrmActive))) {
-            return false;
-        }
-        // Enable SRM if it should be enabled
-        checkForSrm();
-
-        // send all of the output data in 0x48,
-        // send 0x49 with empty body
-        if ((mPrivateOutput != null) && (mPrivateOutput.size() > 0))
-            returnValue = true;
-
-        return returnValue;
-    }
-
-    private void checkForSrm() throws IOException {
-        Byte srmMode = (Byte)mReplyHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
-        if(mParent.isSrmSupported() == true && srmMode != null
-                && srmMode == ObexHelper.OBEX_SRM_ENABLE) {
-            mSrmEnabled = true;
-        }
-        /**
-         * Call this only when a complete obex packet have been received.
-         * (This is not optimal, but the current design is not really suited to
-         * the way SRM is specified.)
-         * The BT usage of SRM is not really safe - it assumes that the SRMP will fit
-         * into every OBEX packet, hence if another header occupies the entire packet,
-         * the scheme will not work - unlikely though.
-         */
-        if(mSrmEnabled) {
-            mSrmWaitingForRemote = false;
-            Byte srmp = (Byte)mReplyHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
-            if(srmp != null && srmp == ObexHelper.OBEX_SRMP_WAIT) {
-                mSrmWaitingForRemote = true;
-                // Clear the wait header, as the absence of the header in the next packet
-                // indicates don't wait anymore.
-                mReplyHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
-            }
-        }
-        if((mSrmWaitingForRemote == false) && (mSrmEnabled == true)) {
-            mSrmActive = true;
-        }
-    }
-
-    /**
-     * This method starts the processing thread results. It will send the
-     * initial request. If the response takes more then one packet, a thread
-     * will be started to handle additional requests
-     * @throws IOException if an IO error occurs
-     */
-    private synchronized void startProcessing() throws IOException {
-
-        if (mPrivateInput == null) {
-            mPrivateInput = new PrivateInputStream(this);
-        }
-        boolean more = true;
-
-        if (mGetOperation) {
-            if (!mOperationDone) {
-                if (!mGetFinalFlag) {
-                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
-                    while ((more) && (mReplyHeader.responseCode ==
-                            ResponseCodes.OBEX_HTTP_CONTINUE)) {
-                        more = sendRequest(ObexHelper.OBEX_OPCODE_GET);
-                    }
-                    // For GET we need to loop until all headers have been sent,
-                    // And then we wait for the first continue package with the
-                    // reply.
-                    if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
-                        mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL,
-                                null, mReplyHeader, mPrivateInput, mSrmActive);
-                    }
-                    if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
-                        mOperationDone = true;
-                    } else {
-                        checkForSrm();
-                    }
-                } else {
-                    more = sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
-
-                    if (more) {
-                        throw new IOException("FINAL_GET forced, data didn't fit into one packet");
-                    }
-
-                    mOperationDone = true;
-                }
-            }
-        } else {
-            // PUT operation
-            if (!mOperationDone) {
-                mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
-                while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
-                    more = sendRequest(ObexHelper.OBEX_OPCODE_PUT);
-                }
-            }
-
-            if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
-                mParent.sendRequest(ObexHelper.OBEX_OPCODE_PUT_FINAL,
-                        null, mReplyHeader, mPrivateInput, mSrmActive);
-            }
-
-            if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
-                mOperationDone = true;
-            }
-        }
-    }
-
-    /**
-     * Continues the operation since there is no data to read.
-     * @param sendEmpty <code>true</code> if the operation should send an empty
-     *        packet or not send anything if there is no data to send
-     * @param inStream <code>true</code> if the stream is input stream or is
-     *        output stream
-     * @throws IOException if an IO error occurs
-     */
-    public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
-            throws IOException {
-
-        // One path to the first put operation - the other one does not need to
-        // handle SRM, as all will fit into one packet.
-
-        if (mGetOperation) {
-            if ((inStream) && (!mOperationDone)) {
-                // to deal with inputstream in get operation
-                mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL,
-                        null, mReplyHeader, mPrivateInput, mSrmActive);
-                /*
-                  * Determine if that was not the last packet in the operation
-                  */
-                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
-                    mOperationDone = true;
-                } else {
-                    checkForSrm();
-                }
-
-                return true;
-
-            } else if ((!inStream) && (!mOperationDone)) {
-                // to deal with outputstream in get operation
-
-                if (mPrivateInput == null) {
-                    mPrivateInput = new PrivateInputStream(this);
-                }
-
-                if (!mGetFinalFlag) {
-                    sendRequest(ObexHelper.OBEX_OPCODE_GET);
-                } else {
-                    sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
-                }
-                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
-                    mOperationDone = true;
-                }
-                return true;
-
-            } else if (mOperationDone) {
-                return false;
-            }
-
-        } else {
-            // PUT operation
-            if ((!inStream) && (!mOperationDone)) {
-                // to deal with outputstream in put operation
-                if (mReplyHeader.responseCode == -1) {
-                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
-                }
-                sendRequest(ObexHelper.OBEX_OPCODE_PUT);
-                return true;
-            } else if ((inStream) && (!mOperationDone)) {
-                // How to deal with inputstream  in put operation ?
-                return false;
-
-            } else if (mOperationDone) {
-                return false;
-            }
-
-        }
-        return false;
-    }
-
-    /**
-     * Called when the output or input stream is closed.
-     * @param inStream <code>true</code> if the input stream is closed;
-     *        <code>false</code> if the output stream is closed
-     * @throws IOException if an IO error occurs
-     */
-    public void streamClosed(boolean inStream) throws IOException {
-        if (!mGetOperation) {
-            if ((!inStream) && (!mOperationDone)) {
-                // to deal with outputstream in put operation
-
-                boolean more = true;
-
-                if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) {
-                    byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false);
-                    if (headerArray.length <= 0)
-                        more = false;
-                }
-                // If have not sent any data so send  all now
-                if (mReplyHeader.responseCode == -1) {
-                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
-                }
-
-                while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
-                    more = sendRequest(ObexHelper.OBEX_OPCODE_PUT);
-                }
-
-                /*
-                 * According to the IrOBEX specification, after the final put, you
-                 * only have a single reply to send.  so we don't need the while
-                 * loop.
-                 */
-                while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
-
-                    sendRequest(ObexHelper.OBEX_OPCODE_PUT_FINAL);
-                }
-                mOperationDone = true;
-            } else if ((inStream) && (mOperationDone)) {
-                // how to deal with input stream in put stream ?
-                mOperationDone = true;
-            }
-        } else {
-            if ((inStream) && (!mOperationDone)) {
-
-                // to deal with inputstream in get operation
-                // Have not sent any data so send it all now
-
-                if (mReplyHeader.responseCode == -1) {
-                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
-                }
-
-                while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE && !mOperationDone) {
-                    if (!sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL)) {
-                        break;
-                    }
-                }
-                while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE && !mOperationDone) {
-                    mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL, null,
-                            mReplyHeader, mPrivateInput, false);
-                    // Regardless of the SRM state, wait for the response.
-                }
-                mOperationDone = true;
-            } else if ((!inStream) && (!mOperationDone)) {
-                // to deal with outputstream in get operation
-                // part of the data may have been sent in continueOperation.
-
-                boolean more = true;
-
-                if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) {
-                    byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false);
-                    if (headerArray.length <= 0)
-                        more = false;
-                }
-
-                if (mPrivateInput == null) {
-                    mPrivateInput = new PrivateInputStream(this);
-                }
-                if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0))
-                    more = false;
-
-                mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
-                while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
-                    more = sendRequest(ObexHelper.OBEX_OPCODE_GET);
-                }
-                sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
-                //                parent.sendRequest(0x83, null, replyHeaders, privateInput);
-                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
-                    mOperationDone = true;
-                }
-            }
-        }
-    }
-
-    public void noBodyHeader(){
-        mSendBodyHeader = false;
-    }
-}
diff --git a/obex/javax/obex/ClientSession.java b/obex/javax/obex/ClientSession.java
deleted file mode 100644
index 272a920..0000000
--- a/obex/javax/obex/ClientSession.java
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
- * Copyright (c) 2015 The Android Open Source Project
- * Copyright (C) 2015 Samsung LSI
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import android.util.Log;
-
-/**
- * This class in an implementation of the OBEX ClientSession.
- * @hide
- */
-public final class ClientSession extends ObexSession {
-
-    private static final String TAG = "ClientSession";
-
-    private boolean mOpen;
-
-    // Determines if an OBEX layer connection has been established
-    private boolean mObexConnected;
-
-    private byte[] mConnectionId = null;
-
-    /*
-     * The max Packet size must be at least 255 according to the OBEX
-     * specification.
-     */
-    private int mMaxTxPacketSize = ObexHelper.LOWER_LIMIT_MAX_PACKET_SIZE;
-
-    private boolean mRequestActive;
-
-    private final InputStream mInput;
-
-    private final OutputStream mOutput;
-
-    private final boolean mLocalSrmSupported;
-
-    private final ObexTransport mTransport;
-
-    public ClientSession(final ObexTransport trans) throws IOException {
-        mInput = trans.openInputStream();
-        mOutput = trans.openOutputStream();
-        mOpen = true;
-        mRequestActive = false;
-        mLocalSrmSupported = trans.isSrmSupported();
-        mTransport = trans;
-    }
-
-    /**
-     * Create a ClientSession
-     * @param trans The transport to use for OBEX transactions
-     * @param supportsSrm True if Single Response Mode should be used e.g. if the
-     *        supplied transport is a TCP or l2cap channel.
-     * @throws IOException if it occurs while opening the transport streams.
-     */
-    public ClientSession(final ObexTransport trans, final boolean supportsSrm) throws IOException {
-        mInput = trans.openInputStream();
-        mOutput = trans.openOutputStream();
-        mOpen = true;
-        mRequestActive = false;
-        mLocalSrmSupported = supportsSrm;
-        mTransport = trans;
-    }
-
-    public HeaderSet connect(final HeaderSet header) throws IOException {
-        ensureOpen();
-        if (mObexConnected) {
-            throw new IOException("Already connected to server");
-        }
-        setRequestActive();
-
-        int totalLength = 4;
-        byte[] head = null;
-
-        // Determine the header byte array
-        if (header != null) {
-            if (header.nonce != null) {
-                mChallengeDigest = new byte[16];
-                System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16);
-            }
-            head = ObexHelper.createHeader(header, false);
-            totalLength += head.length;
-        }
-        /*
-        * Write the OBEX CONNECT packet to the server.
-        * Byte 0: 0x80
-        * Byte 1&2: Connect Packet Length
-        * Byte 3: OBEX Version Number (Presently, 0x10)
-        * Byte 4: Flags (For TCP 0x00)
-        * Byte 5&6: Max OBEX Packet Length (Defined in MAX_PACKET_SIZE)
-        * Byte 7 to n: headers
-        */
-        byte[] requestPacket = new byte[totalLength];
-        int maxRxPacketSize = ObexHelper.getMaxRxPacketSize(mTransport);
-        // We just need to start at  byte 3 since the sendRequest() method will
-        // handle the length and 0x80.
-        requestPacket[0] = (byte)0x10;
-        requestPacket[1] = (byte)0x00;
-        requestPacket[2] = (byte)(maxRxPacketSize >> 8);
-        requestPacket[3] = (byte)(maxRxPacketSize & 0xFF);
-        if (head != null) {
-            System.arraycopy(head, 0, requestPacket, 4, head.length);
-        }
-
-        // Since we are not yet connected, the peer max packet size is unknown,
-        // hence we are only guaranteed the server will use the first 7 bytes.
-        if ((requestPacket.length + 3) > ObexHelper.MAX_PACKET_SIZE_INT) {
-            throw new IOException("Packet size exceeds max packet size for connect");
-        }
-
-        HeaderSet returnHeaderSet = new HeaderSet();
-        sendRequest(ObexHelper.OBEX_OPCODE_CONNECT, requestPacket, returnHeaderSet, null, false);
-
-        /*
-        * Read the response from the OBEX server.
-        * Byte 0: Response Code (If successful then OBEX_HTTP_OK)
-        * Byte 1&2: Packet Length
-        * Byte 3: OBEX Version Number
-        * Byte 4: Flags3
-        * Byte 5&6: Max OBEX packet Length
-        * Byte 7 to n: Optional HeaderSet
-        */
-        if (returnHeaderSet.responseCode == ResponseCodes.OBEX_HTTP_OK) {
-            mObexConnected = true;
-        }
-        setRequestInactive();
-
-        return returnHeaderSet;
-    }
-
-    public Operation get(HeaderSet header) throws IOException {
-
-        if (!mObexConnected) {
-            throw new IOException("Not connected to the server");
-        }
-        setRequestActive();
-
-        ensureOpen();
-
-        HeaderSet head;
-        if (header == null) {
-            head = new HeaderSet();
-        } else {
-            head = header;
-            if (head.nonce != null) {
-                mChallengeDigest = new byte[16];
-                System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16);
-            }
-        }
-        // Add the connection ID if one exists
-        if (mConnectionId != null) {
-            head.mConnectionID = new byte[4];
-            System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4);
-        }
-
-        if(mLocalSrmSupported) {
-            head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, ObexHelper.OBEX_SRM_ENABLE);
-            /* TODO: Consider creating an interface to get the wait state.
-             * On an android system, I cannot see when this is to be used.
-             * except perhaps if we are to wait for user accept on a push message.
-            if(getLocalWaitState()) {
-                head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, ObexHelper.OBEX_SRMP_WAIT);
-            }
-            */
-        }
-
-        return new ClientOperation(mMaxTxPacketSize, this, head, true);
-    }
-
-    /**
-     * 0xCB Connection Id an identifier used for OBEX connection multiplexing
-     */
-    public void setConnectionID(long id) {
-        if ((id < 0) || (id > 0xFFFFFFFFL)) {
-            throw new IllegalArgumentException("Connection ID is not in a valid range");
-        }
-        mConnectionId = ObexHelper.convertToByteArray(id);
-    }
-
-    public HeaderSet delete(HeaderSet header) throws IOException {
-
-        Operation op = put(header);
-        op.getResponseCode();
-        HeaderSet returnValue = op.getReceivedHeader();
-        op.close();
-
-        return returnValue;
-    }
-
-    public HeaderSet disconnect(HeaderSet header) throws IOException {
-        if (!mObexConnected) {
-            throw new IOException("Not connected to the server");
-        }
-        setRequestActive();
-
-        ensureOpen();
-        // Determine the header byte array
-        byte[] head = null;
-        if (header != null) {
-            if (header.nonce != null) {
-                mChallengeDigest = new byte[16];
-                System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16);
-            }
-            // Add the connection ID if one exists
-            if (mConnectionId != null) {
-                header.mConnectionID = new byte[4];
-                System.arraycopy(mConnectionId, 0, header.mConnectionID, 0, 4);
-            }
-            head = ObexHelper.createHeader(header, false);
-
-            if ((head.length + 3) > mMaxTxPacketSize) {
-                throw new IOException("Packet size exceeds max packet size");
-            }
-        } else {
-            // Add the connection ID if one exists
-            if (mConnectionId != null) {
-                head = new byte[5];
-                head[0] = (byte)HeaderSet.CONNECTION_ID;
-                System.arraycopy(mConnectionId, 0, head, 1, 4);
-            }
-        }
-
-        HeaderSet returnHeaderSet = new HeaderSet();
-        sendRequest(ObexHelper.OBEX_OPCODE_DISCONNECT, head, returnHeaderSet, null, false);
-
-        /*
-         * An OBEX DISCONNECT reply from the server:
-         * Byte 1: Response code
-         * Bytes 2 & 3: packet size
-         * Bytes 4 & up: headers
-         */
-
-        /* response code , and header are ignored
-         * */
-
-        synchronized (this) {
-            mObexConnected = false;
-            setRequestInactive();
-        }
-
-        return returnHeaderSet;
-    }
-
-    public long getConnectionID() {
-
-        if (mConnectionId == null) {
-            return -1;
-        }
-        return ObexHelper.convertToLong(mConnectionId);
-    }
-
-    public Operation put(HeaderSet header) throws IOException {
-        if (!mObexConnected) {
-            throw new IOException("Not connected to the server");
-        }
-        setRequestActive();
-
-        ensureOpen();
-        HeaderSet head;
-        if (header == null) {
-            head = new HeaderSet();
-        } else {
-            head = header;
-            // when auth is initiated by client ,save the digest
-            if (head.nonce != null) {
-                mChallengeDigest = new byte[16];
-                System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16);
-            }
-        }
-
-        // Add the connection ID if one exists
-        if (mConnectionId != null) {
-
-            head.mConnectionID = new byte[4];
-            System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4);
-        }
-
-        if(mLocalSrmSupported) {
-            head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, ObexHelper.OBEX_SRM_ENABLE);
-            /* TODO: Consider creating an interface to get the wait state.
-             * On an android system, I cannot see when this is to be used.
-            if(getLocalWaitState()) {
-                head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, ObexHelper.OBEX_SRMP_WAIT);
-            }
-             */
-        }
-        return new ClientOperation(mMaxTxPacketSize, this, head, false);
-    }
-
-    public void setAuthenticator(Authenticator auth) throws IOException {
-        if (auth == null) {
-            throw new IOException("Authenticator may not be null");
-        }
-        mAuthenticator = auth;
-    }
-
-    public HeaderSet setPath(HeaderSet header, boolean backup, boolean create) throws IOException {
-        if (!mObexConnected) {
-            throw new IOException("Not connected to the server");
-        }
-        setRequestActive();
-        ensureOpen();
-
-        int totalLength = 2;
-        byte[] head = null;
-        HeaderSet headset;
-        if (header == null) {
-            headset = new HeaderSet();
-        } else {
-            headset = header;
-            if (headset.nonce != null) {
-                mChallengeDigest = new byte[16];
-                System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16);
-            }
-        }
-
-        // when auth is initiated by client ,save the digest
-        if (headset.nonce != null) {
-            mChallengeDigest = new byte[16];
-            System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16);
-        }
-
-        // Add the connection ID if one exists
-        if (mConnectionId != null) {
-            headset.mConnectionID = new byte[4];
-            System.arraycopy(mConnectionId, 0, headset.mConnectionID, 0, 4);
-        }
-
-        head = ObexHelper.createHeader(headset, false);
-        totalLength += head.length;
-
-        if (totalLength > mMaxTxPacketSize) {
-            throw new IOException("Packet size exceeds max packet size");
-        }
-
-        int flags = 0;
-        /*
-         * The backup flag bit is bit 0 so if we add 1, this will set that bit
-         */
-        if (backup) {
-            flags++;
-        }
-        /*
-         * The create bit is bit 1 so if we or with 2 the bit will be set.
-         */
-        if (!create) {
-            flags |= 2;
-        }
-
-        /*
-         * An OBEX SETPATH packet to the server:
-         * Byte 1: 0x85
-         * Byte 2 & 3: packet size
-         * Byte 4: flags
-         * Byte 5: constants
-         * Byte 6 & up: headers
-         */
-        byte[] packet = new byte[totalLength];
-        packet[0] = (byte)flags;
-        packet[1] = (byte)0x00;
-        if (headset != null) {
-            System.arraycopy(head, 0, packet, 2, head.length);
-        }
-
-        HeaderSet returnHeaderSet = new HeaderSet();
-        sendRequest(ObexHelper.OBEX_OPCODE_SETPATH, packet, returnHeaderSet, null, false);
-
-        /*
-         * An OBEX SETPATH reply from the server:
-         * Byte 1: Response code
-         * Bytes 2 & 3: packet size
-         * Bytes 4 & up: headers
-         */
-
-        setRequestInactive();
-
-        return returnHeaderSet;
-    }
-
-    /**
-     * Verifies that the connection is open.
-     * @throws IOException if the connection is closed
-     */
-    public synchronized void ensureOpen() throws IOException {
-        if (!mOpen) {
-            throw new IOException("Connection closed");
-        }
-    }
-
-    /**
-     * Set request inactive. Allows Put and get operation objects to tell this
-     * object when they are done.
-     */
-    /*package*/synchronized void setRequestInactive() {
-        mRequestActive = false;
-    }
-
-    /**
-     * Set request to active.
-     * @throws IOException if already active
-     */
-    private synchronized void setRequestActive() throws IOException {
-        if (mRequestActive) {
-            throw new IOException("OBEX request is already being performed");
-        }
-        mRequestActive = true;
-    }
-
-    /**
-     * Sends a standard request to the client. It will then wait for the reply
-     * and update the header set object provided. If any authentication headers
-     * (i.e. authentication challenge or authentication response) are received,
-     * they will be processed.
-     * @param opCode the type of request to send to the client
-     * @param head the headers to send to the client
-     * @param header the header object to update with the response
-     * @param privateInput the input stream used by the Operation object; null
-     *        if this is called on a CONNECT, SETPATH or DISCONNECT
-     * @return
-     *        <code>true</code> if the operation completed successfully;
-     *        <code>false</code> if an authentication response failed to pass
-     * @throws IOException if an IO error occurs
-     */
-    public boolean sendRequest(int opCode, byte[] head, HeaderSet header,
-            PrivateInputStream privateInput, boolean srmActive) throws IOException {
-        //check header length with local max size
-        if (head != null) {
-            if ((head.length + 3) > ObexHelper.MAX_PACKET_SIZE_INT) {
-                // TODO: This is an implementation limit - not a specification requirement.
-                throw new IOException("header too large ");
-            }
-        }
-
-        boolean skipSend = false;
-        boolean skipReceive = false;
-        if (srmActive == true) {
-            if (opCode == ObexHelper.OBEX_OPCODE_PUT) {
-                // we are in the middle of a SRM PUT operation, don't expect a continue.
-                skipReceive = true;
-            } else if (opCode == ObexHelper.OBEX_OPCODE_GET) {
-                // We are still sending the get request, send, but don't expect continue
-                // until the request is transfered (the final bit is set)
-                skipReceive = true;
-            } else if (opCode == ObexHelper.OBEX_OPCODE_GET_FINAL) {
-                // All done sending the request, expect data from the server, without
-                // sending continue.
-                skipSend = true;
-            }
-
-        }
-
-        int bytesReceived;
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        out.write((byte)opCode);
-
-        // Determine if there are any headers to send
-        if (head == null) {
-            out.write(0x00);
-            out.write(0x03);
-        } else {
-            out.write((byte)((head.length + 3) >> 8));
-            out.write((byte)(head.length + 3));
-            out.write(head);
-        }
-
-        if (!skipSend) {
-            // Write the request to the output stream and flush the stream
-            mOutput.write(out.toByteArray());
-            // TODO: is this really needed? if this flush is implemented
-            //       correctly, we will get a gap between each obex packet.
-            //       which is kind of the idea behind SRM to avoid.
-            //  Consider offloading to another thread (async action)
-            mOutput.flush();
-        }
-
-        if (!skipReceive) {
-            header.responseCode = mInput.read();
-
-            int length = ((mInput.read() << 8) | (mInput.read()));
-
-            if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
-                throw new IOException("Packet received exceeds packet size limit");
-            }
-            if (length > ObexHelper.BASE_PACKET_LENGTH) {
-                byte[] data = null;
-                if (opCode == ObexHelper.OBEX_OPCODE_CONNECT) {
-                    @SuppressWarnings("unused")
-                    int version = mInput.read();
-                    @SuppressWarnings("unused")
-                    int flags = mInput.read();
-                    mMaxTxPacketSize = (mInput.read() << 8) + mInput.read();
-
-                    //check with local max size
-                    if (mMaxTxPacketSize > ObexHelper.MAX_CLIENT_PACKET_SIZE) {
-                        mMaxTxPacketSize = ObexHelper.MAX_CLIENT_PACKET_SIZE;
-                    }
-
-                    // check with transport maximum size
-                    if(mMaxTxPacketSize > ObexHelper.getMaxTxPacketSize(mTransport)) {
-                        // To increase this size, increase the buffer size in L2CAP layer
-                        // in Bluedroid.
-                        Log.w(TAG, "An OBEX packet size of " + mMaxTxPacketSize + "was"
-                                + " requested. Transport only allows: "
-                                + ObexHelper.getMaxTxPacketSize(mTransport)
-                                + " Lowering limit to this value.");
-                        mMaxTxPacketSize = ObexHelper.getMaxTxPacketSize(mTransport);
-                    }
-
-                    if (length > 7) {
-                        data = new byte[length - 7];
-
-                        bytesReceived = mInput.read(data);
-                        while (bytesReceived != (length - 7)) {
-                            bytesReceived += mInput.read(data, bytesReceived, data.length
-                                    - bytesReceived);
-                        }
-                    } else {
-                        return true;
-                    }
-                } else {
-                    data = new byte[length - 3];
-                    bytesReceived = mInput.read(data);
-
-                    while (bytesReceived != (length - 3)) {
-                        bytesReceived += mInput.read(data, bytesReceived, data.length - bytesReceived);
-                    }
-                    if (opCode == ObexHelper.OBEX_OPCODE_ABORT) {
-                        return true;
-                    }
-                }
-
-                byte[] body = ObexHelper.updateHeaderSet(header, data);
-                if ((privateInput != null) && (body != null)) {
-                    privateInput.writeBytes(body, 1);
-                }
-
-                if (header.mConnectionID != null) {
-                    mConnectionId = new byte[4];
-                    System.arraycopy(header.mConnectionID, 0, mConnectionId, 0, 4);
-                }
-
-                if (header.mAuthResp != null) {
-                    if (!handleAuthResp(header.mAuthResp)) {
-                        setRequestInactive();
-                        throw new IOException("Authentication Failed");
-                    }
-                }
-
-                if ((header.responseCode == ResponseCodes.OBEX_HTTP_UNAUTHORIZED)
-                        && (header.mAuthChall != null)) {
-
-                    if (handleAuthChall(header)) {
-                        out.write((byte)HeaderSet.AUTH_RESPONSE);
-                        out.write((byte)((header.mAuthResp.length + 3) >> 8));
-                        out.write((byte)(header.mAuthResp.length + 3));
-                        out.write(header.mAuthResp);
-                        header.mAuthChall = null;
-                        header.mAuthResp = null;
-
-                        byte[] sendHeaders = new byte[out.size() - 3];
-                        System.arraycopy(out.toByteArray(), 3, sendHeaders, 0, sendHeaders.length);
-
-                        return sendRequest(opCode, sendHeaders, header, privateInput, false);
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    public void close() throws IOException {
-        mOpen = false;
-        mInput.close();
-        mOutput.close();
-    }
-
-    public boolean isSrmSupported() {
-        return mLocalSrmSupported;
-    }
-}
diff --git a/obex/javax/obex/HeaderSet.java b/obex/javax/obex/HeaderSet.java
deleted file mode 100644
index 35fe186..0000000
--- a/obex/javax/obex/HeaderSet.java
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- * Copyright (c) 2014 The Android Open Source Project
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Calendar;
-import java.security.SecureRandom;
-
-/**
- * This class implements the javax.obex.HeaderSet interface for OBEX over
- * RFCOMM or OBEX over l2cap.
- * @hide
- */
-public final class HeaderSet {
-
-    /**
-     * Represents the OBEX Count header. This allows the connection statement to
-     * tell the server how many objects it plans to send or retrieve.
-     * <P>
-     * The value of <code>COUNT</code> is 0xC0 (192).
-     */
-    public static final int COUNT = 0xC0;
-
-    /**
-     * Represents the OBEX Name header. This specifies the name of the object.
-     * <P>
-     * The value of <code>NAME</code> is 0x01 (1).
-     */
-    public static final int NAME = 0x01;
-
-    /**
-     * Represents the OBEX Type header. This allows a request to specify the
-     * type of the object (e.g. text, html, binary, etc.).
-     * <P>
-     * The value of <code>TYPE</code> is 0x42 (66).
-     */
-    public static final int TYPE = 0x42;
-
-    /**
-     * Represents the OBEX Length header. This is the length of the object in
-     * bytes.
-     * <P>
-     * The value of <code>LENGTH</code> is 0xC3 (195).
-     */
-    public static final int LENGTH = 0xC3;
-
-    /**
-     * Represents the OBEX Time header using the ISO 8601 standards. This is the
-     * preferred time header.
-     * <P>
-     * The value of <code>TIME_ISO_8601</code> is 0x44 (68).
-     */
-    public static final int TIME_ISO_8601 = 0x44;
-
-    /**
-     * Represents the OBEX Time header using the 4 byte representation. This is
-     * only included for backwards compatibility. It represents the number of
-     * seconds since January 1, 1970.
-     * <P>
-     * The value of <code>TIME_4_BYTE</code> is 0xC4 (196).
-     */
-    public static final int TIME_4_BYTE = 0xC4;
-
-    /**
-     * Represents the OBEX Description header. This is a text description of the
-     * object.
-     * <P>
-     * The value of <code>DESCRIPTION</code> is 0x05 (5).
-     */
-    public static final int DESCRIPTION = 0x05;
-
-    /**
-     * Represents the OBEX Target header. This is the name of the service an
-     * operation is targeted to.
-     * <P>
-     * The value of <code>TARGET</code> is 0x46 (70).
-     */
-    public static final int TARGET = 0x46;
-
-    /**
-     * Represents the OBEX HTTP header. This allows an HTTP 1.X header to be
-     * included in a request or reply.
-     * <P>
-     * The value of <code>HTTP</code> is 0x47 (71).
-     */
-    public static final int HTTP = 0x47;
-
-    /**
-     * Represents the OBEX BODY header.
-     * <P>
-     * The value of <code>BODY</code> is 0x48 (72).
-     */
-    public static final int BODY = 0x48;
-
-    /**
-     * Represents the OBEX End of BODY header.
-     * <P>
-     * The value of <code>BODY</code> is 0x49 (73).
-     */
-    public static final int END_OF_BODY = 0x49;
-
-    /**
-     * Represents the OBEX Who header. Identifies the OBEX application to
-     * determine if the two peers are talking to each other.
-     * <P>
-     * The value of <code>WHO</code> is 0x4A (74).
-     */
-    public static final int WHO = 0x4A;
-
-    /**
-     * Represents the OBEX Connection ID header. Identifies used for OBEX
-     * connection multiplexing.
-     * <P>
-     * The value of <code>CONNECTION_ID</code> is 0xCB (203).
-     */
-
-    public static final int CONNECTION_ID = 0xCB;
-
-    /**
-     * Represents the OBEX Application Parameter header. This header specifies
-     * additional application request and response information.
-     * <P>
-     * The value of <code>APPLICATION_PARAMETER</code> is 0x4C (76).
-     */
-    public static final int APPLICATION_PARAMETER = 0x4C;
-
-    /**
-     * Represents the OBEX authentication digest-challenge.
-     * <P>
-     * The value of <code>AUTH_CHALLENGE</code> is 0x4D (77).
-     */
-    public static final int AUTH_CHALLENGE = 0x4D;
-
-    /**
-     * Represents the OBEX authentication digest-response.
-     * <P>
-     * The value of <code>AUTH_RESPONSE</code> is 0x4E (78).
-     */
-    public static final int AUTH_RESPONSE = 0x4E;
-
-    /**
-     * Represents the OBEX Object Class header. This header specifies the OBEX
-     * object class of the object.
-     * <P>
-     * The value of <code>OBJECT_CLASS</code> is 0x4F (79).
-     */
-    public static final int OBJECT_CLASS = 0x4F;
-
-    /**
-     * Represents the OBEX Single Response Mode (SRM). This header is used
-     * for Single response mode, introduced in OBEX 1.5.
-     * <P>
-     * The value of <code>SINGLE_RESPONSE_MODE</code> is 0x97 (151).
-     */
-    public static final int SINGLE_RESPONSE_MODE = 0x97;
-
-    /**
-     * Represents the OBEX Single Response Mode Parameters. This header is used
-     * for Single response mode, introduced in OBEX 1.5.
-     * <P>
-     * The value of <code>SINGLE_RESPONSE_MODE_PARAMETER</code> is 0x98 (152).
-     */
-    public static final int SINGLE_RESPONSE_MODE_PARAMETER = 0x98;
-
-    private Long mCount; // 4 byte unsigned integer
-
-    private String mName; // null terminated Unicode text string
-
-    private boolean mEmptyName;
-
-    private String mType; // null terminated ASCII text string
-
-    private Long mLength; // 4 byte unsigend integer
-
-    private Calendar mIsoTime; // String of the form YYYYMMDDTHHMMSSZ
-
-    private Calendar mByteTime; // 4 byte unsigned integer
-
-    private String mDescription; // null terminated Unicode text String
-
-    private byte[] mTarget; // byte sequence
-
-    private byte[] mHttpHeader; // byte sequence
-
-    private byte[] mWho; // length prefixed byte sequence
-
-    private byte[] mAppParam; // byte sequence of the form tag length value
-
-    private byte[] mObjectClass; // byte sequence
-
-    private String[] mUnicodeUserDefined; // null terminated unicode string
-
-    private byte[][] mSequenceUserDefined; // byte sequence user defined
-
-    private Byte[] mByteUserDefined; // 1 byte
-
-    private Long[] mIntegerUserDefined; // 4 byte unsigned integer
-
-    private SecureRandom mRandom = null;
-
-    private Byte mSingleResponseMode; // byte to indicate enable/disable/support for SRM
-
-    private Byte mSrmParam; // byte representing the SRM parameters - only "wait"
-                            // is supported by Bluetooth
-
-    /*package*/ byte[] nonce;
-
-    public byte[] mAuthChall; // The authentication challenge header
-
-    public byte[] mAuthResp; // The authentication response header
-
-    public byte[] mConnectionID; // THe connection ID
-
-    public int responseCode;
-
-    /**
-     * Creates new <code>HeaderSet</code> object.
-     * @param size the max packet size for this connection
-     */
-    public HeaderSet() {
-        mUnicodeUserDefined = new String[16];
-        mSequenceUserDefined = new byte[16][];
-        mByteUserDefined = new Byte[16];
-        mIntegerUserDefined = new Long[16];
-        responseCode = -1;
-    }
-
-    /**
-     * Sets flag for special "value" of NAME header which should be empty. This
-     * is not the same as NAME header with empty string in which case it will
-     * have length of 5 bytes. It should be 3 bytes with only header id and
-     * length field.
-     */
-    public void setEmptyNameHeader() {
-        mName = null;
-        mEmptyName = true;
-    }
-
-    /**
-     * Gets flag for special "value" of NAME header which should be empty. See
-     * above.
-     */
-    public boolean getEmptyNameHeader() {
-        return mEmptyName;
-    }
-
-    /**
-     * Sets the value of the header identifier to the value provided. The type
-     * of object must correspond to the Java type defined in the description of
-     * this interface. If <code>null</code> is passed as the
-     * <code>headerValue</code> then the header will be removed from the set of
-     * headers to include in the next request.
-     * @param headerID the identifier to include in the message
-     * @param headerValue the value of the header identifier
-     * @throws IllegalArgumentException if the header identifier provided is not
-     *         one defined in this interface or a user-defined header; if the
-     *         type of <code>headerValue</code> is not the correct Java type as
-     *         defined in the description of this interface\
-     */
-    public void setHeader(int headerID, Object headerValue) {
-        long temp = -1;
-
-        switch (headerID) {
-            case COUNT:
-                if (!(headerValue instanceof Long)) {
-                    if (headerValue == null) {
-                        mCount = null;
-                        break;
-                    }
-                    throw new IllegalArgumentException("Count must be a Long");
-                }
-                temp = ((Long)headerValue).longValue();
-                if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
-                    throw new IllegalArgumentException("Count must be between 0 and 0xFFFFFFFF");
-                }
-                mCount = (Long)headerValue;
-                break;
-            case NAME:
-                if ((headerValue != null) && (!(headerValue instanceof String))) {
-                    throw new IllegalArgumentException("Name must be a String");
-                }
-                mEmptyName = false;
-                mName = (String)headerValue;
-                break;
-            case TYPE:
-                if ((headerValue != null) && (!(headerValue instanceof String))) {
-                    throw new IllegalArgumentException("Type must be a String");
-                }
-                mType = (String)headerValue;
-                break;
-            case LENGTH:
-                if (!(headerValue instanceof Long)) {
-                    if (headerValue == null) {
-                        mLength = null;
-                        break;
-                    }
-                    throw new IllegalArgumentException("Length must be a Long");
-                }
-                temp = ((Long)headerValue).longValue();
-                if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
-                    throw new IllegalArgumentException("Length must be between 0 and 0xFFFFFFFF");
-                }
-                mLength = (Long)headerValue;
-                break;
-            case TIME_ISO_8601:
-                if ((headerValue != null) && (!(headerValue instanceof Calendar))) {
-                    throw new IllegalArgumentException("Time ISO 8601 must be a Calendar");
-                }
-                mIsoTime = (Calendar)headerValue;
-                break;
-            case TIME_4_BYTE:
-                if ((headerValue != null) && (!(headerValue instanceof Calendar))) {
-                    throw new IllegalArgumentException("Time 4 Byte must be a Calendar");
-                }
-                mByteTime = (Calendar)headerValue;
-                break;
-            case DESCRIPTION:
-                if ((headerValue != null) && (!(headerValue instanceof String))) {
-                    throw new IllegalArgumentException("Description must be a String");
-                }
-                mDescription = (String)headerValue;
-                break;
-            case TARGET:
-                if (headerValue == null) {
-                    mTarget = null;
-                } else {
-                    if (!(headerValue instanceof byte[])) {
-                        throw new IllegalArgumentException("Target must be a byte array");
-                    } else {
-                        mTarget = new byte[((byte[])headerValue).length];
-                        System.arraycopy(headerValue, 0, mTarget, 0, mTarget.length);
-                    }
-                }
-                break;
-            case HTTP:
-                if (headerValue == null) {
-                    mHttpHeader = null;
-                } else {
-                    if (!(headerValue instanceof byte[])) {
-                        throw new IllegalArgumentException("HTTP must be a byte array");
-                    } else {
-                        mHttpHeader = new byte[((byte[])headerValue).length];
-                        System.arraycopy(headerValue, 0, mHttpHeader, 0, mHttpHeader.length);
-                    }
-                }
-                break;
-            case WHO:
-                if (headerValue == null) {
-                    mWho = null;
-                } else {
-                    if (!(headerValue instanceof byte[])) {
-                        throw new IllegalArgumentException("WHO must be a byte array");
-                    } else {
-                        mWho = new byte[((byte[])headerValue).length];
-                        System.arraycopy(headerValue, 0, mWho, 0, mWho.length);
-                    }
-                }
-                break;
-            case OBJECT_CLASS:
-                if (headerValue == null) {
-                    mObjectClass = null;
-                } else {
-                    if (!(headerValue instanceof byte[])) {
-                        throw new IllegalArgumentException("Object Class must be a byte array");
-                    } else {
-                        mObjectClass = new byte[((byte[])headerValue).length];
-                        System.arraycopy(headerValue, 0, mObjectClass, 0, mObjectClass.length);
-                    }
-                }
-                break;
-            case APPLICATION_PARAMETER:
-                if (headerValue == null) {
-                    mAppParam = null;
-                } else {
-                    if (!(headerValue instanceof byte[])) {
-                        throw new IllegalArgumentException(
-                                "Application Parameter must be a byte array");
-                    } else {
-                        mAppParam = new byte[((byte[])headerValue).length];
-                        System.arraycopy(headerValue, 0, mAppParam, 0, mAppParam.length);
-                    }
-                }
-                break;
-            case SINGLE_RESPONSE_MODE:
-                if (headerValue == null) {
-                    mSingleResponseMode = null;
-                } else {
-                    if (!(headerValue instanceof Byte)) {
-                        throw new IllegalArgumentException(
-                                "Single Response Mode must be a Byte");
-                    } else {
-                        mSingleResponseMode = (Byte)headerValue;
-                    }
-                }
-                break;
-            case SINGLE_RESPONSE_MODE_PARAMETER:
-                if (headerValue == null) {
-                    mSrmParam = null;
-                } else {
-                    if (!(headerValue instanceof Byte)) {
-                        throw new IllegalArgumentException(
-                                "Single Response Mode Parameter must be a Byte");
-                    } else {
-                        mSrmParam = (Byte)headerValue;
-                    }
-                }
-                break;
-            default:
-                // Verify that it was not a Unicode String user Defined
-                if ((headerID >= 0x30) && (headerID <= 0x3F)) {
-                    if ((headerValue != null) && (!(headerValue instanceof String))) {
-                        throw new IllegalArgumentException(
-                                "Unicode String User Defined must be a String");
-                    }
-                    mUnicodeUserDefined[headerID - 0x30] = (String)headerValue;
-
-                    break;
-                }
-                // Verify that it was not a byte sequence user defined value
-                if ((headerID >= 0x70) && (headerID <= 0x7F)) {
-
-                    if (headerValue == null) {
-                        mSequenceUserDefined[headerID - 0x70] = null;
-                    } else {
-                        if (!(headerValue instanceof byte[])) {
-                            throw new IllegalArgumentException(
-                                    "Byte Sequence User Defined must be a byte array");
-                        } else {
-                            mSequenceUserDefined[headerID - 0x70] = new byte[((byte[])headerValue).length];
-                            System.arraycopy(headerValue, 0, mSequenceUserDefined[headerID - 0x70],
-                                    0, mSequenceUserDefined[headerID - 0x70].length);
-                        }
-                    }
-                    break;
-                }
-                // Verify that it was not a Byte user Defined
-                if ((headerID >= 0xB0) && (headerID <= 0xBF)) {
-                    if ((headerValue != null) && (!(headerValue instanceof Byte))) {
-                        throw new IllegalArgumentException("ByteUser Defined must be a Byte");
-                    }
-                    mByteUserDefined[headerID - 0xB0] = (Byte)headerValue;
-
-                    break;
-                }
-                // Verify that is was not the 4 byte unsigned integer user
-                // defined header
-                if ((headerID >= 0xF0) && (headerID <= 0xFF)) {
-                    if (!(headerValue instanceof Long)) {
-                        if (headerValue == null) {
-                            mIntegerUserDefined[headerID - 0xF0] = null;
-                            break;
-                        }
-                        throw new IllegalArgumentException("Integer User Defined must be a Long");
-                    }
-                    temp = ((Long)headerValue).longValue();
-                    if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
-                        throw new IllegalArgumentException(
-                                "Integer User Defined must be between 0 and 0xFFFFFFFF");
-                    }
-                    mIntegerUserDefined[headerID - 0xF0] = (Long)headerValue;
-                    break;
-                }
-                throw new IllegalArgumentException("Invalid Header Identifier");
-        }
-    }
-
-    /**
-     * Retrieves the value of the header identifier provided. The type of the
-     * Object returned is defined in the description of this interface.
-     * @param headerID the header identifier whose value is to be returned
-     * @return the value of the header provided or <code>null</code> if the
-     *         header identifier specified is not part of this
-     *         <code>HeaderSet</code> object
-     * @throws IllegalArgumentException if the <code>headerID</code> is not one
-     *         defined in this interface or any of the user-defined headers
-     * @throws IOException if an error occurred in the transport layer during
-     *         the operation or if the connection has been closed
-     */
-    public Object getHeader(int headerID) throws IOException {
-
-        switch (headerID) {
-            case COUNT:
-                return mCount;
-            case NAME:
-                return mName;
-            case TYPE:
-                return mType;
-            case LENGTH:
-                return mLength;
-            case TIME_ISO_8601:
-                return mIsoTime;
-            case TIME_4_BYTE:
-                return mByteTime;
-            case DESCRIPTION:
-                return mDescription;
-            case TARGET:
-                return mTarget;
-            case HTTP:
-                return mHttpHeader;
-            case WHO:
-                return mWho;
-            case CONNECTION_ID:
-                return mConnectionID;
-            case OBJECT_CLASS:
-                return mObjectClass;
-            case APPLICATION_PARAMETER:
-                return mAppParam;
-            case SINGLE_RESPONSE_MODE:
-                return mSingleResponseMode;
-            case SINGLE_RESPONSE_MODE_PARAMETER:
-                return mSrmParam;
-            default:
-                // Verify that it was not a Unicode String user Defined
-                if ((headerID >= 0x30) && (headerID <= 0x3F)) {
-                    return mUnicodeUserDefined[headerID - 0x30];
-                }
-                // Verify that it was not a byte sequence user defined header
-                if ((headerID >= 0x70) && (headerID <= 0x7F)) {
-                    return mSequenceUserDefined[headerID - 0x70];
-                }
-                // Verify that it was not a byte user defined header
-                if ((headerID >= 0xB0) && (headerID <= 0xBF)) {
-                    return mByteUserDefined[headerID - 0xB0];
-                }
-                // Verify that it was not a integer user defined header
-                if ((headerID >= 0xF0) && (headerID <= 0xFF)) {
-                    return mIntegerUserDefined[headerID - 0xF0];
-                }
-                throw new IllegalArgumentException("Invalid Header Identifier");
-        }
-    }
-
-    /**
-     * Retrieves the list of headers that may be retrieved via the
-     * <code>getHeader</code> method that will not return <code>null</code>. In
-     * other words, this method returns all the headers that are available in
-     * this object.
-     * @see #getHeader
-     * @return the array of headers that are set in this object or
-     *         <code>null</code> if no headers are available
-     * @throws IOException if an error occurred in the transport layer during
-     *         the operation or the connection has been closed
-     */
-    public int[] getHeaderList() throws IOException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        if (mCount != null) {
-            out.write(COUNT);
-        }
-        if (mName != null) {
-            out.write(NAME);
-        }
-        if (mType != null) {
-            out.write(TYPE);
-        }
-        if (mLength != null) {
-            out.write(LENGTH);
-        }
-        if (mIsoTime != null) {
-            out.write(TIME_ISO_8601);
-        }
-        if (mByteTime != null) {
-            out.write(TIME_4_BYTE);
-        }
-        if (mDescription != null) {
-            out.write(DESCRIPTION);
-        }
-        if (mTarget != null) {
-            out.write(TARGET);
-        }
-        if (mHttpHeader != null) {
-            out.write(HTTP);
-        }
-        if (mWho != null) {
-            out.write(WHO);
-        }
-        if (mAppParam != null) {
-            out.write(APPLICATION_PARAMETER);
-        }
-        if (mObjectClass != null) {
-            out.write(OBJECT_CLASS);
-        }
-        if(mSingleResponseMode != null) {
-            out.write(SINGLE_RESPONSE_MODE);
-        }
-        if(mSrmParam != null) {
-            out.write(SINGLE_RESPONSE_MODE_PARAMETER);
-        }
-
-        for (int i = 0x30; i < 0x40; i++) {
-            if (mUnicodeUserDefined[i - 0x30] != null) {
-                out.write(i);
-            }
-        }
-
-        for (int i = 0x70; i < 0x80; i++) {
-            if (mSequenceUserDefined[i - 0x70] != null) {
-                out.write(i);
-            }
-        }
-
-        for (int i = 0xB0; i < 0xC0; i++) {
-            if (mByteUserDefined[i - 0xB0] != null) {
-                out.write(i);
-            }
-        }
-
-        for (int i = 0xF0; i < 0x100; i++) {
-            if (mIntegerUserDefined[i - 0xF0] != null) {
-                out.write(i);
-            }
-        }
-
-        byte[] headers = out.toByteArray();
-        out.close();
-
-        if ((headers == null) || (headers.length == 0)) {
-            return null;
-        }
-
-        int[] result = new int[headers.length];
-        for (int i = 0; i < headers.length; i++) {
-            // Convert the byte to a positive integer.  That is, an integer
-            // between 0 and 256.
-            result[i] = headers[i] & 0xFF;
-        }
-
-        return result;
-    }
-
-    /**
-     * Sets the authentication challenge header. The <code>realm</code> will be
-     * encoded based upon the default encoding scheme used by the implementation
-     * to encode strings. Therefore, the encoding scheme used to encode the
-     * <code>realm</code> is application dependent.
-     * @param realm a short description that describes what password to use; if
-     *        <code>null</code> no realm will be sent in the authentication
-     *        challenge header
-     * @param userID if <code>true</code>, a user ID is required in the reply;
-     *        if <code>false</code>, no user ID is required
-     * @param access if <code>true</code> then full access will be granted if
-     *        successful; if <code>false</code> then read-only access will be
-     *        granted if successful
-     * @throws IOException
-     */
-    public void createAuthenticationChallenge(String realm, boolean userID, boolean access)
-            throws IOException {
-
-        nonce = new byte[16];
-        if(mRandom == null) {
-            mRandom = new SecureRandom();
-        }
-        for (int i = 0; i < 16; i++) {
-            nonce[i] = (byte)mRandom.nextInt();
-        }
-
-        mAuthChall = ObexHelper.computeAuthenticationChallenge(nonce, realm, access, userID);
-    }
-
-    /**
-     * Returns the response code received from the server. Response codes are
-     * defined in the <code>ResponseCodes</code> class.
-     * @see ResponseCodes
-     * @return the response code retrieved from the server
-     * @throws IOException if an error occurred in the transport layer during
-     *         the transaction; if this method is called on a
-     *         <code>HeaderSet</code> object created by calling
-     *         <code>createHeaderSet()</code> in a <code>ClientSession</code>
-     *         object; if this object was created by an OBEX server
-     */
-    public int getResponseCode() throws IOException {
-        if (responseCode == -1) {
-            throw new IOException("May not be called on a server");
-        } else {
-            return responseCode;
-        }
-    }
-}
diff --git a/obex/javax/obex/ObexHelper.java b/obex/javax/obex/ObexHelper.java
deleted file mode 100644
index 843793a..0000000
--- a/obex/javax/obex/ObexHelper.java
+++ /dev/null
@@ -1,1100 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- * Copyright (C) 2015 Samsung LSI
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import android.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-
-/**
- * This class defines a set of helper methods for the implementation of Obex.
- * @hide
- */
-public final class ObexHelper {
-
-    private static final String TAG = "ObexHelper";
-    public static final boolean VDBG = false;
-    /**
-     * Defines the basic packet length used by OBEX. Every OBEX packet has the
-     * same basic format:<BR>
-     * Byte 0: Request or Response Code Byte 1&2: Length of the packet.
-     */
-    public static final int BASE_PACKET_LENGTH = 3;
-
-    /** Prevent object construction of helper class */
-    private ObexHelper() {
-    }
-
-    /**
-     * The maximum packet size for OBEX packets that this client can handle. At
-     * present, this must be changed for each port. TODO: The max packet size
-     * should be the Max incoming MTU minus TODO: L2CAP package headers and
-     * RFCOMM package headers. TODO: Retrieve the max incoming MTU from TODO:
-     * LocalDevice.getProperty().
-     * NOTE: This value must be larger than or equal to the L2CAP SDU
-     */
-    /*
-     * android note set as 0xFFFE to match remote MPS
-     */
-    public static final int MAX_PACKET_SIZE_INT = 0xFFFE;
-
-    // The minimum allowed max packet size is 255 according to the OBEX specification
-    public static final int LOWER_LIMIT_MAX_PACKET_SIZE = 255;
-
-    // The length of OBEX Byte Sequency Header Id according to the OBEX specification
-    public static final int OBEX_BYTE_SEQ_HEADER_LEN = 0x03;
-
-    /**
-     * Temporary workaround to be able to push files to Windows 7.
-     * TODO: Should be removed as soon as Microsoft updates their driver.
-     */
-    public static final int MAX_CLIENT_PACKET_SIZE = 0xFC00;
-
-    public static final int OBEX_OPCODE_FINAL_BIT_MASK = 0x80;
-
-    public static final int OBEX_OPCODE_CONNECT = 0x80;
-
-    public static final int OBEX_OPCODE_DISCONNECT = 0x81;
-
-    public static final int OBEX_OPCODE_PUT = 0x02;
-
-    public static final int OBEX_OPCODE_PUT_FINAL = 0x82;
-
-    public static final int OBEX_OPCODE_GET = 0x03;
-
-    public static final int OBEX_OPCODE_GET_FINAL = 0x83;
-
-    public static final int OBEX_OPCODE_RESERVED = 0x04;
-
-    public static final int OBEX_OPCODE_RESERVED_FINAL = 0x84;
-
-    public static final int OBEX_OPCODE_SETPATH = 0x85;
-
-    public static final int OBEX_OPCODE_ABORT = 0xFF;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ASCII = 0x00;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_1 = 0x01;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_2 = 0x02;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_3 = 0x03;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_4 = 0x04;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_5 = 0x05;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_6 = 0x06;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_7 = 0x07;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_8 = 0x08;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_9 = 0x09;
-
-    public static final int OBEX_AUTH_REALM_CHARSET_UNICODE = 0xFF;
-
-    public static final byte OBEX_SRM_ENABLE         = 0x01; // For BT we only need enable/disable
-    public static final byte OBEX_SRM_DISABLE        = 0x00;
-    public static final byte OBEX_SRM_SUPPORT        = 0x02; // Unused for now
-
-    public static final byte OBEX_SRMP_WAIT          = 0x01; // Only SRMP value used by BT
-
-    /**
-     * Updates the HeaderSet with the headers received in the byte array
-     * provided. Invalid headers are ignored.
-     * <P>
-     * The first two bits of an OBEX Header specifies the type of object that is
-     * being sent. The table below specifies the meaning of the high bits.
-     * <TABLE>
-     * <TR>
-     * <TH>Bits 8 and 7</TH>
-     * <TH>Value</TH>
-     * <TH>Description</TH>
-     * </TR>
-     * <TR>
-     * <TD>00</TD>
-     * <TD>0x00</TD>
-     * <TD>Null Terminated Unicode text, prefixed with 2 byte unsigned integer</TD>
-     * </TR>
-     * <TR>
-     * <TD>01</TD>
-     * <TD>0x40</TD>
-     * <TD>Byte Sequence, length prefixed with 2 byte unsigned integer</TD>
-     * </TR>
-     * <TR>
-     * <TD>10</TD>
-     * <TD>0x80</TD>
-     * <TD>1 byte quantity</TD>
-     * </TR>
-     * <TR>
-     * <TD>11</TD>
-     * <TD>0xC0</TD>
-     * <TD>4 byte quantity - transmitted in network byte order (high byte first</TD>
-     * </TR>
-     * </TABLE>
-     * This method uses the information in this table to determine the type of
-     * Java object to create and passes that object with the full header to
-     * setHeader() to update the HeaderSet object. Invalid headers will cause an
-     * exception to be thrown. When it is thrown, it is ignored.
-     * @param header the HeaderSet to update
-     * @param headerArray the byte array containing headers
-     * @return the result of the last start body or end body header provided;
-     *         the first byte in the result will specify if a body or end of
-     *         body is received
-     * @throws IOException if an invalid header was found
-     */
-    public static byte[] updateHeaderSet(HeaderSet header, byte[] headerArray) throws IOException {
-        int index = 0;
-        int length = 0;
-        int headerID;
-        byte[] value = null;
-        byte[] body = null;
-        HeaderSet headerImpl = header;
-        try {
-            while (index < headerArray.length) {
-                headerID = 0xFF & headerArray[index];
-                switch (headerID & (0xC0)) {
-
-                    /*
-                     * 0x00 is a unicode null terminate string with the first
-                     * two bytes after the header identifier being the length
-                     */
-                    case 0x00:
-                        // Fall through
-                        /*
-                         * 0x40 is a byte sequence with the first
-                         * two bytes after the header identifier being the length
-                         */
-                    case 0x40:
-                        boolean trimTail = true;
-                        index++;
-                        length = ((0xFF & headerArray[index]) << 8) +
-                                 (0xFF & headerArray[index + 1]);
-                        index += 2;
-                        if (length <= OBEX_BYTE_SEQ_HEADER_LEN) {
-                            Log.e(TAG, "Remote sent an OBEX packet with " +
-                                  "incorrect header length = " + length);
-                            break;
-                        }
-                        length -= OBEX_BYTE_SEQ_HEADER_LEN;
-                        value = new byte[length];
-                        System.arraycopy(headerArray, index, value, 0, length);
-                        if (length == 0 || (length > 0 && (value[length - 1] != 0))) {
-                            trimTail = false;
-                        }
-                        switch (headerID) {
-                            case HeaderSet.TYPE:
-                                try {
-                                    // Remove trailing null
-                                    if (trimTail == false) {
-                                        headerImpl.setHeader(headerID, new String(value, 0,
-                                                value.length, "ISO8859_1"));
-                                    } else {
-                                        headerImpl.setHeader(headerID, new String(value, 0,
-                                                value.length - 1, "ISO8859_1"));
-                                    }
-                                } catch (UnsupportedEncodingException e) {
-                                    throw e;
-                                }
-                                break;
-
-                            case HeaderSet.AUTH_CHALLENGE:
-                                headerImpl.mAuthChall = new byte[length];
-                                System.arraycopy(headerArray, index, headerImpl.mAuthChall, 0,
-                                        length);
-                                break;
-
-                            case HeaderSet.AUTH_RESPONSE:
-                                headerImpl.mAuthResp = new byte[length];
-                                System.arraycopy(headerArray, index, headerImpl.mAuthResp, 0,
-                                        length);
-                                break;
-
-                            case HeaderSet.BODY:
-                                /* Fall Through */
-                            case HeaderSet.END_OF_BODY:
-                                body = new byte[length + 1];
-                                body[0] = (byte)headerID;
-                                System.arraycopy(headerArray, index, body, 1, length);
-                                break;
-
-                            case HeaderSet.TIME_ISO_8601:
-                                try {
-                                    String dateString = new String(value, "ISO8859_1");
-                                    Calendar temp = Calendar.getInstance();
-                                    if ((dateString.length() == 16)
-                                            && (dateString.charAt(15) == 'Z')) {
-                                        temp.setTimeZone(TimeZone.getTimeZone("UTC"));
-                                    }
-                                    temp.set(Calendar.YEAR, Integer.parseInt(dateString.substring(
-                                            0, 4)));
-                                    temp.set(Calendar.MONTH, Integer.parseInt(dateString.substring(
-                                            4, 6)));
-                                    temp.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateString
-                                            .substring(6, 8)));
-                                    temp.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateString
-                                            .substring(9, 11)));
-                                    temp.set(Calendar.MINUTE, Integer.parseInt(dateString
-                                            .substring(11, 13)));
-                                    temp.set(Calendar.SECOND, Integer.parseInt(dateString
-                                            .substring(13, 15)));
-                                    headerImpl.setHeader(HeaderSet.TIME_ISO_8601, temp);
-                                } catch (UnsupportedEncodingException e) {
-                                    throw e;
-                                }
-                                break;
-
-                            default:
-                                if ((headerID & 0xC0) == 0x00) {
-                                    headerImpl.setHeader(headerID, ObexHelper.convertToUnicode(
-                                            value, true));
-                                } else {
-                                    headerImpl.setHeader(headerID, value);
-                                }
-                        }
-
-                        index += length;
-                        break;
-
-                    /*
-                     * 0x80 is a byte header.  The only valid byte headers are
-                     * the 16 user defined byte headers.
-                     */
-                    case 0x80:
-                        index++;
-                        try {
-                            headerImpl.setHeader(headerID, Byte.valueOf(headerArray[index]));
-                        } catch (Exception e) {
-                            // Not a valid header so ignore
-                        }
-                        index++;
-                        break;
-
-                    /*
-                     * 0xC0 is a 4 byte unsigned integer header and with the
-                     * exception of TIME_4_BYTE will be converted to a Long
-                     * and added.
-                     */
-                    case 0xC0:
-                        index++;
-                        value = new byte[4];
-                        System.arraycopy(headerArray, index, value, 0, 4);
-                        try {
-                            if (headerID != HeaderSet.TIME_4_BYTE) {
-                                // Determine if it is a connection ID.  These
-                                // need to be handled differently
-                                if (headerID == HeaderSet.CONNECTION_ID) {
-                                    headerImpl.mConnectionID = new byte[4];
-                                    System.arraycopy(value, 0, headerImpl.mConnectionID, 0, 4);
-                                } else {
-                                    headerImpl.setHeader(headerID, Long
-                                            .valueOf(convertToLong(value)));
-                                }
-                            } else {
-                                Calendar temp = Calendar.getInstance();
-                                temp.setTime(new Date(convertToLong(value) * 1000L));
-                                headerImpl.setHeader(HeaderSet.TIME_4_BYTE, temp);
-                            }
-                        } catch (Exception e) {
-                            // Not a valid header so ignore
-                            throw new IOException("Header was not formatted properly", e);
-                        }
-                        index += 4;
-                        break;
-                }
-
-            }
-        } catch (IOException e) {
-            throw new IOException("Header was not formatted properly", e);
-        }
-
-        return body;
-    }
-
-    /**
-     * Creates the header part of OBEX packet based on the header provided.
-     * TODO: Could use getHeaderList() to get the array of headers to include
-     * and then use the high two bits to determine the the type of the object
-     * and construct the byte array from that. This will make the size smaller.
-     * @param head the header used to construct the byte array
-     * @param nullOut <code>true</code> if the header should be set to
-     *        <code>null</code> once it is added to the array or
-     *        <code>false</code> if it should not be nulled out
-     * @return the header of an OBEX packet
-     */
-    public static byte[] createHeader(HeaderSet head, boolean nullOut) {
-        Long intHeader = null;
-        String stringHeader = null;
-        Calendar dateHeader = null;
-        Byte byteHeader = null;
-        StringBuffer buffer = null;
-        byte[] value = null;
-        byte[] result = null;
-        byte[] lengthArray = new byte[2];
-        int length;
-        HeaderSet headImpl = null;
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        headImpl = head;
-
-        try {
-            /*
-             * Determine if there is a connection ID to send.  If there is,
-             * then it should be the first header in the packet.
-             */
-            if ((headImpl.mConnectionID != null) && (headImpl.getHeader(HeaderSet.TARGET) == null)) {
-
-                out.write((byte)HeaderSet.CONNECTION_ID);
-                out.write(headImpl.mConnectionID);
-            }
-
-            // Count Header
-            intHeader = (Long)headImpl.getHeader(HeaderSet.COUNT);
-            if (intHeader != null) {
-                out.write((byte)HeaderSet.COUNT);
-                value = ObexHelper.convertToByteArray(intHeader.longValue());
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.COUNT, null);
-                }
-            }
-
-            // Name Header
-            stringHeader = (String)headImpl.getHeader(HeaderSet.NAME);
-            if (stringHeader != null) {
-                out.write((byte)HeaderSet.NAME);
-                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
-                length = value.length + 3;
-                lengthArray[0] = (byte)(0xFF & (length >> 8));
-                lengthArray[1] = (byte)(0xFF & length);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.NAME, null);
-                }
-            } else if (headImpl.getEmptyNameHeader()) {
-                out.write((byte) HeaderSet.NAME);
-                lengthArray[0] = (byte) 0x00;
-                lengthArray[1] = (byte) 0x03;
-                out.write(lengthArray);
-            }
-
-            // Type Header
-            stringHeader = (String)headImpl.getHeader(HeaderSet.TYPE);
-            if (stringHeader != null) {
-                out.write((byte)HeaderSet.TYPE);
-                try {
-                    value = stringHeader.getBytes("ISO8859_1");
-                } catch (UnsupportedEncodingException e) {
-                    throw e;
-                }
-
-                length = value.length + 4;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(value);
-                out.write(0x00);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.TYPE, null);
-                }
-            }
-
-            // Length Header
-            intHeader = (Long)headImpl.getHeader(HeaderSet.LENGTH);
-            if (intHeader != null) {
-                out.write((byte)HeaderSet.LENGTH);
-                value = ObexHelper.convertToByteArray(intHeader.longValue());
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.LENGTH, null);
-                }
-            }
-
-            // Time ISO Header
-            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_ISO_8601);
-            if (dateHeader != null) {
-
-                /*
-                 * The ISO Header should take the form YYYYMMDDTHHMMSSZ.  The
-                 * 'Z' will only be included if it is a UTC time.
-                 */
-                buffer = new StringBuffer();
-                int temp = dateHeader.get(Calendar.YEAR);
-                for (int i = temp; i < 1000; i = i * 10) {
-                    buffer.append("0");
-                }
-                buffer.append(temp);
-                temp = dateHeader.get(Calendar.MONTH);
-                if (temp < 10) {
-                    buffer.append("0");
-                }
-                buffer.append(temp);
-                temp = dateHeader.get(Calendar.DAY_OF_MONTH);
-                if (temp < 10) {
-                    buffer.append("0");
-                }
-                buffer.append(temp);
-                buffer.append("T");
-                temp = dateHeader.get(Calendar.HOUR_OF_DAY);
-                if (temp < 10) {
-                    buffer.append("0");
-                }
-                buffer.append(temp);
-                temp = dateHeader.get(Calendar.MINUTE);
-                if (temp < 10) {
-                    buffer.append("0");
-                }
-                buffer.append(temp);
-                temp = dateHeader.get(Calendar.SECOND);
-                if (temp < 10) {
-                    buffer.append("0");
-                }
-                buffer.append(temp);
-
-                if (dateHeader.getTimeZone().getID().equals("UTC")) {
-                    buffer.append("Z");
-                }
-
-                try {
-                    value = buffer.toString().getBytes("ISO8859_1");
-                } catch (UnsupportedEncodingException e) {
-                    throw e;
-                }
-
-                length = value.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(HeaderSet.TIME_ISO_8601);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.TIME_ISO_8601, null);
-                }
-            }
-
-            // Time 4 Byte Header
-            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_4_BYTE);
-            if (dateHeader != null) {
-                out.write(HeaderSet.TIME_4_BYTE);
-
-                /*
-                 * Need to call getTime() twice.  The first call will return
-                 * a java.util.Date object.  The second call returns the number
-                 * of milliseconds since January 1, 1970.  We need to convert
-                 * it to seconds since the TIME_4_BYTE expects the number of
-                 * seconds since January 1, 1970.
-                 */
-                value = ObexHelper.convertToByteArray(dateHeader.getTime().getTime() / 1000L);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.TIME_4_BYTE, null);
-                }
-            }
-
-            // Description Header
-            stringHeader = (String)headImpl.getHeader(HeaderSet.DESCRIPTION);
-            if (stringHeader != null) {
-                out.write((byte)HeaderSet.DESCRIPTION);
-                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
-                length = value.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.DESCRIPTION, null);
-                }
-            }
-
-            // Target Header
-            value = (byte[])headImpl.getHeader(HeaderSet.TARGET);
-            if (value != null) {
-                out.write((byte)HeaderSet.TARGET);
-                length = value.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.TARGET, null);
-                }
-            }
-
-            // HTTP Header
-            value = (byte[])headImpl.getHeader(HeaderSet.HTTP);
-            if (value != null) {
-                out.write((byte)HeaderSet.HTTP);
-                length = value.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.HTTP, null);
-                }
-            }
-
-            // Who Header
-            value = (byte[])headImpl.getHeader(HeaderSet.WHO);
-            if (value != null) {
-                out.write((byte)HeaderSet.WHO);
-                length = value.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.WHO, null);
-                }
-            }
-
-            // Connection ID Header
-            value = (byte[])headImpl.getHeader(HeaderSet.APPLICATION_PARAMETER);
-            if (value != null) {
-                out.write((byte)HeaderSet.APPLICATION_PARAMETER);
-                length = value.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.APPLICATION_PARAMETER, null);
-                }
-            }
-
-            // Object Class Header
-            value = (byte[])headImpl.getHeader(HeaderSet.OBJECT_CLASS);
-            if (value != null) {
-                out.write((byte)HeaderSet.OBJECT_CLASS);
-                length = value.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(value);
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.OBJECT_CLASS, null);
-                }
-            }
-
-            // Check User Defined Headers
-            for (int i = 0; i < 16; i++) {
-
-                //Unicode String Header
-                stringHeader = (String)headImpl.getHeader(i + 0x30);
-                if (stringHeader != null) {
-                    out.write((byte)i + 0x30);
-                    value = ObexHelper.convertToUnicodeByteArray(stringHeader);
-                    length = value.length + 3;
-                    lengthArray[0] = (byte)(255 & (length >> 8));
-                    lengthArray[1] = (byte)(255 & length);
-                    out.write(lengthArray);
-                    out.write(value);
-                    if (nullOut) {
-                        headImpl.setHeader(i + 0x30, null);
-                    }
-                }
-
-                // Byte Sequence Header
-                value = (byte[])headImpl.getHeader(i + 0x70);
-                if (value != null) {
-                    out.write((byte)i + 0x70);
-                    length = value.length + 3;
-                    lengthArray[0] = (byte)(255 & (length >> 8));
-                    lengthArray[1] = (byte)(255 & length);
-                    out.write(lengthArray);
-                    out.write(value);
-                    if (nullOut) {
-                        headImpl.setHeader(i + 0x70, null);
-                    }
-                }
-
-                // Byte Header
-                byteHeader = (Byte)headImpl.getHeader(i + 0xB0);
-                if (byteHeader != null) {
-                    out.write((byte)i + 0xB0);
-                    out.write(byteHeader.byteValue());
-                    if (nullOut) {
-                        headImpl.setHeader(i + 0xB0, null);
-                    }
-                }
-
-                // Integer header
-                intHeader = (Long)headImpl.getHeader(i + 0xF0);
-                if (intHeader != null) {
-                    out.write((byte)i + 0xF0);
-                    out.write(ObexHelper.convertToByteArray(intHeader.longValue()));
-                    if (nullOut) {
-                        headImpl.setHeader(i + 0xF0, null);
-                    }
-                }
-            }
-
-            // Add the authentication challenge header
-            if (headImpl.mAuthChall != null) {
-                out.write((byte)HeaderSet.AUTH_CHALLENGE);
-                length = headImpl.mAuthChall.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(headImpl.mAuthChall);
-                if (nullOut) {
-                    headImpl.mAuthChall = null;
-                }
-            }
-
-            // Add the authentication response header
-            if (headImpl.mAuthResp != null) {
-                out.write((byte)HeaderSet.AUTH_RESPONSE);
-                length = headImpl.mAuthResp.length + 3;
-                lengthArray[0] = (byte)(255 & (length >> 8));
-                lengthArray[1] = (byte)(255 & length);
-                out.write(lengthArray);
-                out.write(headImpl.mAuthResp);
-                if (nullOut) {
-                    headImpl.mAuthResp = null;
-                }
-            }
-
-            // TODO:
-            // If the SRM and SRMP header is in use, they must be send in the same OBEX packet
-            // But the current structure of the obex code cannot handle this, and therefore
-            // it makes sense to put them in the tail of the headers, since we then reduce the
-            // chance of enabling SRM to soon. The down side is that SRM cannot be used while
-            // transferring non-body headers
-
-            // Add the SRM header
-            byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
-            if (byteHeader != null) {
-                out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE);
-                out.write(byteHeader.byteValue());
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, null);
-                }
-            }
-
-            // Add the SRM parameter header
-            byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
-            if (byteHeader != null) {
-                out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
-                out.write(byteHeader.byteValue());
-                if (nullOut) {
-                    headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
-                }
-            }
-
-        } catch (IOException e) {
-        } finally {
-            result = out.toByteArray();
-            try {
-                out.close();
-            } catch (Exception ex) {
-            }
-        }
-
-        return result;
-
-    }
-
-    /**
-     * Determines where the maximum divide is between headers. This method is
-     * used by put and get operations to separate headers to a size that meets
-     * the max packet size allowed.
-     * @param headerArray the headers to separate
-     * @param start the starting index to search
-     * @param maxSize the maximum size of a packet
-     * @return the index of the end of the header block to send or -1 if the
-     *         header could not be divided because the header is too large
-     */
-    public static int findHeaderEnd(byte[] headerArray, int start, int maxSize) {
-
-        int fullLength = 0;
-        int lastLength = -1;
-        int index = start;
-        int length = 0;
-
-        // TODO: Ensure SRM and SRMP headers are not split into two OBEX packets
-
-        while ((fullLength < maxSize) && (index < headerArray.length)) {
-            int headerID = (headerArray[index] < 0 ? headerArray[index] + 256 : headerArray[index]);
-            lastLength = fullLength;
-
-            switch (headerID & (0xC0)) {
-
-                case 0x00:
-                    // Fall through
-                case 0x40:
-
-                    index++;
-                    length = (headerArray[index] < 0 ? headerArray[index] + 256
-                            : headerArray[index]);
-                    length = length << 8;
-                    index++;
-                    length += (headerArray[index] < 0 ? headerArray[index] + 256
-                            : headerArray[index]);
-                    length -= 3;
-                    index++;
-                    index += length;
-                    fullLength += length + 3;
-                    break;
-
-                case 0x80:
-
-                    index++;
-                    index++;
-                    fullLength += 2;
-                    break;
-
-                case 0xC0:
-
-                    index += 5;
-                    fullLength += 5;
-                    break;
-
-            }
-
-        }
-
-        /*
-         * Determine if this is the last header or not
-         */
-        if (lastLength == 0) {
-            /*
-             * Since this is the last header, check to see if the size of this
-             * header is less then maxSize.  If it is, return the length of the
-             * header, otherwise return -1.  The length of the header is
-             * returned since it would be the start of the next header
-             */
-            if (fullLength < maxSize) {
-                return headerArray.length;
-            } else {
-                return -1;
-            }
-        } else {
-            return lastLength + start;
-        }
-    }
-
-    /**
-     * Converts the byte array to a long.
-     * @param b the byte array to convert to a long
-     * @return the byte array as a long
-     */
-    public static long convertToLong(byte[] b) {
-        long result = 0;
-        long value = 0;
-        long power = 0;
-
-        for (int i = (b.length - 1); i >= 0; i--) {
-            value = b[i];
-            if (value < 0) {
-                value += 256;
-            }
-
-            result = result | (value << power);
-            power += 8;
-        }
-
-        return result;
-    }
-
-    /**
-     * Converts the long to a 4 byte array. The long must be non negative.
-     * @param l the long to convert
-     * @return a byte array that is the same as the long
-     */
-    public static byte[] convertToByteArray(long l) {
-        byte[] b = new byte[4];
-
-        b[0] = (byte)(255 & (l >> 24));
-        b[1] = (byte)(255 & (l >> 16));
-        b[2] = (byte)(255 & (l >> 8));
-        b[3] = (byte)(255 & l);
-
-        return b;
-    }
-
-    /**
-     * Converts the String to a UNICODE byte array. It will also add the ending
-     * null characters to the end of the string.
-     * @param s the string to convert
-     * @return the unicode byte array of the string
-     */
-    public static byte[] convertToUnicodeByteArray(String s) {
-        if (s == null) {
-            return null;
-        }
-
-        char c[] = s.toCharArray();
-        byte[] result = new byte[(c.length * 2) + 2];
-        for (int i = 0; i < c.length; i++) {
-            result[(i * 2)] = (byte)(c[i] >> 8);
-            result[((i * 2) + 1)] = (byte)c[i];
-        }
-
-        // Add the UNICODE null character
-        result[result.length - 2] = 0;
-        result[result.length - 1] = 0;
-
-        return result;
-    }
-
-    /**
-     * Retrieves the value from the byte array for the tag value specified. The
-     * array should be of the form Tag - Length - Value triplet.
-     * @param tag the tag to retrieve from the byte array
-     * @param triplet the byte sequence containing the tag length value form
-     * @return the value of the specified tag
-     */
-    public static byte[] getTagValue(byte tag, byte[] triplet) {
-
-        int index = findTag(tag, triplet);
-        if (index == -1) {
-            return null;
-        }
-
-        index++;
-        int length = triplet[index] & 0xFF;
-
-        byte[] result = new byte[length];
-        index++;
-        System.arraycopy(triplet, index, result, 0, length);
-
-        return result;
-    }
-
-    /**
-     * Finds the index that starts the tag value pair in the byte array provide.
-     * @param tag the tag to look for
-     * @param value the byte array to search
-     * @return the starting index of the tag or -1 if the tag could not be found
-     */
-    public static int findTag(byte tag, byte[] value) {
-        int length = 0;
-
-        if (value == null) {
-            return -1;
-        }
-
-        int index = 0;
-
-        while ((index < value.length) && (value[index] != tag)) {
-            length = value[index + 1] & 0xFF;
-            index += length + 2;
-        }
-
-        if (index >= value.length) {
-            return -1;
-        }
-
-        return index;
-    }
-
-    /**
-     * Converts the byte array provided to a unicode string.
-     * @param b the byte array to convert to a string
-     * @param includesNull determine if the byte string provided contains the
-     *        UNICODE null character at the end or not; if it does, it will be
-     *        removed
-     * @return a Unicode string
-     * @throws IllegalArgumentException if the byte array has an odd length
-     */
-    public static String convertToUnicode(byte[] b, boolean includesNull) {
-        if (b == null || b.length == 0) {
-            return null;
-        }
-        int arrayLength = b.length;
-        if (!((arrayLength % 2) == 0)) {
-            throw new IllegalArgumentException("Byte array not of a valid form");
-        }
-        arrayLength = (arrayLength >> 1);
-        if (includesNull) {
-            arrayLength -= 1;
-        }
-
-        char[] c = new char[arrayLength];
-        for (int i = 0; i < arrayLength; i++) {
-            int upper = b[2 * i];
-            int lower = b[(2 * i) + 1];
-            if (upper < 0) {
-                upper += 256;
-            }
-            if (lower < 0) {
-                lower += 256;
-            }
-            // If upper and lower both equal 0, it should be the end of string.
-            // Ignore left bytes from array to avoid potential issues
-            if (upper == 0 && lower == 0) {
-                return new String(c, 0, i);
-            }
-
-            c[i] = (char)((upper << 8) | lower);
-        }
-
-        return new String(c);
-    }
-
-    /**
-     * Compute the MD5 hash of the byte array provided. Does not accumulate
-     * input.
-     * @param in the byte array to hash
-     * @return the MD5 hash of the byte array
-     */
-    public static byte[] computeMd5Hash(byte[] in) {
-        try {
-            MessageDigest md5 = MessageDigest.getInstance("MD5");
-            return md5.digest(in);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Computes an authentication challenge header.
-     * @param nonce the challenge that will be provided to the peer; the
-     *        challenge must be 16 bytes long
-     * @param realm a short description that describes what password to use
-     * @param access if <code>true</code> then full access will be granted if
-     *        successful; if <code>false</code> then read only access will be
-     *        granted if successful
-     * @param userID if <code>true</code>, a user ID is required in the reply;
-     *        if <code>false</code>, no user ID is required
-     * @throws IllegalArgumentException if the challenge is not 16 bytes long;
-     *         if the realm can not be encoded in less then 255 bytes
-     * @throws IOException if the encoding scheme ISO 8859-1 is not supported
-     */
-    public static byte[] computeAuthenticationChallenge(byte[] nonce, String realm, boolean access,
-            boolean userID) throws IOException {
-        byte[] authChall = null;
-
-        if (nonce.length != 16) {
-            throw new IllegalArgumentException("Nonce must be 16 bytes long");
-        }
-
-        /*
-         * The authentication challenge is a byte sequence of the following form
-         * byte 0: 0x00 - the tag for the challenge
-         * byte 1: 0x10 - the length of the challenge; must be 16
-         * byte 2-17: the authentication challenge
-         * byte 18: 0x01 - the options tag; this is optional in the spec, but
-         *                 we are going to include it in every message
-         * byte 19: 0x01 - length of the options; must be 1
-         * byte 20: the value of the options; bit 0 is set if user ID is
-         *          required; bit 1 is set if access mode is read only
-         * byte 21: 0x02 - the tag for authentication realm; only included if
-         *                 an authentication realm is specified
-         * byte 22: the length of the authentication realm; only included if
-         *          the authentication realm is specified
-         * byte 23: the encoding scheme of the authentication realm; we will use
-         *          the ISO 8859-1 encoding scheme since it is part of the KVM
-         * byte 24 & up: the realm if one is specified.
-         */
-        if (realm == null) {
-            authChall = new byte[21];
-        } else {
-            if (realm.length() >= 255) {
-                throw new IllegalArgumentException("Realm must be less then 255 bytes");
-            }
-            authChall = new byte[24 + realm.length()];
-            authChall[21] = 0x02;
-            authChall[22] = (byte)(realm.length() + 1);
-            authChall[23] = 0x01; // ISO 8859-1 Encoding
-            System.arraycopy(realm.getBytes("ISO8859_1"), 0, authChall, 24, realm.length());
-        }
-
-        // Include the nonce field in the header
-        authChall[0] = 0x00;
-        authChall[1] = 0x10;
-        System.arraycopy(nonce, 0, authChall, 2, 16);
-
-        // Include the options header
-        authChall[18] = 0x01;
-        authChall[19] = 0x01;
-        authChall[20] = 0x00;
-
-        if (!access) {
-            authChall[20] = (byte)(authChall[20] | 0x02);
-        }
-        if (userID) {
-            authChall[20] = (byte)(authChall[20] | 0x01);
-        }
-
-        return authChall;
-    }
-
-    /**
-     * Return the maximum allowed OBEX packet to transmit.
-     * OBEX packets transmitted must be smaller than this value.
-     * @param transport Reference to the ObexTransport in use.
-     * @return the maximum allowed OBEX packet to transmit
-     */
-    public static int getMaxTxPacketSize(ObexTransport transport) {
-        int size = transport.getMaxTransmitPacketSize();
-        return validateMaxPacketSize(size);
-    }
-
-    /**
-     * Return the maximum allowed OBEX packet to receive - used in OBEX connect.
-     * @param transport
-     * @return he maximum allowed OBEX packet to receive
-     */
-    public static int getMaxRxPacketSize(ObexTransport transport) {
-        int size = transport.getMaxReceivePacketSize();
-        return validateMaxPacketSize(size);
-    }
-
-    private static int validateMaxPacketSize(int size) {
-        if (VDBG && (size > MAX_PACKET_SIZE_INT)) {
-            Log.w(TAG, "The packet size supported for the connection (" + size + ") is larger"
-                    + " than the configured OBEX packet size: " + MAX_PACKET_SIZE_INT);
-        }
-        if (size != -1 && size < MAX_PACKET_SIZE_INT) {
-            if (size < LOWER_LIMIT_MAX_PACKET_SIZE) {
-                throw new IllegalArgumentException(size + " is less that the lower limit: "
-                        + LOWER_LIMIT_MAX_PACKET_SIZE);
-            }
-            return size;
-        }
-        return MAX_PACKET_SIZE_INT;
-    }
-}
diff --git a/obex/javax/obex/ObexSession.java b/obex/javax/obex/ObexSession.java
deleted file mode 100644
index 542b9c8..0000000
--- a/obex/javax/obex/ObexSession.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.IOException;
-
-import android.util.Log;
-
-/**
- * The <code>ObexSession</code> interface characterizes the term
- * "OBEX Connection" as defined in the IrDA Object Exchange Protocol v1.2, which
- * could be the server-side view of an OBEX connection, or the client-side view
- * of the same connection, which is established by server's accepting of a
- * client issued "CONNECT".
- * <P>
- * This interface serves as the common super class for
- * <CODE>ClientSession</CODE> and <CODE>ServerSession</CODE>.
- * @hide
- */
-public class ObexSession {
-
-    private static final String TAG = "ObexSession";
-    private static final boolean V = ObexHelper.VDBG;
-
-    protected Authenticator mAuthenticator;
-
-    protected byte[] mChallengeDigest;
-
-    /**
-     * Called when the server received an authentication challenge header. This
-     * will cause the authenticator to handle the authentication challenge.
-     * @param header the header with the authentication challenge
-     * @return <code>true</code> if the last request should be resent;
-     *         <code>false</code> if the last request should not be resent
-     * @throws IOException
-     */
-    public boolean handleAuthChall(HeaderSet header) throws IOException {
-        if (mAuthenticator == null) {
-            return false;
-        }
-
-        /*
-         * An authentication challenge is made up of one required and two
-         * optional tag length value triplets. The tag 0x00 is required to be in
-         * the authentication challenge and it represents the challenge digest
-         * that was received. The tag 0x01 is the options tag. This tag tracks
-         * if user ID is required and if full access will be granted. The tag
-         * 0x02 is the realm, which provides a description of which user name
-         * and password to use.
-         */
-        byte[] challenge = ObexHelper.getTagValue((byte)0x00, header.mAuthChall);
-        byte[] option = ObexHelper.getTagValue((byte)0x01, header.mAuthChall);
-        byte[] description = ObexHelper.getTagValue((byte)0x02, header.mAuthChall);
-
-        String realm = null;
-        if (description != null) {
-            byte[] realmString = new byte[description.length - 1];
-            System.arraycopy(description, 1, realmString, 0, realmString.length);
-
-            switch (description[0] & 0xFF) {
-
-                case ObexHelper.OBEX_AUTH_REALM_CHARSET_ASCII:
-                    // ASCII encoding
-                    // Fall through
-                case ObexHelper.OBEX_AUTH_REALM_CHARSET_ISO_8859_1:
-                    // ISO-8859-1 encoding
-                    try {
-                        realm = new String(realmString, "ISO8859_1");
-                    } catch (Exception e) {
-                        throw new IOException("Unsupported Encoding Scheme");
-                    }
-                    break;
-
-                case ObexHelper.OBEX_AUTH_REALM_CHARSET_UNICODE:
-                    // UNICODE Encoding
-                    realm = ObexHelper.convertToUnicode(realmString, false);
-                    break;
-
-                default:
-                    throw new IOException("Unsupported Encoding Scheme");
-            }
-        }
-
-        boolean isUserIDRequired = false;
-        boolean isFullAccess = true;
-        if (option != null) {
-            if ((option[0] & 0x01) != 0) {
-                isUserIDRequired = true;
-            }
-
-            if ((option[0] & 0x02) != 0) {
-                isFullAccess = false;
-            }
-        }
-
-        PasswordAuthentication result = null;
-        header.mAuthChall = null;
-
-        try {
-            result = mAuthenticator
-                    .onAuthenticationChallenge(realm, isUserIDRequired, isFullAccess);
-        } catch (Exception e) {
-            if (V) Log.d(TAG, "Exception occured - returning false", e);
-            return false;
-        }
-
-        /*
-         * If no password is provided then we not resent the request
-         */
-        if (result == null) {
-            return false;
-        }
-
-        byte[] password = result.getPassword();
-        if (password == null) {
-            return false;
-        }
-
-        byte[] userName = result.getUserName();
-
-        /*
-         * Create the authentication response header. It includes 1 required and
-         * 2 option tag length value triples. The required triple has a tag of
-         * 0x00 and is the response digest. The first optional tag is 0x01 and
-         * represents the user ID. If no user ID is provided, then no user ID
-         * will be sent. The second optional tag is 0x02 and is the challenge
-         * that was received. This will always be sent
-         */
-        if (userName != null) {
-            header.mAuthResp = new byte[38 + userName.length];
-            header.mAuthResp[36] = (byte)0x01;
-            header.mAuthResp[37] = (byte)userName.length;
-            System.arraycopy(userName, 0, header.mAuthResp, 38, userName.length);
-        } else {
-            header.mAuthResp = new byte[36];
-        }
-
-        // Create the secret String
-        byte[] digest = new byte[challenge.length + password.length + 1];
-        System.arraycopy(challenge, 0, digest, 0, challenge.length);
-        // Insert colon between challenge and password
-        digest[challenge.length] = (byte)0x3A;
-        System.arraycopy(password, 0, digest, challenge.length + 1, password.length);
-
-        // Add the Response Digest
-        header.mAuthResp[0] = (byte)0x00;
-        header.mAuthResp[1] = (byte)0x10;
-
-        System.arraycopy(ObexHelper.computeMd5Hash(digest), 0, header.mAuthResp, 2, 16);
-
-        // Add the challenge
-        header.mAuthResp[18] = (byte)0x02;
-        header.mAuthResp[19] = (byte)0x10;
-        System.arraycopy(challenge, 0, header.mAuthResp, 20, 16);
-
-        return true;
-    }
-
-    /**
-     * Called when the server received an authentication response header. This
-     * will cause the authenticator to handle the authentication response.
-     * @param authResp the authentication response
-     * @return <code>true</code> if the response passed; <code>false</code> if
-     *         the response failed
-     */
-    public boolean handleAuthResp(byte[] authResp) {
-        if (mAuthenticator == null) {
-            return false;
-        }
-        // get the correct password from the application
-        byte[] correctPassword = mAuthenticator.onAuthenticationResponse(ObexHelper.getTagValue(
-                (byte)0x01, authResp));
-        if (correctPassword == null) {
-            return false;
-        }
-
-        byte[] temp = new byte[correctPassword.length + 16];
-
-        System.arraycopy(mChallengeDigest, 0, temp, 0, 16);
-        System.arraycopy(correctPassword, 0, temp, 16, correctPassword.length);
-
-        byte[] correctResponse = ObexHelper.computeMd5Hash(temp);
-        byte[] actualResponse = ObexHelper.getTagValue((byte)0x00, authResp);
-
-        // compare the MD5 hash array .
-        for (int i = 0; i < 16; i++) {
-            if (correctResponse[i] != actualResponse[i]) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-}
diff --git a/obex/javax/obex/ObexTransport.java b/obex/javax/obex/ObexTransport.java
deleted file mode 100644
index 4cef0b3..0000000
--- a/obex/javax/obex/ObexTransport.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * The <code>ObexTransport</code> interface defines the underlying transport
- * connection which carries the OBEX protocol( such as TCP, RFCOMM device file
- * exposed by Bluetooth or USB in kernel, RFCOMM socket emulated in Android
- * platform, Irda). This interface provides an abstract layer to be used by the
- * <code>ObexConnection</code>. Each kind of medium shall have its own
- * implementation to wrap and follow the same interface.
- * <P>
- * See section 1.2.2 of IrDA Object Exchange Protocol specification.
- * <P>
- * Different kind of medium may have different construction - for example, the
- * RFCOMM device file medium may be constructed from a file descriptor or simply
- * a string while the TCP medium usually from a socket.
- * @hide
- */
-public interface ObexTransport {
-
-    void create() throws IOException;
-
-    void listen() throws IOException;
-
-    void close() throws IOException;
-
-    void connect() throws IOException;
-
-    void disconnect() throws IOException;
-
-    InputStream openInputStream() throws IOException;
-
-    OutputStream openOutputStream() throws IOException;
-
-    DataInputStream openDataInputStream() throws IOException;
-
-    DataOutputStream openDataOutputStream() throws IOException;
-
-    /**
-     * Must return the maximum allowed OBEX packet that can be sent over
-     * the transport. For L2CAP this will be the Max SDU reported by the
-     * peer device.
-     * The returned value will be used to set the outgoing OBEX packet
-     * size. Therefore this value shall not change.
-     * For RFCOMM or other transport types where the OBEX packets size
-     * is unrelated to the transport packet size, return -1;
-     * Exception can be made (like PBAP transport) with a smaller value
-     * to avoid bad effect on other profiles using the RFCOMM;
-     * @return the maximum allowed OBEX packet that can be send over
-     *         the transport. Or -1 in case of don't care.
-     */
-    int getMaxTransmitPacketSize();
-
-    /**
-     * Must return the maximum allowed OBEX packet that can be received over
-     * the transport. For L2CAP this will be the Max SDU configured for the
-     * L2CAP channel.
-     * The returned value will be used to validate the incoming packet size
-     * values.
-     * For RFCOMM or other transport types where the OBEX packets size
-     * is unrelated to the transport packet size, return -1;
-     * @return the maximum allowed OBEX packet that can be send over
-     *         the transport. Or -1 in case of don't care.
-     */
-    int getMaxReceivePacketSize();
-
-    /**
-     * Shall return true if the transport in use supports SRM.
-     * @return
-     *        <code>true</code> if SRM operation is supported, and is to be enabled.
-     *        <code>false</code> if SRM operations are not supported, or should not be used.
-     */
-    boolean isSrmSupported();
-
-
-}
diff --git a/obex/javax/obex/Operation.java b/obex/javax/obex/Operation.java
deleted file mode 100644
index 5b4d5ac..0000000
--- a/obex/javax/obex/Operation.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * The <code>Operation</code> interface provides ways to manipulate a single
- * OBEX PUT or GET operation. The implementation of this interface sends OBEX
- * packets as they are built. If during the operation the peer in the operation
- * ends the operation, an <code>IOException</code> is thrown on the next read
- * from the input stream, write to the output stream, or call to
- * <code>sendHeaders()</code>.
- * <P>
- * <STRONG>Definition of methods inherited from <code>ContentConnection</code>
- * </STRONG>
- * <P>
- * <code>getEncoding()</code> will always return <code>null</code>. <BR>
- * <code>getLength()</code> will return the length specified by the OBEX Length
- * header or -1 if the OBEX Length header was not included. <BR>
- * <code>getType()</code> will return the value specified in the OBEX Type
- * header or <code>null</code> if the OBEX Type header was not included.<BR>
- * <P>
- * <STRONG>How Headers are Handled</STRONG>
- * <P>
- * As headers are received, they may be retrieved through the
- * <code>getReceivedHeaders()</code> method. If new headers are set during the
- * operation, the new headers will be sent during the next packet exchange.
- * <P>
- * <STRONG>PUT example</STRONG>
- * <P>
- * <PRE>
- * void putObjectViaOBEX(ClientSession conn, HeaderSet head, byte[] obj) throws IOException {
- *     // Include the length header
- *     head.setHeader(head.LENGTH, new Long(obj.length));
- *     // Initiate the PUT request
- *     Operation op = conn.put(head);
- *     // Open the output stream to put the object to it
- *     DataOutputStream out = op.openDataOutputStream();
- *     // Send the object to the server
- *     out.write(obj);
- *     // End the transaction
- *     out.close();
- *     op.close();
- * }
- * </PRE>
- * <P>
- * <STRONG>GET example</STRONG>
- * <P>
- * <PRE>
- * byte[] getObjectViaOBEX(ClientSession conn, HeaderSet head) throws IOException {
- *     // Send the initial GET request to the server
- *     Operation op = conn.get(head);
- *     // Retrieve the length of the object being sent back
- *     int length = op.getLength();
- *     // Create space for the object
- *     byte[] obj = new byte[length];
- *     // Get the object from the input stream
- *     DataInputStream in = trans.openDataInputStream();
- *     in.read(obj);
- *     // End the transaction
- *     in.close();
- *     op.close();
- *     return obj;
- * }
- * </PRE>
- *
- * <H3>Client PUT Operation Flow</H3> For PUT operations, a call to
- * <code>close()</code> the <code>OutputStream</code> returned from
- * <code>openOutputStream()</code> or <code>openDataOutputStream()</code> will
- * signal that the request is done. (In OBEX terms, the End-Of-Body header
- * should be sent and the final bit in the request will be set.) At this point,
- * the reply from the server may begin to be processed. A call to
- * <code>getResponseCode()</code> will do an implicit close on the
- * <code>OutputStream</code> and therefore signal that the request is done.
- * <H3>Client GET Operation Flow</H3> For GET operation, a call to
- * <code>openInputStream()</code> or <code>openDataInputStream()</code> will
- * signal that the request is done. (In OBEX terms, the final bit in the request
- * will be set.) A call to <code>getResponseCode()</code> will cause an implicit
- * close on the <code>InputStream</code>. No further data may be read at this
- * point.
- * @hide
- */
-public interface Operation {
-
-    /**
-     * Sends an ABORT message to the server. By calling this method, the
-     * corresponding input and output streams will be closed along with this
-     * object. No headers are sent in the abort request. This will end the
-     * operation since <code>close()</code> will be called by this method.
-     * @throws IOException if the transaction has already ended or if an OBEX
-     *         server calls this method
-     */
-    void abort() throws IOException;
-
-    /**
-     * Returns the headers that have been received during the operation.
-     * Modifying the object returned has no effect on the headers that are sent
-     * or retrieved.
-     * @return the headers received during this <code>Operation</code>
-     * @throws IOException if this <code>Operation</code> has been closed
-     */
-    HeaderSet getReceivedHeader() throws IOException;
-
-    /**
-     * Specifies the headers that should be sent in the next OBEX message that
-     * is sent.
-     * @param headers the headers to send in the next message
-     * @throws IOException if this <code>Operation</code> has been closed or the
-     *         transaction has ended and no further messages will be exchanged
-     * @throws IllegalArgumentException if <code>headers</code> was not created
-     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
-     *         or <code>ClientSession.createHeaderSet()</code>
-     * @throws NullPointerException if <code>headers</code> if <code>null</code>
-     */
-    void sendHeaders(HeaderSet headers) throws IOException;
-
-    /**
-     * Returns the response code received from the server. Response codes are
-     * defined in the <code>ResponseCodes</code> class.
-     * @see ResponseCodes
-     * @return the response code retrieved from the server
-     * @throws IOException if an error occurred in the transport layer during
-     *         the transaction; if this object was created by an OBEX server
-     */
-    int getResponseCode() throws IOException;
-
-    String getEncoding();
-
-    long getLength();
-
-    int getHeaderLength();
-
-    String getType();
-
-    InputStream openInputStream() throws IOException;
-
-    DataInputStream openDataInputStream() throws IOException;
-
-    OutputStream openOutputStream() throws IOException;
-
-    DataOutputStream openDataOutputStream() throws IOException;
-
-    void close() throws IOException;
-
-    int getMaxPacketSize();
-
-    public void noBodyHeader();
-}
diff --git a/obex/javax/obex/PasswordAuthentication.java b/obex/javax/obex/PasswordAuthentication.java
deleted file mode 100644
index 326b1ff..0000000
--- a/obex/javax/obex/PasswordAuthentication.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-/**
- * This class holds user name and password combinations.
- * @hide
- */
-public final class PasswordAuthentication {
-
-    private byte[] mUserName;
-
-    private final byte[] mPassword;
-
-    /**
-     * Creates a new <code>PasswordAuthentication</code> with the user name and
-     * password provided.
-     * @param userName the user name to include; this may be <code>null</code>
-     * @param password the password to include in the response
-     * @throws NullPointerException if <code>password</code> is
-     *         <code>null</code>
-     */
-    public PasswordAuthentication(final byte[] userName, final byte[] password) {
-        if (userName != null) {
-            mUserName = new byte[userName.length];
-            System.arraycopy(userName, 0, mUserName, 0, userName.length);
-        }
-
-        mPassword = new byte[password.length];
-        System.arraycopy(password, 0, mPassword, 0, password.length);
-    }
-
-    /**
-     * Retrieves the user name that was specified in the constructor. The user
-     * name may be <code>null</code>.
-     * @return the user name
-     */
-    public byte[] getUserName() {
-        return mUserName;
-    }
-
-    /**
-     * Retrieves the password.
-     * @return the password
-     */
-    public byte[] getPassword() {
-        return mPassword;
-    }
-}
diff --git a/obex/javax/obex/PrivateInputStream.java b/obex/javax/obex/PrivateInputStream.java
deleted file mode 100644
index 5daee72..0000000
--- a/obex/javax/obex/PrivateInputStream.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.InputStream;
-import java.io.IOException;
-
-/**
- * This object provides an input stream to the Operation objects used in this
- * package.
- * @hide
- */
-public final class PrivateInputStream extends InputStream {
-
-    private BaseStream mParent;
-
-    private byte[] mData;
-
-    private int mIndex;
-
-    private boolean mOpen;
-
-    /**
-     * Creates an input stream for the <code>Operation</code> to read from
-     * @param p the connection this input stream is for
-     */
-    public PrivateInputStream(BaseStream p) {
-        mParent = p;
-        mData = new byte[0];
-        mIndex = 0;
-        mOpen = true;
-    }
-
-    /**
-     * Returns the number of bytes that can be read (or skipped over) from this
-     * input stream without blocking by the next caller of a method for this
-     * input stream. The next caller might be the same thread or or another
-     * thread.
-     * @return the number of bytes that can be read from this input stream
-     *         without blocking
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public synchronized int available() throws IOException {
-        ensureOpen();
-        return mData.length - mIndex;
-    }
-
-    /**
-     * Reads the next byte of data from the input stream. The value byte is
-     * returned as an int in the range 0 to 255. If no byte is available because
-     * the end of the stream has been reached, the value -1 is returned. This
-     * method blocks until input data is available, the end of the stream is
-     * detected, or an exception is thrown.
-     * @return the byte read from the input stream or -1 if it reaches the end of
-     *         stream
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public synchronized int read() throws IOException {
-        ensureOpen();
-        while (mData.length == mIndex) {
-            if (!mParent.continueOperation(true, true)) {
-                return -1;
-            }
-        }
-        return (mData[mIndex++] & 0xFF);
-    }
-
-    @Override
-    public int read(byte[] b) throws IOException {
-        return read(b, 0, b.length);
-    }
-
-    @Override
-    public synchronized int read(byte[] b, int offset, int length) throws IOException {
-
-        if (b == null) {
-            throw new IOException("buffer is null");
-        }
-        if ((offset | length) < 0 || length > b.length - offset) {
-            throw new ArrayIndexOutOfBoundsException("index outof bound");
-        }
-        ensureOpen();
-
-        int currentDataLength = mData.length - mIndex;
-        int remainReadLength = length;
-        int offset1 = offset;
-        int result = 0;
-
-        while (currentDataLength <= remainReadLength) {
-            System.arraycopy(mData, mIndex, b, offset1, currentDataLength);
-            mIndex += currentDataLength;
-            offset1 += currentDataLength;
-            result += currentDataLength;
-            remainReadLength -= currentDataLength;
-
-            if (!mParent.continueOperation(true, true)) {
-                return result == 0 ? -1 : result;
-            }
-            currentDataLength = mData.length - mIndex;
-        }
-        if (remainReadLength > 0) {
-            System.arraycopy(mData, mIndex, b, offset1, remainReadLength);
-            mIndex += remainReadLength;
-            result += remainReadLength;
-        }
-        return result;
-    }
-
-    /**
-     * Allows the <code>OperationImpl</code> thread to add body data to the
-     * input stream.
-     * @param body the data to add to the stream
-     * @param start the start of the body to array to copy
-     */
-    public synchronized void writeBytes(byte[] body, int start) {
-
-        int length = (body.length - start) + (mData.length - mIndex);
-        byte[] temp = new byte[length];
-
-        System.arraycopy(mData, mIndex, temp, 0, mData.length - mIndex);
-        System.arraycopy(body, start, temp, mData.length - mIndex, body.length - start);
-
-        mData = temp;
-        mIndex = 0;
-        notifyAll();
-    }
-
-    /**
-     * Verifies that this stream is open
-     * @throws IOException if the stream is not open
-     */
-    private void ensureOpen() throws IOException {
-        mParent.ensureOpen();
-        if (!mOpen) {
-            throw new IOException("Input stream is closed");
-        }
-    }
-
-    /**
-     * Closes the input stream. If the input stream is already closed, do
-     * nothing.
-     * @throws IOException this will never happen
-     */
-    @Override
-    public void close() throws IOException {
-        mOpen = false;
-        mParent.streamClosed(true);
-    }
-}
diff --git a/obex/javax/obex/PrivateOutputStream.java b/obex/javax/obex/PrivateOutputStream.java
deleted file mode 100644
index 713f4ae..0000000
--- a/obex/javax/obex/PrivateOutputStream.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.ByteArrayOutputStream;
-
-/**
- * This object provides an output stream to the Operation objects used in this
- * package.
- * @hide
- */
-public final class PrivateOutputStream extends OutputStream {
-
-    private BaseStream mParent;
-
-    private ByteArrayOutputStream mArray;
-
-    private boolean mOpen;
-
-    private int mMaxPacketSize;
-
-    /**
-     * Creates an empty <code>PrivateOutputStream</code> to write to.
-     * @param p the connection that this stream runs over
-     */
-    public PrivateOutputStream(BaseStream p, int maxSize) {
-        mParent = p;
-        mArray = new ByteArrayOutputStream();
-        mMaxPacketSize = maxSize;
-        mOpen = true;
-    }
-
-    /**
-     * Determines how many bytes have been written to the output stream.
-     * @return the number of bytes written to the output stream
-     */
-    public int size() {
-        return mArray.size();
-    }
-
-    /**
-     * Writes the specified byte to this output stream. The general contract for
-     * write is that one byte is written to the output stream. The byte to be
-     * written is the eight low-order bits of the argument b. The 24 high-order
-     * bits of b are ignored.
-     * @param b the byte to write
-     * @throws IOException if an I/O error occurs
-     */
-    @Override
-    public synchronized void write(int b) throws IOException {
-        ensureOpen();
-        mParent.ensureNotDone();
-        mArray.write(b);
-        if (mArray.size() == mMaxPacketSize) {
-            mParent.continueOperation(true, false);
-        }
-    }
-
-    @Override
-    public void write(byte[] buffer) throws IOException {
-        write(buffer, 0, buffer.length);
-    }
-
-    @Override
-    public synchronized void write(byte[] buffer, int offset, int count) throws IOException {
-        int offset1 = offset;
-        int remainLength = count;
-
-        if (buffer == null) {
-            throw new IOException("buffer is null");
-        }
-        if ((offset | count) < 0 || count > buffer.length - offset) {
-            throw new IndexOutOfBoundsException("index outof bound");
-        }
-
-        ensureOpen();
-        mParent.ensureNotDone();
-        while ((mArray.size() + remainLength) >= mMaxPacketSize) {
-            int bufferLeft = mMaxPacketSize - mArray.size();
-            mArray.write(buffer, offset1, bufferLeft);
-            offset1 += bufferLeft;
-            remainLength -= bufferLeft;
-            mParent.continueOperation(true, false);
-        }
-        if (remainLength > 0) {
-            mArray.write(buffer, offset1, remainLength);
-        }
-    }
-
-    /**
-     * Reads the bytes that have been written to this stream.
-     * @param size the size of the array to return
-     * @return the byte array that is written
-     */
-    public synchronized byte[] readBytes(int size) {
-        if (mArray.size() > 0) {
-            byte[] temp = mArray.toByteArray();
-            mArray.reset();
-            byte[] result = new byte[size];
-            System.arraycopy(temp, 0, result, 0, size);
-            if (temp.length != size) {
-                mArray.write(temp, size, temp.length - size);
-            }
-            return result;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Verifies that this stream is open
-     * @throws IOException if the stream is not open
-     */
-    private void ensureOpen() throws IOException {
-        mParent.ensureOpen();
-        if (!mOpen) {
-            throw new IOException("Output stream is closed");
-        }
-    }
-
-    /**
-     * Closes the output stream. If the input stream is already closed, do
-     * nothing.
-     * @throws IOException this will never happen
-     */
-    @Override
-    public void close() throws IOException {
-        mOpen = false;
-        mParent.streamClosed(false);
-    }
-
-    /**
-     * Determines if the connection is closed
-     * @return <code>true</code> if the connection is closed; <code>false</code>
-     *         if the connection is open
-     */
-    public boolean isClosed() {
-        return !mOpen;
-    }
-}
diff --git a/obex/javax/obex/ResponseCodes.java b/obex/javax/obex/ResponseCodes.java
deleted file mode 100644
index a2b9a37..0000000
--- a/obex/javax/obex/ResponseCodes.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-/**
- * The <code>ResponseCodes</code> class contains the list of valid response
- * codes a server may send to a client.
- * <P>
- * <STRONG>IMPORTANT NOTE</STRONG>
- * <P>
- * The values in this interface represent the values defined in the IrOBEX
- * specification, which is different with the HTTP specification.
- * <P>
- * <code>OBEX_DATABASE_FULL</code> and <code>OBEX_DATABASE_LOCKED</code> require
- * further description since they are not defined in HTTP. The server will send
- * an <code>OBEX_DATABASE_FULL</code> message when the client requests that
- * something be placed into a database but the database is full (cannot take
- * more data). <code>OBEX_DATABASE_LOCKED</code> will be returned when the
- * client wishes to access a database, database table, or database record that
- * has been locked.
- * @hide
- */
-public final class ResponseCodes {
-
-    /**
-     * Defines the OBEX CONTINUE response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_CONTINUE</code> is 0x90 (144).
-     */
-    public static final int OBEX_HTTP_CONTINUE = 0x90;
-
-    /**
-     * Defines the OBEX SUCCESS response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_OK</code> is 0xA0 (160).
-     */
-    public static final int OBEX_HTTP_OK = 0xA0;
-
-    /**
-     * Defines the OBEX CREATED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_CREATED</code> is 0xA1 (161).
-     */
-    public static final int OBEX_HTTP_CREATED = 0xA1;
-
-    /**
-     * Defines the OBEX ACCEPTED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_ACCEPTED</code> is 0xA2 (162).
-     */
-    public static final int OBEX_HTTP_ACCEPTED = 0xA2;
-
-    /**
-     * Defines the OBEX NON-AUTHORITATIVE INFORMATION response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_NOT_AUTHORITATIVE</code> is 0xA3 (163).
-     */
-    public static final int OBEX_HTTP_NOT_AUTHORITATIVE = 0xA3;
-
-    /**
-     * Defines the OBEX NO CONTENT response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_NO_CONTENT</code> is 0xA4 (164).
-     */
-    public static final int OBEX_HTTP_NO_CONTENT = 0xA4;
-
-    /**
-     * Defines the OBEX RESET CONTENT response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_RESET</code> is 0xA5 (165).
-     */
-    public static final int OBEX_HTTP_RESET = 0xA5;
-
-    /**
-     * Defines the OBEX PARTIAL CONTENT response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_PARTIAL</code> is 0xA6 (166).
-     */
-    public static final int OBEX_HTTP_PARTIAL = 0xA6;
-
-    /**
-     * Defines the OBEX MULTIPLE_CHOICES response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_MULT_CHOICE</code> is 0xB0 (176).
-     */
-    public static final int OBEX_HTTP_MULT_CHOICE = 0xB0;
-
-    /**
-     * Defines the OBEX MOVED PERMANENTLY response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_MOVED_PERM</code> is 0xB1 (177).
-     */
-    public static final int OBEX_HTTP_MOVED_PERM = 0xB1;
-
-    /**
-     * Defines the OBEX MOVED TEMPORARILY response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_MOVED_TEMP</code> is 0xB2 (178).
-     */
-    public static final int OBEX_HTTP_MOVED_TEMP = 0xB2;
-
-    /**
-     * Defines the OBEX SEE OTHER response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_SEE_OTHER</code> is 0xB3 (179).
-     */
-    public static final int OBEX_HTTP_SEE_OTHER = 0xB3;
-
-    /**
-     * Defines the OBEX NOT MODIFIED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_NOT_MODIFIED</code> is 0xB4 (180).
-     */
-    public static final int OBEX_HTTP_NOT_MODIFIED = 0xB4;
-
-    /**
-     * Defines the OBEX USE PROXY response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_USE_PROXY</code> is 0xB5 (181).
-     */
-    public static final int OBEX_HTTP_USE_PROXY = 0xB5;
-
-    /**
-     * Defines the OBEX BAD REQUEST response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_BAD_REQUEST</code> is 0xC0 (192).
-     */
-    public static final int OBEX_HTTP_BAD_REQUEST = 0xC0;
-
-    /**
-     * Defines the OBEX UNAUTHORIZED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_UNAUTHORIZED</code> is 0xC1 (193).
-     */
-    public static final int OBEX_HTTP_UNAUTHORIZED = 0xC1;
-
-    /**
-     * Defines the OBEX PAYMENT REQUIRED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_PAYMENT_REQUIRED</code> is 0xC2 (194).
-     */
-    public static final int OBEX_HTTP_PAYMENT_REQUIRED = 0xC2;
-
-    /**
-     * Defines the OBEX FORBIDDEN response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_FORBIDDEN</code> is 0xC3 (195).
-     */
-    public static final int OBEX_HTTP_FORBIDDEN = 0xC3;
-
-    /**
-     * Defines the OBEX NOT FOUND response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_NOT_FOUND</code> is 0xC4 (196).
-     */
-    public static final int OBEX_HTTP_NOT_FOUND = 0xC4;
-
-    /**
-     * Defines the OBEX METHOD NOT ALLOWED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_BAD_METHOD</code> is 0xC5 (197).
-     */
-    public static final int OBEX_HTTP_BAD_METHOD = 0xC5;
-
-    /**
-     * Defines the OBEX NOT ACCEPTABLE response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_NOT_ACCEPTABLE</code> is 0xC6 (198).
-     */
-    public static final int OBEX_HTTP_NOT_ACCEPTABLE = 0xC6;
-
-    /**
-     * Defines the OBEX PROXY AUTHENTICATION REQUIRED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_PROXY_AUTH</code> is 0xC7 (199).
-     */
-    public static final int OBEX_HTTP_PROXY_AUTH = 0xC7;
-
-    /**
-     * Defines the OBEX REQUEST TIME OUT response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_TIMEOUT</code> is 0xC8 (200).
-     */
-    public static final int OBEX_HTTP_TIMEOUT = 0xC8;
-
-    /**
-     * Defines the OBEX METHOD CONFLICT response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_CONFLICT</code> is 0xC9 (201).
-     */
-    public static final int OBEX_HTTP_CONFLICT = 0xC9;
-
-    /**
-     * Defines the OBEX METHOD GONE response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_GONE</code> is 0xCA (202).
-     */
-    public static final int OBEX_HTTP_GONE = 0xCA;
-
-    /**
-     * Defines the OBEX METHOD LENGTH REQUIRED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_LENGTH_REQUIRED</code> is 0xCB (203).
-     */
-    public static final int OBEX_HTTP_LENGTH_REQUIRED = 0xCB;
-
-    /**
-     * Defines the OBEX PRECONDITION FAILED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_PRECON_FAILED</code> is 0xCC (204).
-     */
-    public static final int OBEX_HTTP_PRECON_FAILED = 0xCC;
-
-    /**
-     * Defines the OBEX REQUESTED ENTITY TOO LARGE response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_ENTITY_TOO_LARGE</code> is 0xCD (205).
-     */
-    public static final int OBEX_HTTP_ENTITY_TOO_LARGE = 0xCD;
-
-    /**
-     * Defines the OBEX REQUESTED URL TOO LARGE response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_REQ_TOO_LARGE</code> is 0xCE (206).
-     */
-    public static final int OBEX_HTTP_REQ_TOO_LARGE = 0xCE;
-
-    /**
-     * Defines the OBEX UNSUPPORTED MEDIA TYPE response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_UNSUPPORTED_TYPE</code> is 0xCF (207).
-     */
-    public static final int OBEX_HTTP_UNSUPPORTED_TYPE = 0xCF;
-
-    /**
-     * Defines the OBEX INTERNAL SERVER ERROR response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_INTERNAL_ERROR</code> is 0xD0 (208).
-     */
-    public static final int OBEX_HTTP_INTERNAL_ERROR = 0xD0;
-
-    /**
-     * Defines the OBEX NOT IMPLEMENTED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_NOT_IMPLEMENTED</code> is 0xD1 (209).
-     */
-    public static final int OBEX_HTTP_NOT_IMPLEMENTED = 0xD1;
-
-    /**
-     * Defines the OBEX BAD GATEWAY response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_BAD_GATEWAY</code> is 0xD2 (210).
-     */
-    public static final int OBEX_HTTP_BAD_GATEWAY = 0xD2;
-
-    /**
-     * Defines the OBEX SERVICE UNAVAILABLE response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_UNAVAILABLE</code> is 0xD3 (211).
-     */
-    public static final int OBEX_HTTP_UNAVAILABLE = 0xD3;
-
-    /**
-     * Defines the OBEX GATEWAY TIMEOUT response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_GATEWAY_TIMEOUT</code> is 0xD4 (212).
-     */
-    public static final int OBEX_HTTP_GATEWAY_TIMEOUT = 0xD4;
-
-    /**
-     * Defines the OBEX HTTP VERSION NOT SUPPORTED response code.
-     * <P>
-     * The value of <code>OBEX_HTTP_VERSION</code> is 0xD5 (213).
-     */
-    public static final int OBEX_HTTP_VERSION = 0xD5;
-
-    /**
-     * Defines the OBEX DATABASE FULL response code.
-     * <P>
-     * The value of <code>OBEX_DATABASE_FULL</code> is 0xE0 (224).
-     */
-    public static final int OBEX_DATABASE_FULL = 0xE0;
-
-    /**
-     * Defines the OBEX DATABASE LOCKED response code.
-     * <P>
-     * The value of <code>OBEX_DATABASE_LOCKED</code> is 0xE1 (225).
-     */
-    public static final int OBEX_DATABASE_LOCKED = 0xE1;
-
-    /**
-     * Constructor does nothing.
-     */
-    private ResponseCodes() {
-    }
-}
diff --git a/obex/javax/obex/ServerOperation.java b/obex/javax/obex/ServerOperation.java
deleted file mode 100644
index 15ea367..0000000
--- a/obex/javax/obex/ServerOperation.java
+++ /dev/null
@@ -1,861 +0,0 @@
-/* Copyright (c) 2015 The Android Open Source Project
- * Copyright (C) 2015 Samsung LSI
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.DataInputStream;
-import java.io.OutputStream;
-import java.io.DataOutputStream;
-import java.io.ByteArrayOutputStream;
-
-import android.util.Log;
-
-/**
- * This class implements the Operation interface for server side connections.
- * <P>
- * <STRONG>Request Codes</STRONG> There are four different request codes that
- * are in this class. 0x02 is a PUT request that signals that the request is not
- * complete and requires an additional OBEX packet. 0x82 is a PUT request that
- * says that request is complete. In this case, the server can begin sending the
- * response. The 0x03 is a GET request that signals that the request is not
- * finished. When the server receives a 0x83, the client is signaling the server
- * that it is done with its request. TODO: Extend the ClientOperation and reuse
- * the methods defined TODO: in that class.
- * @hide
- */
-public final class ServerOperation implements Operation, BaseStream {
-
-    private static final String TAG = "ServerOperation";
-
-    private static final boolean V = ObexHelper.VDBG; // Verbose debugging
-
-    public boolean isAborted;
-
-    public HeaderSet requestHeader;
-
-    public HeaderSet replyHeader;
-
-    public boolean finalBitSet;
-
-    private InputStream mInput;
-
-    private ServerSession mParent;
-
-    private int mMaxPacketLength;
-
-    private int mResponseSize;
-
-    private boolean mClosed;
-
-    private boolean mGetOperation;
-
-    private PrivateInputStream mPrivateInput;
-
-    private PrivateOutputStream mPrivateOutput;
-
-    private ObexTransport mTransport;
-
-    private boolean mPrivateOutputOpen;
-
-    private String mExceptionString;
-
-    private ServerRequestHandler mListener;
-
-    private boolean mRequestFinished;
-
-    private boolean mHasBody;
-
-    private boolean mSendBodyHeader = true;
-    // Assume SRM disabled - needs to be explicit
-    // enabled by client
-    private boolean mSrmEnabled = false;
-    // A latch - when triggered, there is not way back ;-)
-    private boolean mSrmActive = false;
-    // Set to true when a SRM enable response have been send
-    private boolean mSrmResponseSent = false;
-    // keep waiting until final-bit is received in request
-    // to handle the case where the SRM enable header is in
-    // a different OBEX packet than the SRMP header.
-    private boolean mSrmWaitingForRemote = true;
-    // Why should we wait? - currently not exposed to apps.
-    private boolean mSrmLocalWait = false;
-
-    /**
-     * Creates new ServerOperation
-     * @param p the parent that created this object
-     * @param in the input stream to read from
-     * @param out the output stream to write to
-     * @param request the initial request that was received from the client
-     * @param maxSize the max packet size that the client will accept
-     * @param listen the listener that is responding to the request
-     * @throws IOException if an IO error occurs
-     */
-    public ServerOperation(ServerSession p, InputStream in, int request, int maxSize,
-            ServerRequestHandler listen) throws IOException {
-
-        isAborted = false;
-        mParent = p;
-        mInput = in;
-        mMaxPacketLength = maxSize;
-        mClosed = false;
-        requestHeader = new HeaderSet();
-        replyHeader = new HeaderSet();
-        mPrivateInput = new PrivateInputStream(this);
-        mResponseSize = 3;
-        mListener = listen;
-        mRequestFinished = false;
-        mPrivateOutputOpen = false;
-        mHasBody = false;
-        ObexPacket packet;
-        mTransport = p.getTransport();
-
-        /*
-         * Determine if this is a PUT request
-         */
-        if ((request == ObexHelper.OBEX_OPCODE_PUT) ||
-                (request == ObexHelper.OBEX_OPCODE_PUT_FINAL)) {
-            /*
-             * It is a PUT request.
-             */
-            mGetOperation = false;
-
-            /*
-             * Determine if the final bit is set
-             */
-            if ((request & ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK) == 0) {
-                finalBitSet = false;
-            } else {
-                finalBitSet = true;
-                mRequestFinished = true;
-            }
-        } else if ((request == ObexHelper.OBEX_OPCODE_GET) ||
-                (request == ObexHelper.OBEX_OPCODE_GET_FINAL)) {
-            /*
-             * It is a GET request.
-             */
-            mGetOperation = true;
-
-            // For Get request, final bit set is decided by server side logic
-            finalBitSet = false;
-
-            if (request == ObexHelper.OBEX_OPCODE_GET_FINAL) {
-                mRequestFinished = true;
-            }
-        } else {
-            throw new IOException("ServerOperation can not handle such request");
-        }
-
-        packet = ObexPacket.read(request, mInput);
-
-        /*
-         * Determine if the packet length is larger than this device can receive
-         */
-        if (packet.mLength > ObexHelper.getMaxRxPacketSize(mTransport)) {
-            mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null);
-            throw new IOException("Packet received was too large. Length: "
-                    + packet.mLength + " maxLength: " + ObexHelper.getMaxRxPacketSize(mTransport));
-        }
-
-        /*
-         * Determine if any headers were sent in the initial request
-         */
-        if (packet.mLength > 3) {
-            if(!handleObexPacket(packet)) {
-                return;
-            }
-            /* Don't Pre-Send continue when Remote requested for SRM
-             * Let the Application confirm.
-             */
-            if (V) Log.v(TAG, "Get App confirmation if SRM ENABLED case: " + mSrmEnabled
-                    + " not hasBody case: " + mHasBody);
-            if (!mHasBody && !mSrmEnabled) {
-                while ((!mGetOperation) && (!finalBitSet)) {
-                    sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
-                    if (mPrivateInput.available() > 0) {
-                        break;
-                    }
-                }
-            }
-        }
-        /* Don't Pre-Send continue when Remote requested for SRM
-          * Let the Application confirm.
-          */
-        if (V) Log.v(TAG, "Get App confirmation if SRM ENABLED case: " + mSrmEnabled
-            + " not finalPacket: " + finalBitSet + " not GETOp Case: " + mGetOperation);
-        while ((!mSrmEnabled) && (!mGetOperation) && (!finalBitSet)
-                && (mPrivateInput.available() == 0)) {
-            sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
-            if (mPrivateInput.available() > 0) {
-                break;
-            }
-        }
-
-        // wait for get request finished !!!!
-        while (mGetOperation && !mRequestFinished) {
-            sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
-        }
-    }
-
-    /**
-     * Parse headers and update member variables
-     * @param packet the received obex packet
-     * @return false for failing authentication - and a OBEX_HTTP_UNAUTHORIZED
-     * response have been send. Else true.
-     * @throws IOException
-     */
-    private boolean handleObexPacket(ObexPacket packet) throws IOException {
-        byte[] body = updateRequestHeaders(packet);
-
-        if (body != null) {
-            mHasBody = true;
-        }
-        if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) {
-            mListener.setConnectionId(ObexHelper
-                    .convertToLong(requestHeader.mConnectionID));
-        } else {
-            mListener.setConnectionId(1);
-        }
-
-        if (requestHeader.mAuthResp != null) {
-            if (!mParent.handleAuthResp(requestHeader.mAuthResp)) {
-                mExceptionString = "Authentication Failed";
-                mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null);
-                mClosed = true;
-                requestHeader.mAuthResp = null;
-                return false;
-            }
-            requestHeader.mAuthResp = null;
-        }
-
-        if (requestHeader.mAuthChall != null) {
-            mParent.handleAuthChall(requestHeader);
-            // send the auhtResp to the client
-            replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length];
-            System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0,
-                    replyHeader.mAuthResp.length);
-            requestHeader.mAuthResp = null;
-            requestHeader.mAuthChall = null;
-        }
-
-        if (body != null) {
-            mPrivateInput.writeBytes(body, 1);
-        }
-        return true;
-    }
-
-    /**
-     * Update the request header set, and sniff on SRM headers to update local state.
-     * @param data the OBEX packet data
-     * @return any bytes in a body/end-of-body header returned by {@link ObexHelper.updateHeaderSet}
-     * @throws IOException
-     */
-    private byte[] updateRequestHeaders(ObexPacket packet) throws IOException {
-        byte[] body = null;
-        if (packet.mPayload != null) {
-            body = ObexHelper.updateHeaderSet(requestHeader, packet.mPayload);
-        }
-        Byte srmMode = (Byte)requestHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
-        if(mTransport.isSrmSupported() && srmMode != null
-                && srmMode == ObexHelper.OBEX_SRM_ENABLE) {
-            mSrmEnabled = true;
-            if(V) Log.d(TAG,"SRM is now ENABLED (but not active) for this operation");
-        }
-        checkForSrmWait(packet.mHeaderId);
-        if((!mSrmWaitingForRemote) && (mSrmEnabled)) {
-            if(V) Log.d(TAG,"SRM is now ACTIVE for this operation");
-            mSrmActive = true;
-        }
-        return body;
-    }
-
-    /**
-     * Call this only when a complete request have been received.
-     * (This is not optimal, but the current design is not really suited to
-     * the way SRM is specified.)
-     */
-    private void checkForSrmWait(int headerId){
-        if (mSrmEnabled && (headerId == ObexHelper.OBEX_OPCODE_GET
-                || headerId == ObexHelper.OBEX_OPCODE_GET_FINAL
-                || headerId == ObexHelper.OBEX_OPCODE_PUT)) {
-            try {
-                mSrmWaitingForRemote = false;
-                Byte srmp = (Byte)requestHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
-                if(srmp != null && srmp == ObexHelper.OBEX_SRMP_WAIT) {
-                    mSrmWaitingForRemote = true;
-                    // Clear the wait header, as the absents of the header when the final bit is set
-                    // indicates don't wait.
-                    requestHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
-                }
-            } catch (IOException e) {if(V){Log.w(TAG,"Exception while extracting header",e);}}
-        }
-    }
-
-    public boolean isValidBody() {
-        return mHasBody;
-    }
-
-    /**
-     * Determines if the operation should continue or should wait. If it should
-     * continue, this method will continue the operation.
-     * @param sendEmpty if <code>true</code> then this will continue the
-     *        operation even if no headers will be sent; if <code>false</code>
-     *        then this method will only continue the operation if there are
-     *        headers to send
-     * @param inStream if<code>true</code> the stream is input stream, otherwise
-     *        output stream
-     * @return <code>true</code> if the operation was completed;
-     *         <code>false</code> if no operation took place
-     */
-    public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
-            throws IOException {
-        if (!mGetOperation) {
-            if (!finalBitSet) {
-                if (sendEmpty) {
-                    sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
-                    return true;
-                } else {
-                    if ((mResponseSize > 3) || (mPrivateOutput.size() > 0)) {
-                        sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
-                        return true;
-                    } else {
-                        return false;
-                    }
-                }
-            } else {
-                return false;
-            }
-        } else {
-            sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
-            return true;
-        }
-    }
-
-    /**
-     * Sends a reply to the client. If the reply is a OBEX_HTTP_CONTINUE, it
-     * will wait for a response from the client before ending unless SRM is active.
-     * @param type the response code to send back to the client
-     * @return <code>true</code> if the final bit was not set on the reply;
-     *         <code>false</code> if no reply was received because the operation
-     *         ended, an abort was received, the final bit was set in the
-     *         reply or SRM is active.
-     * @throws IOException if an IO error occurs
-     */
-    public synchronized boolean sendReply(int type) throws IOException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        boolean skipSend = false;
-        boolean skipReceive = false;
-        boolean srmRespSendPending = false;
-
-        long id = mListener.getConnectionId();
-        if (id == -1) {
-            replyHeader.mConnectionID = null;
-        } else {
-            replyHeader.mConnectionID = ObexHelper.convertToByteArray(id);
-        }
-
-        if(mSrmEnabled && !mSrmResponseSent) {
-            // As we are not ensured that the SRM enable is in the first OBEX packet
-            // We must check for each reply.
-            if(V)Log.v(TAG, "mSrmEnabled==true, sending SRM enable response.");
-            replyHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, (byte)ObexHelper.OBEX_SRM_ENABLE);
-            srmRespSendPending = true;
-        }
-
-        if(mSrmEnabled && !mGetOperation && mSrmLocalWait) {
-            replyHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, (byte)ObexHelper.OBEX_SRMP_WAIT);
-        }
-
-        byte[] headerArray = ObexHelper.createHeader(replyHeader, true); // This clears the headers
-        int bodyLength = -1;
-        int orginalBodyLength = -1;
-
-        if (mPrivateOutput != null) {
-            bodyLength = mPrivateOutput.size();
-            orginalBodyLength = bodyLength;
-        }
-
-        if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketLength) {
-
-            int end = 0;
-            int start = 0;
-
-            while (end != headerArray.length) {
-                end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketLength
-                        - ObexHelper.BASE_PACKET_LENGTH);
-                if (end == -1) {
-
-                    mClosed = true;
-
-                    if (mPrivateInput != null) {
-                        mPrivateInput.close();
-                    }
-
-                    if (mPrivateOutput != null) {
-                        mPrivateOutput.close();
-                    }
-                    mParent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
-                    throw new IOException("OBEX Packet exceeds max packet size");
-                }
-                byte[] sendHeader = new byte[end - start];
-                System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length);
-
-                mParent.sendResponse(type, sendHeader);
-                start = end;
-            }
-
-            if (bodyLength > 0) {
-                return true;
-            } else {
-                return false;
-            }
-
-        } else {
-            out.write(headerArray);
-        }
-
-        // For Get operation: if response code is OBEX_HTTP_OK, then this is the
-        // last packet; so set finalBitSet to true.
-        if (mGetOperation && type == ResponseCodes.OBEX_HTTP_OK) {
-            finalBitSet = true;
-        }
-
-        if(mSrmActive) {
-            if(!mGetOperation && type == ResponseCodes.OBEX_HTTP_CONTINUE &&
-                    mSrmResponseSent == true) {
-                // we are in the middle of a SRM PUT operation, don't send a continue.
-                skipSend = true;
-            } else if(mGetOperation && mRequestFinished == false && mSrmResponseSent == true) {
-                // We are still receiving the get request, receive, but don't send continue.
-                skipSend = true;
-            } else if(mGetOperation && mRequestFinished == true) {
-                // All done receiving the GET request, send data to the client, without
-                // expecting a continue.
-                skipReceive = true;
-            }
-            if(V)Log.v(TAG, "type==" + type + " skipSend==" + skipSend
-                    + " skipReceive==" + skipReceive);
-        }
-        if(srmRespSendPending) {
-            if(V)Log.v(TAG,
-                    "SRM Enabled (srmRespSendPending == true)- sending SRM Enable response");
-            mSrmResponseSent = true;
-        }
-
-        if ((finalBitSet) || (headerArray.length < (mMaxPacketLength - 20))) {
-            if (bodyLength > 0) {
-                /*
-                 * Determine if I can send the whole body or just part of
-                 * the body.  Remember that there is the 3 bytes for the
-                 * response message and 3 bytes for the header ID and length
-                 */
-                if (bodyLength > (mMaxPacketLength - headerArray.length - 6)) {
-                    bodyLength = mMaxPacketLength - headerArray.length - 6;
-                }
-
-                byte[] body = mPrivateOutput.readBytes(bodyLength);
-
-                /*
-                 * Since this is a put request if the final bit is set or
-                 * the output stream is closed we need to send the 0x49
-                 * (End of Body) otherwise, we need to send 0x48 (Body)
-                 */
-                if ((finalBitSet) || (mPrivateOutput.isClosed())) {
-                    if(mSendBodyHeader == true) {
-                        out.write(0x49);
-                        bodyLength += 3;
-                        out.write((byte)(bodyLength >> 8));
-                        out.write((byte)bodyLength);
-                        out.write(body);
-                    }
-                } else {
-                    if(mSendBodyHeader == true) {
-                    out.write(0x48);
-                    bodyLength += 3;
-                    out.write((byte)(bodyLength >> 8));
-                    out.write((byte)bodyLength);
-                    out.write(body);
-                    }
-                }
-
-            }
-        }
-
-        if ((finalBitSet) && (type == ResponseCodes.OBEX_HTTP_OK) && (orginalBodyLength <= 0)) {
-            if(mSendBodyHeader) {
-                out.write(0x49);
-                orginalBodyLength = 3;
-                out.write((byte)(orginalBodyLength >> 8));
-                out.write((byte)orginalBodyLength);
-            }
-        }
-
-        if(skipSend == false) {
-            mResponseSize = 3;
-            mParent.sendResponse(type, out.toByteArray());
-        }
-
-        if (type == ResponseCodes.OBEX_HTTP_CONTINUE) {
-
-            if(mGetOperation && skipReceive) {
-                // Here we need to check for and handle abort (throw an exception).
-                // Any other signal received should be discarded silently (only on server side)
-                checkSrmRemoteAbort();
-            } else {
-                // Receive and handle data (only send reply if !skipSend)
-                // Read a complete OBEX Packet
-                ObexPacket packet = ObexPacket.read(mInput);
-
-                int headerId = packet.mHeaderId;
-                if ((headerId != ObexHelper.OBEX_OPCODE_PUT)
-                        && (headerId != ObexHelper.OBEX_OPCODE_PUT_FINAL)
-                        && (headerId != ObexHelper.OBEX_OPCODE_GET)
-                        && (headerId != ObexHelper.OBEX_OPCODE_GET_FINAL)) {
-
-                    /*
-                     * Determine if an ABORT was sent as the reply
-                     */
-                    if (headerId == ObexHelper.OBEX_OPCODE_ABORT) {
-                        handleRemoteAbort();
-                    } else {
-                        // TODO:shall we send this if it occurs during SRM? Errata on the subject
-                        mParent.sendResponse(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null);
-                        mClosed = true;
-                        mExceptionString = "Bad Request Received";
-                        throw new IOException("Bad Request Received");
-                    }
-                } else {
-
-                    if ((headerId == ObexHelper.OBEX_OPCODE_PUT_FINAL)) {
-                        finalBitSet = true;
-                    } else if (headerId == ObexHelper.OBEX_OPCODE_GET_FINAL) {
-                        mRequestFinished = true;
-                    }
-
-                    /*
-                     * Determine if the packet length is larger than the negotiated packet size
-                     */
-                    if (packet.mLength > ObexHelper.getMaxRxPacketSize(mTransport)) {
-                        mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null);
-                        throw new IOException("Packet received was too large");
-                    }
-
-                    /*
-                     * Determine if any headers were sent in the initial request
-                     */
-                    if (packet.mLength > 3 || (mSrmEnabled && packet.mLength == 3)) {
-                        if(handleObexPacket(packet) == false) {
-                            return false;
-                        }
-                    }
-                }
-
-            }
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * This method will look for an abort from the peer during a SRM transfer.
-     * The function will not block if no data has been received from the remote device.
-     * If data have been received, the function will block while reading the incoming
-     * OBEX package.
-     * An Abort request will be handled, and cause an IOException("Abort Received").
-     * Other messages will be discarded silently as per GOEP specification.
-     * @throws IOException if an abort request have been received.
-     * TODO: I think this is an error in the specification. If we discard other messages,
-     *       the peer device will most likely stall, as it will not receive the expected
-     *       response for the message...
-     *       I'm not sure how to understand "Receipt of invalid or unexpected SRM or SRMP
-     *       header values shall be ignored by the receiving device."
-     *       If any signal is received during an active SRM transfer it is unexpected regardless
-     *       whether or not it contains SRM/SRMP headers...
-     */
-    private void checkSrmRemoteAbort() throws IOException {
-        if(mInput.available() > 0) {
-            ObexPacket packet = ObexPacket.read(mInput);
-            /*
-             * Determine if an ABORT was sent as the reply
-             */
-            if (packet.mHeaderId == ObexHelper.OBEX_OPCODE_ABORT) {
-                handleRemoteAbort();
-            } else {
-                // TODO: should we throw an exception here anyway? - don't see how to
-                //       ignore SRM/SRMP headers without ignoring the complete signal
-                //       (in this particular case).
-                Log.w(TAG, "Received unexpected request from client - discarding...\n"
-                        + "   headerId: " + packet.mHeaderId + " length: " + packet.mLength);
-            }
-        }
-    }
-
-    private void handleRemoteAbort() throws IOException {
-        /* TODO: To increase the speed of the abort operation in SRM, we need
-         *       to be able to flush the L2CAP queue for the PSM in use.
-         *       This could be implemented by introducing a control
-         *       message to be send over the socket, that in the abort case
-         *       could carry a flush command. */
-        mParent.sendResponse(ResponseCodes.OBEX_HTTP_OK, null);
-        mClosed = true;
-        isAborted = true;
-        mExceptionString = "Abort Received";
-        throw new IOException("Abort Received");
-    }
-
-    /**
-     * Sends an ABORT message to the server. By calling this method, the
-     * corresponding input and output streams will be closed along with this
-     * object.
-     * @throws IOException if the transaction has already ended or if an OBEX
-     *         server called this method
-     */
-    public void abort() throws IOException {
-        throw new IOException("Called from a server");
-    }
-
-    /**
-     * Returns the headers that have been received during the operation.
-     * Modifying the object returned has no effect on the headers that are sent
-     * or retrieved.
-     * @return the headers received during this <code>Operation</code>
-     * @throws IOException if this <code>Operation</code> has been closed
-     */
-    public HeaderSet getReceivedHeader() throws IOException {
-        ensureOpen();
-        return requestHeader;
-    }
-
-    /**
-     * Specifies the headers that should be sent in the next OBEX message that
-     * is sent.
-     * @param headers the headers to send in the next message
-     * @throws IOException if this <code>Operation</code> has been closed or the
-     *         transaction has ended and no further messages will be exchanged
-     * @throws IllegalArgumentException if <code>headers</code> was not created
-     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
-     */
-    public void sendHeaders(HeaderSet headers) throws IOException {
-        ensureOpen();
-
-        if (headers == null) {
-            throw new IOException("Headers may not be null");
-        }
-
-        int[] headerList = headers.getHeaderList();
-        if (headerList != null) {
-            for (int i = 0; i < headerList.length; i++) {
-                replyHeader.setHeader(headerList[i], headers.getHeader(headerList[i]));
-            }
-
-        }
-    }
-
-    /**
-     * Retrieves the response code retrieved from the server. Response codes are
-     * defined in the <code>ResponseCodes</code> interface.
-     * @return the response code retrieved from the server
-     * @throws IOException if an error occurred in the transport layer during
-     *         the transaction; if this method is called on a
-     *         <code>HeaderSet</code> object created by calling
-     *         <code>createHeaderSet</code> in a <code>ClientSession</code>
-     *         object; if this is called from a server
-     */
-    public int getResponseCode() throws IOException {
-        throw new IOException("Called from a server");
-    }
-
-    /**
-     * Always returns <code>null</code>
-     * @return <code>null</code>
-     */
-    public String getEncoding() {
-        return null;
-    }
-
-    /**
-     * Returns the type of content that the resource connected to is providing.
-     * E.g. if the connection is via HTTP, then the value of the content-type
-     * header field is returned.
-     * @return the content type of the resource that the URL references, or
-     *         <code>null</code> if not known
-     */
-    public String getType() {
-        try {
-            return (String)requestHeader.getHeader(HeaderSet.TYPE);
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Returns the length of the content which is being provided. E.g. if the
-     * connection is via HTTP, then the value of the content-length header field
-     * is returned.
-     * @return the content length of the resource that this connection's URL
-     *         references, or -1 if the content length is not known
-     */
-    public long getLength() {
-        try {
-            Long temp = (Long)requestHeader.getHeader(HeaderSet.LENGTH);
-
-            if (temp == null) {
-                return -1;
-            } else {
-                return temp.longValue();
-            }
-        } catch (IOException e) {
-            return -1;
-        }
-    }
-
-    public int getMaxPacketSize() {
-        return mMaxPacketLength - 6 - getHeaderLength();
-    }
-
-    public int getHeaderLength() {
-        long id = mListener.getConnectionId();
-        if (id == -1) {
-            replyHeader.mConnectionID = null;
-        } else {
-            replyHeader.mConnectionID = ObexHelper.convertToByteArray(id);
-        }
-
-        byte[] headerArray = ObexHelper.createHeader(replyHeader, false);
-
-        return headerArray.length;
-    }
-
-    /**
-     * Open and return an input stream for a connection.
-     * @return an input stream
-     * @throws IOException if an I/O error occurs
-     */
-    public InputStream openInputStream() throws IOException {
-        ensureOpen();
-        return mPrivateInput;
-    }
-
-    /**
-     * Open and return a data input stream for a connection.
-     * @return an input stream
-     * @throws IOException if an I/O error occurs
-     */
-    public DataInputStream openDataInputStream() throws IOException {
-        return new DataInputStream(openInputStream());
-    }
-
-    /**
-     * Open and return an output stream for a connection.
-     * @return an output stream
-     * @throws IOException if an I/O error occurs
-     */
-    public OutputStream openOutputStream() throws IOException {
-        ensureOpen();
-
-        if (mPrivateOutputOpen) {
-            throw new IOException("no more input streams available, stream already opened");
-        }
-
-        if (!mRequestFinished) {
-            throw new IOException("no  output streams available ,request not finished");
-        }
-
-        if (mPrivateOutput == null) {
-            mPrivateOutput = new PrivateOutputStream(this, getMaxPacketSize());
-        }
-        mPrivateOutputOpen = true;
-        return mPrivateOutput;
-    }
-
-    /**
-     * Open and return a data output stream for a connection.
-     * @return an output stream
-     * @throws IOException if an I/O error occurs
-     */
-    public DataOutputStream openDataOutputStream() throws IOException {
-        return new DataOutputStream(openOutputStream());
-    }
-
-    /**
-     * Closes the connection and ends the transaction
-     * @throws IOException if the operation has already ended or is closed
-     */
-    public void close() throws IOException {
-        ensureOpen();
-        mClosed = true;
-    }
-
-    /**
-     * Verifies that the connection is open and no exceptions should be thrown.
-     * @throws IOException if an exception needs to be thrown
-     */
-    public void ensureOpen() throws IOException {
-        if (mExceptionString != null) {
-            throw new IOException(mExceptionString);
-        }
-        if (mClosed) {
-            throw new IOException("Operation has already ended");
-        }
-    }
-
-    /**
-     * Verifies that additional information may be sent. In other words, the
-     * operation is not done.
-     * <P>
-     * Included to implement the BaseStream interface only. It does not do
-     * anything on the server side since the operation of the Operation object
-     * is not done until after the handler returns from its method.
-     * @throws IOException if the operation is completed
-     */
-    public void ensureNotDone() throws IOException {
-    }
-
-    /**
-     * Called when the output or input stream is closed. It does not do anything
-     * on the server side since the operation of the Operation object is not
-     * done until after the handler returns from its method.
-     * @param inStream <code>true</code> if the input stream is closed;
-     *        <code>false</code> if the output stream is closed
-     * @throws IOException if an IO error occurs
-     */
-    public void streamClosed(boolean inStream) throws IOException {
-
-    }
-
-    public void noBodyHeader(){
-        mSendBodyHeader = false;
-    }
-}
diff --git a/obex/javax/obex/ServerRequestHandler.java b/obex/javax/obex/ServerRequestHandler.java
deleted file mode 100644
index 09cbc2c..0000000
--- a/obex/javax/obex/ServerRequestHandler.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-/**
- * The <code>ServerRequestHandler</code> class defines an event listener that
- * will respond to OBEX requests made to the server.
- * <P>
- * The <code>onConnect()</code>, <code>onSetPath()</code>,
- * <code>onDelete()</code>, <code>onGet()</code>, and <code>onPut()</code>
- * methods may return any response code defined in the
- * <code>ResponseCodes</code> class except for <code>OBEX_HTTP_CONTINUE</code>.
- * If <code>OBEX_HTTP_CONTINUE</code> or a value not defined in the
- * <code>ResponseCodes</code> class is returned, the server implementation will
- * send an <code>OBEX_HTTP_INTERNAL_ERROR</code> response to the client.
- * <P>
- * <STRONG>Connection ID and Target Headers</STRONG>
- * <P>
- * According to the IrOBEX specification, a packet may not contain a Connection
- * ID and Target header. Since the Connection ID header is managed by the
- * implementation, it will not send a Connection ID header, if a Connection ID
- * was specified, in a packet that has a Target header. In other words, if an
- * application adds a Target header to a <code>HeaderSet</code> object used in
- * an OBEX operation and a Connection ID was specified, no Connection ID will be
- * sent in the packet containing the Target header.
- * <P>
- * <STRONG>CREATE-EMPTY Requests</STRONG>
- * <P>
- * A CREATE-EMPTY request allows clients to create empty objects on the server.
- * When a CREATE-EMPTY request is received, the <code>onPut()</code> method will
- * be called by the implementation. To differentiate between a normal PUT
- * request and a CREATE-EMPTY request, an application must open the
- * <code>InputStream</code> from the <code>Operation</code> object passed to the
- * <code>onPut()</code> method. For a PUT request, the application will be able
- * to read Body data from this <code>InputStream</code>. For a CREATE-EMPTY
- * request, there will be no Body data to read. Therefore, a call to
- * <code>InputStream.read()</code> will return -1.
- * @hide
- */
-public class ServerRequestHandler {
-
-    private long mConnectionId;
-
-    /**
-     * Creates a <code>ServerRequestHandler</code>.
-     */
-    protected ServerRequestHandler() {
-        /*
-         * A connection ID of -1 implies there is no conenction ID
-         */
-        mConnectionId = -1;
-    }
-
-    /**
-     * Sets the connection ID header to include in the reply packets.
-     * @param connectionId the connection ID to use; -1 if no connection ID
-     *        should be sent
-     * @throws IllegalArgumentException if <code>id</code> is not in the range
-     *         -1 to 2<sup>32</sup>-1
-     */
-    public void setConnectionId(final long connectionId) {
-        if ((connectionId < -1) || (connectionId > 0xFFFFFFFFL)) {
-            throw new IllegalArgumentException("Illegal Connection ID");
-        }
-        mConnectionId = connectionId;
-    }
-
-    /**
-     * Retrieves the connection ID that is being used in the present connection.
-     * This method will return -1 if no connection ID is being used.
-     * @return the connection id being used or -1 if no connection ID is being
-     *         used
-     */
-    public long getConnectionId() {
-        return mConnectionId;
-    }
-
-    /**
-     * Called when a CONNECT request is received.
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * <code>onConnect()</code> will always return an <code>OBEX_HTTP_OK</code>
-     * response code.
-     * <P>
-     * The headers received in the request can be retrieved from the
-     * <code>request</code> argument. The headers that should be sent in the
-     * reply must be specified in the <code>reply</code> argument.
-     * @param request contains the headers sent by the client;
-     *        <code>request</code> will never be <code>null</code>
-     * @param reply the headers that should be sent in the reply;
-     *        <code>reply</code> will never be <code>null</code>
-     * @return a response code defined in <code>ResponseCodes</code> that will
-     *         be returned to the client; if an invalid response code is
-     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
-     *         will be used
-     */
-    public int onConnect(HeaderSet request, HeaderSet reply) {
-        return ResponseCodes.OBEX_HTTP_OK;
-    }
-
-    /**
-     * Called when a DISCONNECT request is received.
-     * <P>
-     * The headers received in the request can be retrieved from the
-     * <code>request</code> argument. The headers that should be sent in the
-     * reply must be specified in the <code>reply</code> argument.
-     * @param request contains the headers sent by the client;
-     *        <code>request</code> will never be <code>null</code>
-     * @param reply the headers that should be sent in the reply;
-     *        <code>reply</code> will never be <code>null</code>
-     */
-    public void onDisconnect(HeaderSet request, HeaderSet reply) {
-    }
-
-    /**
-     * Called when a SETPATH request is received.
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * <code>onSetPath()</code> will always return an
-     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
-     * <P>
-     * The headers received in the request can be retrieved from the
-     * <code>request</code> argument. The headers that should be sent in the
-     * reply must be specified in the <code>reply</code> argument.
-     * @param request contains the headers sent by the client;
-     *        <code>request</code> will never be <code>null</code>
-     * @param reply the headers that should be sent in the reply;
-     *        <code>reply</code> will never be <code>null</code>
-     * @param backup <code>true</code> if the client requests that the server
-     *        back up one directory before changing to the path described by
-     *        <code>name</code>; <code>false</code> to apply the request to the
-     *        present path
-     * @param create <code>true</code> if the path should be created if it does
-     *        not already exist; <code>false</code> if the path should not be
-     *        created if it does not exist and an error code should be returned
-     * @return a response code defined in <code>ResponseCodes</code> that will
-     *         be returned to the client; if an invalid response code is
-     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
-     *         will be used
-     */
-    public int onSetPath(HeaderSet request, HeaderSet reply, boolean backup, boolean create) {
-
-        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
-    }
-
-    /**
-     * Called when a DELETE request is received.
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * <code>onDelete()</code> will always return an
-     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
-     * <P>
-     * The headers received in the request can be retrieved from the
-     * <code>request</code> argument. The headers that should be sent in the
-     * reply must be specified in the <code>reply</code> argument.
-     * @param request contains the headers sent by the client;
-     *        <code>request</code> will never be <code>null</code>
-     * @param reply the headers that should be sent in the reply;
-     *        <code>reply</code> will never be <code>null</code>
-     * @return a response code defined in <code>ResponseCodes</code> that will
-     *         be returned to the client; if an invalid response code is
-     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
-     *         will be used
-     */
-    public int onDelete(HeaderSet request, HeaderSet reply) {
-        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
-    }
-
-    /**
-     * Called when a ABORT request is received.
-     */
-    public int onAbort(HeaderSet request, HeaderSet reply) {
-        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
-    }
-
-    /**
-     * Called when a PUT request is received.
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * <code>onPut()</code> will always return an
-     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
-     * <P>
-     * If an ABORT request is received during the processing of a PUT request,
-     * <code>op</code> will be closed by the implementation.
-     * @param operation contains the headers sent by the client and allows new
-     *        headers to be sent in the reply; <code>op</code> will never be
-     *        <code>null</code>
-     * @return a response code defined in <code>ResponseCodes</code> that will
-     *         be returned to the client; if an invalid response code is
-     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
-     *         will be used
-     */
-    public int onPut(Operation operation) {
-        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
-    }
-
-    /**
-     * Called when a GET request is received.
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * <code>onGet()</code> will always return an
-     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
-     * <P>
-     * If an ABORT request is received during the processing of a GET request,
-     * <code>op</code> will be closed by the implementation.
-     * @param operation contains the headers sent by the client and allows new
-     *        headers to be sent in the reply; <code>op</code> will never be
-     *        <code>null</code>
-     * @return a response code defined in <code>ResponseCodes</code> that will
-     *         be returned to the client; if an invalid response code is
-     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
-     *         will be used
-     */
-    public int onGet(Operation operation) {
-        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
-    }
-
-    /**
-     * Called when this object attempts to authenticate a client and the
-     * authentication request fails because the response digest in the
-     * authentication response header was wrong.
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * this method will do nothing.
-     * @param userName the user name returned in the authentication response;
-     *        <code>null</code> if no user name was provided in the response
-     */
-    public void onAuthenticationFailure(byte[] userName) {
-    }
-
-    /**
-     * Called by ServerSession to update the status of current transaction
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * this method will do nothing.
-     */
-    public void updateStatus(String message) {
-    }
-
-    /**
-     * Called when session is closed.
-     * <P>
-     * If this method is not implemented by the class that extends this class,
-     * this method will do nothing.
-     */
-    public void onClose() {
-    }
-
-    /**
-     * Override to add Single Response Mode support - e.g. if the supplied
-     * transport is l2cap.
-     * @return True if SRM is supported, else False
-     */
-    public boolean isSrmSupported() {
-        return false;
-    }
-}
diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java
deleted file mode 100644
index dbfeefd..0000000
--- a/obex/javax/obex/ServerSession.java
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- * Copyright (c) 2015 Samsung LSI
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import android.util.Log;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * This class in an implementation of the OBEX ServerSession.
- * @hide
- */
-public final class ServerSession extends ObexSession implements Runnable {
-
-    private static final String TAG = "Obex ServerSession";
-    private static final boolean V = ObexHelper.VDBG;
-
-    private ObexTransport mTransport;
-
-    private InputStream mInput;
-
-    private OutputStream mOutput;
-
-    private ServerRequestHandler mListener;
-
-    private Thread mProcessThread;
-
-    private int mMaxPacketLength;
-
-    private boolean mClosed;
-
-    /**
-     * Creates new ServerSession.
-     * @param trans the connection to the client
-     * @param handler the event listener that will process requests
-     * @param auth the authenticator to use with this connection
-     * @throws IOException if an error occurred while opening the input and
-     *         output streams
-     */
-    public ServerSession(ObexTransport trans, ServerRequestHandler handler, Authenticator auth)
-            throws IOException {
-        mAuthenticator = auth;
-        mTransport = trans;
-        mInput = mTransport.openInputStream();
-        mOutput = mTransport.openOutputStream();
-        mListener = handler;
-        mMaxPacketLength = 256;
-
-        mClosed = false;
-        mProcessThread = new Thread(this);
-        mProcessThread.start();
-    }
-
-    /**
-     * Processes requests made to the server and forwards them to the
-     * appropriate event listener.
-     */
-    public void run() {
-        try {
-
-            boolean done = false;
-            while (!done && !mClosed) {
-                if(V) Log.v(TAG, "Waiting for incoming request...");
-                int requestType = mInput.read();
-                if(V) Log.v(TAG, "Read request: " + requestType);
-                switch (requestType) {
-                    case ObexHelper.OBEX_OPCODE_CONNECT:
-                        handleConnectRequest();
-                        break;
-
-                    case ObexHelper.OBEX_OPCODE_DISCONNECT:
-                        handleDisconnectRequest();
-                        break;
-
-                    case ObexHelper.OBEX_OPCODE_GET:
-                    case ObexHelper.OBEX_OPCODE_GET_FINAL:
-                        handleGetRequest(requestType);
-                        break;
-
-                    case ObexHelper.OBEX_OPCODE_PUT:
-                    case ObexHelper.OBEX_OPCODE_PUT_FINAL:
-                        handlePutRequest(requestType);
-                        break;
-
-                    case ObexHelper.OBEX_OPCODE_SETPATH:
-                        handleSetPathRequest();
-                        break;
-                    case ObexHelper.OBEX_OPCODE_ABORT:
-                        handleAbortRequest();
-                        break;
-
-                    case -1:
-                        done = true;
-                        break;
-
-                    default:
-
-                        /*
-                         * Received a request type that is not recognized so I am
-                         * just going to read the packet and send a not implemented
-                         * to the client
-                         */
-                        int length = mInput.read();
-                        length = (length << 8) + mInput.read();
-                        for (int i = 3; i < length; i++) {
-                            mInput.read();
-                        }
-                        sendResponse(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED, null);
-                }
-            }
-
-        } catch (NullPointerException e) {
-            Log.d(TAG, "Exception occured - ignoring", e);
-        } catch (Exception e) {
-            Log.d(TAG, "Exception occured - ignoring", e);
-        }
-        close();
-    }
-
-    /**
-     * Handles a ABORT request from a client. This method will read the rest of
-     * the request from the client. Assuming the request is valid, it will
-     * create a <code>HeaderSet</code> object to pass to the
-     * <code>ServerRequestHandler</code> object. After the handler processes the
-     * request, this method will create a reply message to send to the server.
-     *
-     * @throws IOException if an error occurred at the transport layer
-     */
-    private void handleAbortRequest() throws IOException {
-        int code = ResponseCodes.OBEX_HTTP_OK;
-        HeaderSet request = new HeaderSet();
-        HeaderSet reply = new HeaderSet();
-
-        int length = mInput.read();
-        length = (length << 8) + mInput.read();
-        if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
-            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
-        } else {
-            for (int i = 3; i < length; i++) {
-                mInput.read();
-            }
-            code = mListener.onAbort(request, reply);
-            Log.v(TAG, "onAbort request handler return value- " + code);
-            code = validateResponseCode(code);
-        }
-        sendResponse(code, null);
-    }
-
-    /**
-     * Handles a PUT request from a client. This method will provide a
-     * <code>ServerOperation</code> object to the request handler. The
-     * <code>ServerOperation</code> object will handle the rest of the request.
-     * It will also send replies and receive requests until the final reply
-     * should be sent. When the final reply should be sent, this method will get
-     * the response code to use and send the reply. The
-     * <code>ServerOperation</code> object will always reply with a
-     * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
-     * needed.
-     * @param type the type of request received; either 0x02 or 0x82
-     * @throws IOException if an error occurred at the transport layer
-     */
-    private void handlePutRequest(int type) throws IOException {
-        ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
-        try {
-            int response = -1;
-
-            if ((op.finalBitSet) && !op.isValidBody()) {
-                response = validateResponseCode(mListener
-                        .onDelete(op.requestHeader, op.replyHeader));
-            } else {
-                response = validateResponseCode(mListener.onPut(op));
-            }
-            if (response != ResponseCodes.OBEX_HTTP_OK && !op.isAborted) {
-                op.sendReply(response);
-            } else if (!op.isAborted) {
-                // wait for the final bit
-                while (!op.finalBitSet) {
-                    op.sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
-                }
-                op.sendReply(response);
-            }
-        } catch (Exception e) {
-            /*To fix bugs in aborted cases,
-             *(client abort file transfer prior to the last packet which has the end of body header,
-             *internal error should not be sent because server has already replied with
-             *OK response in "sendReply")
-             */
-            if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e);
-            if (!op.isAborted) {
-                sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
-            }
-        }
-    }
-
-    /**
-     * Handles a GET request from a client. This method will provide a
-     * <code>ServerOperation</code> object to the request handler. The
-     * <code>ServerOperation</code> object will handle the rest of the request.
-     * It will also send replies and receive requests until the final reply
-     * should be sent. When the final reply should be sent, this method will get
-     * the response code to use and send the reply. The
-     * <code>ServerOperation</code> object will always reply with a
-     * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
-     * needed.
-     * @param type the type of request received; either 0x03 or 0x83
-     * @throws IOException if an error occurred at the transport layer
-     */
-    private void handleGetRequest(int type) throws IOException {
-        ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
-        try {
-            int response = validateResponseCode(mListener.onGet(op));
-
-            if (!op.isAborted) {
-                op.sendReply(response);
-            }
-        } catch (Exception e) {
-            if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e);
-            sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
-        }
-    }
-
-    /**
-     * Send standard response.
-     * @param code the response code to send
-     * @param header the headers to include in the response
-     * @throws IOException if an IO error occurs
-     */
-    public void sendResponse(int code, byte[] header) throws IOException {
-        int totalLength = 3;
-        byte[] data = null;
-        OutputStream op = mOutput;
-        if (op == null) {
-            return;
-        }
-
-        if (header != null) {
-            totalLength += header.length;
-            data = new byte[totalLength];
-            data[0] = (byte)code;
-            data[1] = (byte)(totalLength >> 8);
-            data[2] = (byte)totalLength;
-            System.arraycopy(header, 0, data, 3, header.length);
-        } else {
-            data = new byte[totalLength];
-            data[0] = (byte)code;
-            data[1] = (byte)0x00;
-            data[2] = (byte)totalLength;
-        }
-        op.write(data);
-        op.flush(); // TODO: Do we need to flush?
-    }
-
-    /**
-     * Handles a SETPATH request from a client. This method will read the rest
-     * of the request from the client. Assuming the request is valid, it will
-     * create a <code>HeaderSet</code> object to pass to the
-     * <code>ServerRequestHandler</code> object. After the handler processes the
-     * request, this method will create a reply message to send to the server
-     * with the response code provided.
-     * @throws IOException if an error occurred at the transport layer
-     */
-    private void handleSetPathRequest() throws IOException {
-        int length;
-        int flags;
-        @SuppressWarnings("unused")
-        int constants;
-        int totalLength = 3;
-        byte[] head = null;
-        int code = -1;
-        int bytesReceived;
-        HeaderSet request = new HeaderSet();
-        HeaderSet reply = new HeaderSet();
-
-        length = mInput.read();
-        length = (length << 8) + mInput.read();
-        flags = mInput.read();
-        constants = mInput.read();
-
-        if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
-            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
-            totalLength = 3;
-        } else {
-            if (length > 5) {
-                byte[] headers = new byte[length - 5];
-                bytesReceived = mInput.read(headers);
-
-                while (bytesReceived != headers.length) {
-                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
-                            - bytesReceived);
-                }
-
-                ObexHelper.updateHeaderSet(request, headers);
-
-                if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
-                    mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
-                } else {
-                    mListener.setConnectionId(1);
-                }
-                // the Auth chan is initiated by the server, client sent back the authResp .
-                if (request.mAuthResp != null) {
-                    if (!handleAuthResp(request.mAuthResp)) {
-                        code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
-                        mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
-                                request.mAuthResp));
-                    }
-                    request.mAuthResp = null;
-                }
-            }
-
-            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
-                // the Auth challenge is initiated by the client
-                // the server will send back the authResp to the client
-                if (request.mAuthChall != null) {
-                    handleAuthChall(request);
-                    reply.mAuthResp = new byte[request.mAuthResp.length];
-                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
-                            reply.mAuthResp.length);
-                    request.mAuthChall = null;
-                    request.mAuthResp = null;
-                }
-                boolean backup = false;
-                boolean create = true;
-                if (!((flags & 1) == 0)) {
-                    backup = true;
-                }
-                if (!((flags & 2) == 0)) {
-                    create = false;
-                }
-
-                try {
-                    code = mListener.onSetPath(request, reply, backup, create);
-                } catch (Exception e) {
-                    if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e);
-                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
-                    return;
-                }
-
-                code = validateResponseCode(code);
-
-                if (reply.nonce != null) {
-                    mChallengeDigest = new byte[16];
-                    System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
-                } else {
-                    mChallengeDigest = null;
-                }
-
-                long id = mListener.getConnectionId();
-                if (id == -1) {
-                    reply.mConnectionID = null;
-                } else {
-                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
-                }
-
-                head = ObexHelper.createHeader(reply, false);
-                totalLength += head.length;
-
-                if (totalLength > mMaxPacketLength) {
-                    totalLength = 3;
-                    head = null;
-                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
-                }
-            }
-        }
-
-        // Compute Length of OBEX SETPATH packet
-        byte[] replyData = new byte[totalLength];
-        replyData[0] = (byte)code;
-        replyData[1] = (byte)(totalLength >> 8);
-        replyData[2] = (byte)totalLength;
-        if (head != null) {
-            System.arraycopy(head, 0, replyData, 3, head.length);
-        }
-        /*
-         * Write the OBEX SETPATH packet to the server. Byte 0: response code
-         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
-         */
-        mOutput.write(replyData);
-        mOutput.flush();
-    }
-
-    /**
-     * Handles a disconnect request from a client. This method will read the
-     * rest of the request from the client. Assuming the request is valid, it
-     * will create a <code>HeaderSet</code> object to pass to the
-     * <code>ServerRequestHandler</code> object. After the handler processes the
-     * request, this method will create a reply message to send to the server.
-     * @throws IOException if an error occurred at the transport layer
-     */
-    private void handleDisconnectRequest() throws IOException {
-        int length;
-        int code = ResponseCodes.OBEX_HTTP_OK;
-        int totalLength = 3;
-        byte[] head = null;
-        int bytesReceived;
-        HeaderSet request = new HeaderSet();
-        HeaderSet reply = new HeaderSet();
-
-        length = mInput.read();
-        length = (length << 8) + mInput.read();
-
-        if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
-            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
-            totalLength = 3;
-        } else {
-            if (length > 3) {
-                byte[] headers = new byte[length - 3];
-                bytesReceived = mInput.read(headers);
-
-                while (bytesReceived != headers.length) {
-                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
-                            - bytesReceived);
-                }
-
-                ObexHelper.updateHeaderSet(request, headers);
-            }
-
-            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
-                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
-            } else {
-                mListener.setConnectionId(1);
-            }
-
-            if (request.mAuthResp != null) {
-                if (!handleAuthResp(request.mAuthResp)) {
-                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
-                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
-                            request.mAuthResp));
-                }
-                request.mAuthResp = null;
-            }
-
-            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
-
-                if (request.mAuthChall != null) {
-                    handleAuthChall(request);
-                    request.mAuthChall = null;
-                }
-
-                try {
-                    mListener.onDisconnect(request, reply);
-                } catch (Exception e) {
-                    if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e);
-                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
-                    return;
-                }
-
-                long id = mListener.getConnectionId();
-                if (id == -1) {
-                    reply.mConnectionID = null;
-                } else {
-                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
-                }
-
-                head = ObexHelper.createHeader(reply, false);
-                totalLength += head.length;
-
-                if (totalLength > mMaxPacketLength) {
-                    totalLength = 3;
-                    head = null;
-                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
-                }
-            }
-        }
-
-        // Compute Length of OBEX CONNECT packet
-        byte[] replyData;
-        if (head != null) {
-            replyData = new byte[3 + head.length];
-        } else {
-            replyData = new byte[3];
-        }
-        replyData[0] = (byte)code;
-        replyData[1] = (byte)(totalLength >> 8);
-        replyData[2] = (byte)totalLength;
-        if (head != null) {
-            System.arraycopy(head, 0, replyData, 3, head.length);
-        }
-        /*
-         * Write the OBEX DISCONNECT packet to the server. Byte 0: response code
-         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
-         */
-        mOutput.write(replyData);
-        mOutput.flush();
-    }
-
-    /**
-     * Handles a connect request from a client. This method will read the rest
-     * of the request from the client. Assuming the request is valid, it will
-     * create a <code>HeaderSet</code> object to pass to the
-     * <code>ServerRequestHandler</code> object. After the handler processes the
-     * request, this method will create a reply message to send to the server
-     * with the response code provided.
-     * @throws IOException if an error occurred at the transport layer
-     */
-    private void handleConnectRequest() throws IOException {
-        int packetLength;
-        @SuppressWarnings("unused")
-        int version;
-        @SuppressWarnings("unused")
-        int flags;
-        int totalLength = 7;
-        byte[] head = null;
-        int code = -1;
-        HeaderSet request = new HeaderSet();
-        HeaderSet reply = new HeaderSet();
-        int bytesReceived;
-
-        if(V) Log.v(TAG,"handleConnectRequest()");
-
-        /*
-         * Read in the length of the OBEX packet, OBEX version, flags, and max
-         * packet length
-         */
-        packetLength = mInput.read();
-        packetLength = (packetLength << 8) + mInput.read();
-        if(V) Log.v(TAG,"handleConnectRequest() - packetLength: " + packetLength);
-
-        version = mInput.read();
-        flags = mInput.read();
-        mMaxPacketLength = mInput.read();
-        mMaxPacketLength = (mMaxPacketLength << 8) + mInput.read();
-
-        if(V) Log.v(TAG,"handleConnectRequest() - version: " + version
-                + " MaxLength: " + mMaxPacketLength + " flags: " + flags);
-
-        // should we check it?
-        if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) {
-            mMaxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT;
-        }
-
-        if(mMaxPacketLength > ObexHelper.getMaxTxPacketSize(mTransport)) {
-            Log.w(TAG, "Requested MaxObexPacketSize " + mMaxPacketLength
-                    + " is larger than the max size supported by the transport: "
-                    + ObexHelper.getMaxTxPacketSize(mTransport)
-                    + " Reducing to this size.");
-            mMaxPacketLength = ObexHelper.getMaxTxPacketSize(mTransport);
-        }
-
-        if (packetLength > ObexHelper.getMaxRxPacketSize(mTransport)) {
-            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
-            totalLength = 7;
-        } else {
-            if (packetLength > 7) {
-                byte[] headers = new byte[packetLength - 7];
-                bytesReceived = mInput.read(headers);
-
-                while (bytesReceived != headers.length) {
-                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
-                            - bytesReceived);
-                }
-
-                ObexHelper.updateHeaderSet(request, headers);
-            }
-
-            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
-                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
-            } else {
-                mListener.setConnectionId(1);
-            }
-
-            if (request.mAuthResp != null) {
-                if (!handleAuthResp(request.mAuthResp)) {
-                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
-                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
-                            request.mAuthResp));
-                }
-                request.mAuthResp = null;
-            }
-
-            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
-                if (request.mAuthChall != null) {
-                    handleAuthChall(request);
-                    reply.mAuthResp = new byte[request.mAuthResp.length];
-                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
-                            reply.mAuthResp.length);
-                    request.mAuthChall = null;
-                    request.mAuthResp = null;
-                }
-
-                try {
-                    code = mListener.onConnect(request, reply);
-                    code = validateResponseCode(code);
-
-                    if (reply.nonce != null) {
-                        mChallengeDigest = new byte[16];
-                        System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
-                    } else {
-                        mChallengeDigest = null;
-                    }
-                    long id = mListener.getConnectionId();
-                    if (id == -1) {
-                        reply.mConnectionID = null;
-                    } else {
-                        reply.mConnectionID = ObexHelper.convertToByteArray(id);
-                    }
-
-                    head = ObexHelper.createHeader(reply, false);
-                    totalLength += head.length;
-
-                    if (totalLength > mMaxPacketLength) {
-                        totalLength = 7;
-                        head = null;
-                        code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
-                    }
-                } catch (Exception e) {
-                    if(V) Log.d(TAG,"Exception occured - sending OBEX_HTTP_INTERNAL_ERROR reply",e);
-                    totalLength = 7;
-                    head = null;
-                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
-                }
-
-            }
-        }
-
-        // Compute Length of OBEX CONNECT packet
-        byte[] length = ObexHelper.convertToByteArray(totalLength);
-
-        /*
-         * Write the OBEX CONNECT packet to the server. Byte 0: response code
-         * Byte 1&2: Connect Packet Length Byte 3: OBEX Version Number
-         * (Presently, 0x10) Byte 4: Flags (For TCP 0x00) Byte 5&6: Max OBEX
-         * Packet Length (Defined in MAX_PACKET_SIZE) Byte 7 to n: headers
-         */
-        byte[] sendData = new byte[totalLength];
-        int maxRxLength = ObexHelper.getMaxRxPacketSize(mTransport);
-        if (maxRxLength > mMaxPacketLength) {
-            if(V) Log.v(TAG,"Set maxRxLength to min of maxRxServrLen:" + maxRxLength +
-                    " and MaxNegotiated from Client: " + mMaxPacketLength);
-            maxRxLength = mMaxPacketLength;
-        }
-        sendData[0] = (byte)code;
-        sendData[1] = length[2];
-        sendData[2] = length[3];
-        sendData[3] = (byte)0x10;
-        sendData[4] = (byte)0x00;
-        sendData[5] = (byte)(maxRxLength >> 8);
-        sendData[6] = (byte)(maxRxLength & 0xFF);
-
-        if (head != null) {
-            System.arraycopy(head, 0, sendData, 7, head.length);
-        }
-
-        mOutput.write(sendData);
-        mOutput.flush();
-    }
-
-    /**
-     * Closes the server session - in detail close I/O streams and the
-     * underlying transport layer. Internal flag is also set so that later
-     * attempt to read/write will throw an exception.
-     */
-    public synchronized void close() {
-        if (mListener != null) {
-            mListener.onClose();
-        }
-        try {
-            /* Set state to closed before interrupting the thread by closing the streams */
-            mClosed = true;
-            if(mInput != null)
-                mInput.close();
-            if(mOutput != null)
-                mOutput.close();
-            if(mTransport != null)
-                mTransport.close();
-        } catch (Exception e) {
-            if(V) Log.d(TAG,"Exception occured during close() - ignore",e);
-        }
-        mTransport = null;
-        mInput = null;
-        mOutput = null;
-        mListener = null;
-    }
-
-    /**
-     * Verifies that the response code is valid. If it is not valid, it will
-     * return the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code.
-     * @param code the response code to check
-     * @return the valid response code or <code>OBEX_HTTP_INTERNAL_ERROR</code>
-     *         if <code>code</code> is not valid
-     */
-    private int validateResponseCode(int code) {
-
-        if ((code >= ResponseCodes.OBEX_HTTP_OK) && (code <= ResponseCodes.OBEX_HTTP_PARTIAL)) {
-            return code;
-        }
-        if ((code >= ResponseCodes.OBEX_HTTP_MULT_CHOICE)
-                && (code <= ResponseCodes.OBEX_HTTP_USE_PROXY)) {
-            return code;
-        }
-        if ((code >= ResponseCodes.OBEX_HTTP_BAD_REQUEST)
-                && (code <= ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE)) {
-            return code;
-        }
-        if ((code >= ResponseCodes.OBEX_HTTP_INTERNAL_ERROR)
-                && (code <= ResponseCodes.OBEX_HTTP_VERSION)) {
-            return code;
-        }
-        if ((code >= ResponseCodes.OBEX_DATABASE_FULL)
-                && (code <= ResponseCodes.OBEX_DATABASE_LOCKED)) {
-            return code;
-        }
-        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
-    }
-
-    public ObexTransport getTransport() {
-        return mTransport;
-    }
-}
diff --git a/obex/javax/obex/SessionNotifier.java b/obex/javax/obex/SessionNotifier.java
deleted file mode 100644
index 9836dd6..0000000
--- a/obex/javax/obex/SessionNotifier.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2008-2009, Motorola, Inc.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * - Neither the name of the Motorola, Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-package javax.obex;
-
-import java.io.IOException;
-
-/**
- * The <code>SessionNotifier</code> interface defines a connection notifier for
- * server-side OBEX connections. When a <code>SessionNotifier</code> is created
- * and calls <code>acceptAndOpen()</code>, it will begin listening for clients
- * to create a connection at the transport layer. When the transport layer
- * connection is received, the <code>acceptAndOpen()</code> method will return a
- * <code>javax.microedition.io.Connection</code> that is the connection to the
- * client. The <code>acceptAndOpen()</code> method also takes a
- * <code>ServerRequestHandler</code> argument that will process the requests
- * from the client that connects to the server.
- * @hide
- */
-public interface SessionNotifier {
-
-    /**
-     * Waits for a transport layer connection to be established and specifies
-     * the handler to handle the requests from the client. No authenticator is
-     * associated with this connection, therefore, it is implementation
-     * dependent as to how an authentication challenge and authentication
-     * response header will be received and processed.
-     * <P>
-     * <H4>Additional Note for OBEX over Bluetooth</H4> If this method is called
-     * on a <code>SessionNotifier</code> object that does not have a
-     * <code>ServiceRecord</code> in the SDDB, the <code>ServiceRecord</code>
-     * for this object will be added to the SDDB. This method requests the BCC
-     * to put the local device in connectable mode so that it will respond to
-     * connection attempts by clients.
-     * <P>
-     * The following checks are done to verify that the service record provided
-     * is valid. If any of these checks fail, then a
-     * <code>ServiceRegistrationException</code> is thrown.
-     * <UL>
-     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory service
-     * attributes for a <code>btgoep</code> service record, must be present in
-     * the <code>ServiceRecord</code> associated with this notifier.
-     * <LI>L2CAP, RFCOMM and OBEX must all be in the ProtocolDescriptorList
-     * <LI>The <code>ServiceRecord</code> associated with this notifier must not
-     * have changed the RFCOMM server channel number
-     * </UL>
-     * <P>
-     * This method will not ensure that <code>ServiceRecord</code> associated
-     * with this notifier is a completely valid service record. It is the
-     * responsibility of the application to ensure that the service record
-     * follows all of the applicable syntactic and semantic rules for service
-     * record correctness.
-     * @param handler the request handler that will respond to OBEX requests
-     * @return the connection to the client
-     * @throws IOException if an error occurs in the transport layer
-     * @throws NullPointerException if <code>handler</code> is <code>null</code>
-     */
-    ObexSession acceptAndOpen(ServerRequestHandler handler) throws IOException;
-
-    /**
-     * Waits for a transport layer connection to be established and specifies
-     * the handler to handle the requests from the client and the
-     * <code>Authenticator</code> to use to respond to authentication challenge
-     * and authentication response headers.
-     * <P>
-     * <H4>Additional Note for OBEX over Bluetooth</H4> If this method is called
-     * on a <code>SessionNotifier</code> object that does not have a
-     * <code>ServiceRecord</code> in the SDDB, the <code>ServiceRecord</code>
-     * for this object will be added to the SDDB. This method requests the BCC
-     * to put the local device in connectable mode so that it will respond to
-     * connection attempts by clients.
-     * <P>
-     * The following checks are done to verify that the service record provided
-     * is valid. If any of these checks fail, then a
-     * <code>ServiceRegistrationException</code> is thrown.
-     * <UL>
-     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory service
-     * attributes for a <code>btgoep</code> service record, must be present in
-     * the <code>ServiceRecord</code> associated with this notifier.
-     * <LI>L2CAP, RFCOMM and OBEX must all be in the ProtocolDescriptorList
-     * <LI>The <code>ServiceRecord</code> associated with this notifier must not
-     * have changed the RFCOMM server channel number
-     * </UL>
-     * <P>
-     * This method will not ensure that <code>ServiceRecord</code> associated
-     * with this notifier is a completely valid service record. It is the
-     * responsibility of the application to ensure that the service record
-     * follows all of the applicable syntactic and semantic rules for service
-     * record correctness.
-     * @param handler the request handler that will respond to OBEX requests
-     * @param auth the <code>Authenticator</code> to use with this connection;
-     *        if <code>null</code> then no <code>Authenticator</code> will be
-     *        used
-     * @return the connection to the client
-     * @throws IOException if an error occurs in the transport layer
-     * @throws NullPointerException if <code>handler</code> is <code>null</code>
-     */
-    ObexSession acceptAndOpen(ServerRequestHandler handler, Authenticator auth) throws IOException;
-}
diff --git a/packages/CompanionDeviceManager/res/color/selector.xml b/packages/CompanionDeviceManager/res/color/selector.xml
index fda827d..56e5dca 100644
--- a/packages/CompanionDeviceManager/res/color/selector.xml
+++ b/packages/CompanionDeviceManager/res/color/selector.xml
@@ -16,5 +16,5 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true" android:color="@android:color/darker_gray"/> <!-- pressed -->
-    <item android:color="@android:color/white"/>
+    <item android:color="?android:attr/colorBackground"/>
 </selector>
\ No newline at end of file
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..125fee6
--- /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="2dp"
+        android:color="@android:color/system_accent1_600" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml b/packages/CompanionDeviceManager/res/drawable/btn_negative_top.xml
similarity index 61%
rename from packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml
rename to packages/CompanionDeviceManager/res/drawable/btn_negative_top.xml
index e456e29..7df92bb 100644
--- a/packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml
+++ b/packages/CompanionDeviceManager/res/drawable/btn_negative_top.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ 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,12 +13,10 @@
   ~ 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">
-    <gradient
-        android:angle="90"
-        android:startColor="#ff000000"
-        android:endColor="#00000000"
-        android:type="linear" />
+
+<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/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml b/packages/CompanionDeviceManager/res/drawable/btn_positive_bottom.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml
copy to packages/CompanionDeviceManager/res/drawable/btn_positive_bottom.xml
index e456e29..55e96f6 100644
--- a/packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml
+++ b/packages/CompanionDeviceManager/res/drawable/btn_positive_bottom.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ 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,12 +13,10 @@
   ~ 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">
-    <gradient
-        android:angle="90"
-        android:startColor="#ff000000"
-        android:endColor="#00000000"
-        android:type="linear" />
+
+<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/dialog_background.xml b/packages/CompanionDeviceManager/res/drawable/dialog_background.xml
index ef7052d..a017f41 100644
--- a/packages/CompanionDeviceManager/res/drawable/dialog_background.xml
+++ b/packages/CompanionDeviceManager/res/drawable/dialog_background.xml
@@ -16,7 +16,7 @@
 
 <inset xmlns:android="http://schemas.android.com/apk/res/android">
     <shape android:shape="rectangle">
-        <corners android:radius="@*android:dimen/config_dialogCornerRadius" />
+        <corners android:radius="?android:attr/dialogCornerRadius" />
         <solid android:color="?android:attr/colorBackground" />
     </shape>
 </inset>
diff --git a/packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml b/packages/CompanionDeviceManager/res/drawable/helper_ok_button.xml
similarity index 60%
copy from packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml
copy to packages/CompanionDeviceManager/res/drawable/helper_ok_button.xml
index e456e29..f9ec5d0 100644
--- a/packages/SystemUI/res/drawable/notif_dungeon_bg_gradient.xml
+++ b/packages/CompanionDeviceManager/res/drawable/helper_ok_button.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ 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,12 +13,10 @@
   ~ 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">
-    <gradient
-        android:angle="90"
-        android:startColor="#ff000000"
-        android:endColor="#00000000"
-        android:type="linear" />
-</shape>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="@android:color/system_accent1_100"/>
+    <corners android:topLeftRadius="16dp" android:topRightRadius="16dp"
+             android:bottomLeftRadius="16dp" android:bottomRightRadius="16dp"/>
+</shape>
\ No newline at end of file
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_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/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index 70cbfdf..9e5b166 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -15,70 +15,75 @@
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
               android:id="@+id/activity_confirmation"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:background="@drawable/dialog_background"
-              android:elevation="16dp"
-              android:maxHeight="400dp"
-              android:orientation="vertical"
-              android:padding="18dp"
-              android:layout_gravity="center">
+              style="@style/ContainerLayout">
+
+    <!-- A header for selfManaged devices only. -->
+    <include layout="@layout/vendor_header" />
 
     <!-- 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" />
 
     <RelativeLayout
-            android:layout_width="match_parent"
-            android:layout_height="0dp"
-            android:layout_weight="1">
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1">
 
         <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/device_list"
-                style="@android:style/Widget.Material.ListView"
-                android:layout_width="match_parent"
-                android:layout_height="200dp" />
+            android:layout_width="match_parent"
+            android:scrollbars="vertical"
+            android:layout_height="200dp" />
+
+        <androidx.recyclerview.widget.RecyclerView
+            android:id="@+id/permission_list"
+            android:layout_width="match_parent"
+            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
new file mode 100644
index 0000000..c177039
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/layout/helper_confirmation.xml
@@ -0,0 +1,63 @@
+<!--
+  ~ 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/helper_confirmation"
+              android:theme="@style/ChooserActivity"
+              style="@style/ContainerLayout">
+
+    <ImageView
+        android:id="@+id/app_icon"
+        android:layout_width="match_parent"
+        android:layout_height="32dp"
+        android:gravity="center"
+        android:layout_marginBottom="12dp"
+        android:layout_marginTop="1dp"/>
+
+    <TextView
+        android:id="@+id/helper_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:textSize="20sp" />
+
+    <TextView
+        android:id="@+id/helper_summary"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="12dp"
+        android:layout_marginLeft="20dp"
+        android:layout_marginBottom="24dp"
+        android:gravity="start"
+        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">
+
+        <Button
+            android:id="@+id/btn_ok"
+            style="@style/VendorHelperOkButton"
+            android:text="@string/consent_ok" />
+
+    </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..b732b1b 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -25,16 +25,16 @@
     <!-- 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"/>
 
     <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..b8a0f79
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/layout/list_item_permission.xml
@@ -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.
+  -->
+
+<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: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/layout/vendor_header.xml b/packages/CompanionDeviceManager/res/layout/vendor_header.xml
new file mode 100644
index 0000000..d04eadf
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/layout/vendor_header.xml
@@ -0,0 +1,48 @@
+<!--
+  ~ 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.
+  -->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/vendor_header"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:layout_gravity="center"
+    android:layout_marginBottom="16dp"
+    android:visibility="gone" >
+
+    <ImageView
+        android:id="@+id/vendor_header_image"
+        android:layout_width="31dp"
+        android:layout_height="32dp" />
+
+    <TextView
+        android:id="@+id/vendor_header_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="20dp"
+        android:layout_marginTop="5dp"
+        android:layout_toRightOf="@+id/header_image" />
+
+    <ImageButton
+        android:id="@+id/vendor_header_button"
+        style="?android:attr/actionOverflowButtonStyle"
+        android:layout_width="31dp"
+        android:layout_height="32dp"
+        android:layout_marginLeft="100dp"
+        android:layout_alignParentRight="true" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-w650dp-land/dimens.xml b/packages/CompanionDeviceManager/res/values-night/themes.xml
similarity index 60%
copy from packages/SystemUI/res/values-w650dp-land/dimens.xml
copy to packages/CompanionDeviceManager/res/values-night/themes.xml
index 97b6da1..6eb16e7 100644
--- a/packages/SystemUI/res/values-w650dp-land/dimens.xml
+++ b/packages/CompanionDeviceManager/res/values-night/themes.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ 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,7 +13,14 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
+
 <resources>
-    <!-- Standard notification width + gravity -->
-    <dimen name="notification_panel_width">-1px</dimen> <!-- match_parent -->
+
+    <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 f32f2cd..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 stream applications?</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>
@@ -50,6 +56,12 @@
     <!-- 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="device">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 device when connected.</string>
 
+    <!-- Title of the helper dialog for APP_STREAMING profile [CHAR LIMIT=30]. -->
+    <string name="helper_title_app_streaming">Cross-device services</string>
+
+    <!-- Description of the helper dialog for APP_STREAMING profile. [CHAR LIMIT=NONE] -->
+    <string name="helper_summary_app_streaming">This service is used to stream apps between your devices</string>
+
     <!-- ================= DEVICE_PROFILE_AUTOMOTIVE_PROJECTION ================= -->
 
     <!-- Confirmation for associating an application with a companion device of AUTOMOTIVE_PROJECTION profile (type) [CHAR LIMIT=NONE] -->
@@ -66,6 +78,27 @@
     <!-- 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>
+
+    <!-- Description of the helper dialog for COMPUTER profile. [CHAR LIMIT=NONE] -->
+    <string name="helper_summary_computer" product="default">This service shares photos, media, and notifications form your phone to other devices</string>
+
+    <!-- Description of the helper dialog for COMPUTER profile. [CHAR LIMIT=NONE] -->
+    <string name="helper_summary_computer" product="tablet">This service shares photos, media, and notifications form your phone to other devices</string>
+
     <!-- ================= null profile ================= -->
 
     <!-- A noun for a companion device with unspecified profile (type) [CHAR LIMIT=30] -->
@@ -82,6 +115,9 @@
     <!-- Negative button for the device-app association consent dialog [CHAR LIMIT=30] -->
     <string name="consent_no">Don\u2019t allow</string>
 
+    <!-- Ok button for the helper consent dialog [CHAR LIMIT=30] -->
+    <string name="consent_ok">OK</string>
+
     <!-- ================== System data transfer ==================== -->
     <!-- Title of the permission sync confirmation dialog. [CHAR LIMIT=60] -->
     <string name="permission_sync_confirmation_title">Transfer app permissions to your
diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml
new file mode 100644
index 0000000..4a267db
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/values/styles.xml
@@ -0,0 +1,68 @@
+<!--
+  ~ 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="ContainerLayout">
+        <item name="android:padding">18dp</item>
+        <item name="android:elevation">16dp</item>
+        <item name="android:maxHeight">400dp</item>
+        <item name="android:orientation">vertical</item>
+        <item name="android:layout_gravity">center</item>
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:background">@drawable/dialog_background</item>
+    </style>
+
+    <style name="VendorHelperOkButton"
+           parent="@android:style/Widget.Material.Button.Borderless.Colored">
+        <item name="android:layout_width">50dp</item>
+        <item name="android:layout_height">35dp</item>
+        <item name="android:layout_marginTop">20dp</item>
+        <item name="android:textColor">@android:color/system_neutral1_900</item>
+        <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>
+
+</resources>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/themes.xml b/packages/CompanionDeviceManager/res/values/themes.xml
index 8559ef6..e3fc67c 100644
--- a/packages/CompanionDeviceManager/res/values/themes.xml
+++ b/packages/CompanionDeviceManager/res/values/themes.xml
@@ -17,13 +17,10 @@
 <resources>
 
     <style name="ChooserActivity"
-           parent="@style/Theme.AppCompat.Light.Dialog">
-        <item name="windowActionBar">false</item>
-        <item name="windowNoTitle">true</item>
+           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 a6a8fcf..0ab126a 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -24,8 +24,13 @@
 
 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.getVendorHeaderIcon;
+import static com.android.companiondevicemanager.Utils.getVendorHeaderName;
 import static com.android.companiondevicemanager.Utils.prepareResultReceiverForIpc;
 
 import static java.util.Objects.requireNonNull;
@@ -38,6 +43,7 @@
 import android.companion.IAssociationRequestCallback;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
 import android.net.MacAddress;
 import android.os.Bundle;
 import android.os.Handler;
@@ -47,19 +53,26 @@
 import android.util.Log;
 import android.view.View;
 import android.widget.Button;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
  *  A CompanionDevice activity response for showing the available
  *  nearby devices to be associated with.
  */
-public class CompanionDeviceActivity extends AppCompatActivity {
+public class CompanionDeviceActivity extends FragmentActivity implements
+        CompanionVendorHelperDialogFragment.CompanionVendorHelperDialogListener {
     private static final boolean DEBUG = false;
     private static final String TAG = CompanionDeviceActivity.class.getSimpleName();
 
@@ -72,6 +85,8 @@
     private static final String EXTRA_ASSOCIATION_REQUEST = "association_request";
     private static final String EXTRA_RESULT_RECEIVER = "result_receiver";
 
+    private static final String FRAGMENT_DIALOG_TAG = "fragment_dialog";
+
     // Activity result: Internal Error.
     private static final int RESULT_INTERNAL_ERROR = 2;
 
@@ -91,6 +106,11 @@
     private TextView mTitle;
     private TextView mSummary;
 
+    // Only present for selfManaged devices.
+    private ImageView mVendorHeaderImage;
+    private TextView mVendorHeaderName;
+    private ImageButton mVendorHeaderButton;
+
     // Progress indicator is only shown while we are looking for the first suitable device for a
     // "regular" (ie. not self-managed) association.
     private View mProgressIndicator;
@@ -98,11 +118,21 @@
     // Present for self-managed association requests and "single-device" regular association
     // regular.
     private Button mButtonAllow;
+    private Button mButtonNotAllow;
+    // Present for multiple devices association requests only.
+    private Button mButtonNotAllowMultipleDevices;
+
+    private LinearLayout mAssociationConfirmationDialog;
+    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.
@@ -112,6 +142,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()");
@@ -211,15 +243,31 @@
 
         setContentView(R.layout.activity_confirmation);
 
+        mAssociationConfirmationDialog = findViewById(R.id.activity_confirmation);
+        mVendorHeader = findViewById(R.id.vendor_header);
+
         mTitle = findViewById(R.id.title);
         mSummary = findViewById(R.id.summary);
 
-        mRecyclerView = findViewById(R.id.device_list);
-        mAdapter = new DeviceListAdapter(this, this::onListItemClick);
+        mVendorHeaderImage = findViewById(R.id.vendor_header_image);
+        mVendorHeaderName = findViewById(R.id.vendor_header_name);
+        mVendorHeaderButton = findViewById(R.id.vendor_header_button);
+
+        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);
-        findViewById(R.id.btn_negative).setOnClickListener(this::onNegativeButtonClick);
+        mButtonNotAllow.setOnClickListener(this::onNegativeButtonClick);
+        mButtonNotAllowMultipleDevices.setOnClickListener(this::onNegativeButtonClick);
+
+        mVendorHeaderButton.setOnClickListener(this::onShowHelperDialog);
 
         if (mRequest.isSelfManaged()) {
             initUiForSelfManagedAssociation(appLabel);
@@ -321,37 +369,58 @@
     private void initUiForSelfManagedAssociation(CharSequence appLabel) {
         if (DEBUG) Log.i(TAG, "initUiFor_SelfManaged_Association()");
 
-        final CharSequence deviceName = mRequest.getDisplayName(); // "<device>";
-        final String deviceProfile = mRequest.getDeviceProfile(); // DEVICE_PROFILE_APP_STREAMING;
-
+        final CharSequence deviceName = mRequest.getDisplayName();
+        final String deviceProfile = mRequest.getDeviceProfile();
+        final String packageName = mRequest.getPackageName();
+        final int userId = mRequest.getUserId();
+        final Drawable vendorIcon;
+        final CharSequence vendorName;
         final Spanned title;
-        final Spanned summary;
+
+        mPermissionTypes = new ArrayList<>();
+
+        try {
+            vendorIcon = getVendorHeaderIcon(this, packageName, userId);
+            vendorName = getVendorHeaderName(this, packageName, userId);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "Package u" + userId + "/" + packageName + " not found.");
+            setResultAndFinish(null, RESULT_INTERNAL_ERROR);
+            return;
+        }
+
         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);
         }
-        mTitle.setText(title);
-        mSummary.setText(summary);
 
-        mRecyclerView.setVisibility(View.GONE);
+        mSummary.setVisibility(View.GONE);
+
+        mPermissionListAdapter.setPermissionType(mPermissionTypes);
+        mPermissionListRecyclerView.setAdapter(mPermissionListAdapter);
+        mPermissionListRecyclerView.setLayoutManager(new LinearLayoutManager(this));
+
+        mTitle.setText(title);
+        mVendorHeaderImage.setImageDrawable(vendorIcon);
+        mVendorHeaderName.setText(vendorName);
+
+        mDeviceListRecyclerView.setVisibility(View.GONE);
+        mVendorHeader.setVisibility(View.VISIBLE);
     }
 
     private void initUiForSingleDevice(CharSequence appLabel) {
@@ -363,13 +432,15 @@
                 deviceFilterPairs -> updateSingleDeviceUi(
                         deviceFilterPairs, deviceProfile, appLabel));
 
-        mRecyclerView.setVisibility(View.GONE);
+        mPermissionListRecyclerView.setVisibility(View.GONE);
+        mDeviceListRecyclerView.setVisibility(View.GONE);
     }
 
     private void updateSingleDeviceUi(List<DeviceFilterPair<?>> deviceFilterPairs,
             String deviceProfile, CharSequence appLabel) {
         // Ignore "empty" scan reports.
         if (deviceFilterPairs.isEmpty()) return;
+
         mSelectedDevice = requireNonNull(deviceFilterPairs.get(0));
 
         final String deviceName = mSelectedDevice.getDisplayName();
@@ -411,31 +482,33 @@
         mTitle.setText(title);
         mSummary.setText(summary);
 
-        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);
     }
 
     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);
 
@@ -464,6 +537,17 @@
         cancel(false);
     }
 
+    private void onShowHelperDialog(View view) {
+        FragmentManager fragmentManager = getSupportFragmentManager();
+        CompanionVendorHelperDialogFragment fragmentDialog =
+                CompanionVendorHelperDialogFragment.newInstance(mRequest.getPackageName(),
+                        mRequest.getUserId(), mRequest.getDeviceProfile());
+
+        mAssociationConfirmationDialog.setVisibility(View.GONE);
+
+        fragmentDialog.show(fragmentManager, /* Tag */ FRAGMENT_DIALOG_TAG);
+    }
+
     private boolean isDone() {
         return mApproved || mCancelled;
     }
@@ -482,4 +566,14 @@
                     onAssociationCreated(association);
                 }
             };
+
+    @Override
+    public void onShowHelperDialogFailed() {
+        setResultAndFinish(null, RESULT_INTERNAL_ERROR);
+    }
+
+    @Override
+    public void onHelperDialogDismissed() {
+        mAssociationConfirmationDialog.setVisibility(View.VISIBLE);
+    }
 }
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.java
new file mode 100644
index 0000000..728e5e5
--- /dev/null
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionVendorHelperDialogFragment.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.companiondevicemanager;
+
+import static android.companion.AssociationRequest.DEVICE_PROFILE_APP_STREAMING;
+import static android.companion.AssociationRequest.DEVICE_PROFILE_COMPUTER;
+
+import static com.android.companiondevicemanager.Utils.getApplicationIcon;
+import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
+
+import android.annotation.Nullable;
+import android.content.DialogInterface;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.text.Spanned;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.DialogFragment;
+
+/**
+ * A fragmentDialog shows additional information about selfManaged devices
+ */
+public class CompanionVendorHelperDialogFragment extends DialogFragment {
+    private static final String TAG = CompanionVendorHelperDialogFragment.class.getSimpleName();
+
+    private static final String PACKAGE_NAME_EXTRA = "packageName";
+    private static final String DEVICE_PROFILE_EXTRA = "deviceProfile";
+    private static final String USER_ID_EXTRA = "userId";
+
+    private CompanionVendorHelperDialogListener mListener;
+    // Only present for selfManaged devices.
+    private TextView mTitle;
+    private TextView mSummary;
+    private ImageView mAppIcon;
+    private Button mButton;
+
+    interface CompanionVendorHelperDialogListener {
+        void onShowHelperDialogFailed();
+        void onHelperDialogDismissed();
+    }
+
+    private CompanionVendorHelperDialogFragment() {}
+
+    static CompanionVendorHelperDialogFragment newInstance(String packageName,
+            int userId, String deviceProfile) {
+        CompanionVendorHelperDialogFragment fragmentDialog =
+                new CompanionVendorHelperDialogFragment();
+
+        Bundle bundle = new Bundle();
+        bundle.putString(PACKAGE_NAME_EXTRA, packageName);
+        bundle.putInt(USER_ID_EXTRA, userId);
+        bundle.putString(DEVICE_PROFILE_EXTRA, deviceProfile);
+        fragmentDialog.setArguments(bundle);
+
+        return fragmentDialog;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mListener = (CompanionVendorHelperDialogListener) getActivity();
+        // Hide the title bar in the dialog.
+        setStyle(STYLE_NO_TITLE, /* Theme */0);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.helper_confirmation, container);
+    }
+
+    @Override
+    public void onDismiss(@NonNull DialogInterface dialog) {
+        super.onDismiss(dialog);
+        mListener.onHelperDialogDismissed();
+    }
+
+    @Override
+    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        Drawable applicationIcon;
+        String packageName = getArguments().getString(PACKAGE_NAME_EXTRA);
+        String deviceProfile = getArguments().getString(DEVICE_PROFILE_EXTRA);
+        int userId = getArguments().getInt(USER_ID_EXTRA);
+
+        try {
+            applicationIcon = getApplicationIcon(getContext(), packageName);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "Package u" + userId + "/" + packageName + " not found.");
+            mListener.onShowHelperDialogFailed();
+            return;
+        }
+
+        mTitle = view.findViewById(R.id.helper_title);
+        mSummary = view.findViewById(R.id.helper_summary);
+        mAppIcon = view.findViewById(R.id.app_icon);
+        mButton = view.findViewById(R.id.btn_ok);
+
+        final Spanned title;
+        final Spanned summary;
+
+        switch (deviceProfile) {
+            case DEVICE_PROFILE_APP_STREAMING:
+                title = getHtmlFromResources(getContext(), R.string.helper_title_app_streaming);
+                summary = getHtmlFromResources(getContext(), R.string.helper_summary_app_streaming);
+                break;
+
+            case DEVICE_PROFILE_COMPUTER:
+                title = getHtmlFromResources(getContext(), R.string.helper_title_computer);
+                summary = getHtmlFromResources(getContext(), R.string.helper_summary_computer);
+                break;
+
+            default:
+                throw new RuntimeException("Unsupported profile " + deviceProfile);
+        }
+
+        mTitle.setText(title);
+        mSummary.setText(summary);
+        mAppIcon.setImageDrawable(applicationIcon);
+
+        mButton.setOnClickListener(v -> {
+            dismiss();
+            mListener.onHelperDialogDismissed();
+        });
+    }
+}
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 e3e563d..d5b2f0a 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
@@ -21,6 +21,10 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Parcel;
@@ -32,6 +36,10 @@
  * Utilities.
  */
 class Utils {
+    private static final String COMPANION_DEVICE_ACTIVITY_VENDOR_ICON =
+            "android.companion.vendor_icon";
+    private static final String COMPANION_DEVICE_ACTIVITY_VENDOR_NAME =
+            "android.companion.vendor_name";
 
     /**
      * Convert an instance of a "locally-defined" ResultReceiver to an instance of
@@ -60,6 +68,12 @@
         return packageManager.getApplicationLabel(appInfo);
     }
 
+    static @NonNull Drawable getApplicationIcon(@NonNull Context context,
+            @NonNull String packageName) throws PackageManager.NameNotFoundException {
+        final PackageManager packageManager = context.getPackageManager();
+        return packageManager.getApplicationIcon(packageName);
+    }
+
     static Spanned getHtmlFromResources(
             @NonNull Context context, @StringRes int resId, CharSequence... formatArgs) {
         final String[] escapedArgs = new String[formatArgs.length];
@@ -70,6 +84,50 @@
         return Html.fromHtml(plain, 0);
     }
 
+    static @NonNull Drawable getVendorHeaderIcon(@NonNull Context context,
+            @NonNull String packageName, int userId) throws PackageManager.NameNotFoundException {
+        final ApplicationInfo appInfo = getApplicationInfo(context, packageName, userId);
+        final Bundle bundle = appInfo.metaData;
+        int resId = bundle == null ? 0 : bundle.getInt(COMPANION_DEVICE_ACTIVITY_VENDOR_ICON, 0);
+
+        if (bundle == null || resId == 0) {
+            return getApplicationIcon(context, packageName);
+        }
+
+        return context.createPackageContext(packageName, /* flags= */ 0).getDrawable(resId);
+    }
+
+    static CharSequence getVendorHeaderName(@NonNull Context context,
+            @NonNull String packageName, int userId) throws PackageManager.NameNotFoundException {
+        final ApplicationInfo appInfo = getApplicationInfo(context, packageName, userId);
+        final Bundle bundle = appInfo.metaData;
+
+        if (bundle == null) {
+            return "";
+        }
+
+        return appInfo.metaData.getCharSequence(COMPANION_DEVICE_ACTIVITY_VENDOR_NAME, "");
+    }
+
+    /**
+     * Getting ApplicationInfo from meta-data.
+     */
+    private static @NonNull ApplicationInfo getApplicationInfo(@NonNull Context context,
+            @NonNull String packageName, int userId) throws PackageManager.NameNotFoundException {
+        final PackageManager packageManager = context.getPackageManager();
+        final ApplicationInfoFlags flags = ApplicationInfoFlags.of(PackageManager.GET_META_DATA);
+        final ApplicationInfo appInfo = packageManager.getApplicationInfoAsUser(
+                packageName, flags, userId);
+
+        return appInfo;
+    }
+
+    static @NonNull Drawable getIcon(@NonNull Context context, int resId) {
+        Drawable icon = context.getResources().getDrawable(resId, null);
+        icon.setTint(Color.DKGRAY);
+        return icon;
+    }
+
     static void runOnMainThread(Runnable runnable) {
         if (Thread.currentThread() == Looper.getMainLooper().getThread()) {
             runnable.run();
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
index e879e40..a626971 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -27,13 +28,13 @@
 @SystemApi
 public final class EthernetNetworkUpdateRequest implements Parcelable {
     @NonNull
-    private final StaticIpConfiguration mIpConfig;
+    private final IpConfiguration mIpConfig;
     @NonNull
     private final NetworkCapabilities mNetworkCapabilities;
 
     @NonNull
-    public StaticIpConfiguration getIpConfig() {
-        return new StaticIpConfiguration(mIpConfig);
+    public IpConfiguration getIpConfiguration() {
+        return new IpConfiguration(mIpConfig);
     }
 
     @NonNull
@@ -41,20 +42,75 @@
         return new NetworkCapabilities(mNetworkCapabilities);
     }
 
-    public EthernetNetworkUpdateRequest(@NonNull final StaticIpConfiguration ipConfig,
+    private EthernetNetworkUpdateRequest(@NonNull final IpConfiguration ipConfig,
             @NonNull final NetworkCapabilities networkCapabilities) {
         Objects.requireNonNull(ipConfig);
         Objects.requireNonNull(networkCapabilities);
-        mIpConfig = new StaticIpConfiguration(ipConfig);
+        mIpConfig = new IpConfiguration(ipConfig);
         mNetworkCapabilities = new NetworkCapabilities(networkCapabilities);
     }
 
     private EthernetNetworkUpdateRequest(@NonNull final Parcel source) {
         Objects.requireNonNull(source);
-        mIpConfig = StaticIpConfiguration.CREATOR.createFromParcel(source);
+        mIpConfig = IpConfiguration.CREATOR.createFromParcel(source);
         mNetworkCapabilities = NetworkCapabilities.CREATOR.createFromParcel(source);
     }
 
+    /**
+     * Builder used to create {@link EthernetNetworkUpdateRequest} objects.
+     */
+    public static final class Builder {
+        @Nullable
+        private IpConfiguration mBuilderIpConfig;
+        @Nullable
+        private NetworkCapabilities mBuilderNetworkCapabilities;
+
+        public Builder(){}
+
+        /**
+         * Constructor to populate the builder's values with an already built
+         * {@link EthernetNetworkUpdateRequest}.
+         * @param request the {@link EthernetNetworkUpdateRequest} to populate with.
+         */
+        public Builder(@NonNull final EthernetNetworkUpdateRequest request) {
+            Objects.requireNonNull(request);
+            mBuilderIpConfig = new IpConfiguration(request.mIpConfig);
+            mBuilderNetworkCapabilities = new NetworkCapabilities(request.mNetworkCapabilities);
+        }
+
+        /**
+         * Set the {@link IpConfiguration} to be used with the {@code Builder}.
+         * @param ipConfig the {@link IpConfiguration} to set.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setIpConfiguration(@NonNull final IpConfiguration ipConfig) {
+            Objects.requireNonNull(ipConfig);
+            mBuilderIpConfig = new IpConfiguration(ipConfig);
+            return this;
+        }
+
+        /**
+         * Set the {@link NetworkCapabilities} to be used with the {@code Builder}.
+         * @param nc the {@link NetworkCapabilities} to set.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setNetworkCapabilities(@NonNull final NetworkCapabilities nc) {
+            Objects.requireNonNull(nc);
+            mBuilderNetworkCapabilities = new NetworkCapabilities(nc);
+            return this;
+        }
+
+        /**
+         * Build {@link EthernetNetworkUpdateRequest} return the current update request.
+         */
+        @NonNull
+        public EthernetNetworkUpdateRequest build() {
+            return new EthernetNetworkUpdateRequest(mBuilderIpConfig, mBuilderNetworkCapabilities);
+        }
+    }
+
     @Override
     public String toString() {
         return "EthernetNetworkUpdateRequest{"
@@ -68,7 +124,7 @@
         if (o == null || getClass() != o.getClass()) return false;
         EthernetNetworkUpdateRequest that = (EthernetNetworkUpdateRequest) o;
 
-        return Objects.equals(that.getIpConfig(), mIpConfig)
+        return Objects.equals(that.getIpConfiguration(), mIpConfig)
                 && Objects.equals(that.getNetworkCapabilities(), mNetworkCapabilities);
     }
 
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/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
index 67d48f0..735c44d 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
@@ -732,19 +732,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);
         }
 
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/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..b5e0539 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
@@ -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/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 7a5ea47..1b7298a 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -19,6 +19,7 @@
         "androidx.appcompat_appcompat",
         "androidx.lifecycle_lifecycle-runtime",
         "androidx.mediarouter_mediarouter-nodeps",
+        "com.google.android.material_material",
         "iconloader",
 
         "WifiTrackerLibRes",
diff --git a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml
index 77c4533..5e3907c 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-night-v31/colors.xml
@@ -31,7 +31,7 @@
     <!-- Dialog accent color -->
     <color name="settingslib_dialog_accent">@android:color/system_accent1_100</color>
     <!-- Dialog background color. -->
-    <color name="settingslib_dialog_background">@android:color/system_neutral1_800</color>
+    <color name="settingslib_dialog_background">@color/settingslib_surface_dark</color>
     <!-- Dialog error color. -->
     <color name="settingslib_dialog_colorError">#f28b82</color> <!-- Red 300 -->
 
@@ -49,4 +49,8 @@
     <color name="settingslib_text_color_preference_category_title">@android:color/system_accent1_100</color>
 
     <color name="settingslib_ripple_color">@color/settingslib_material_grey_900</color>
+
+    <color name="settingslib_surface_dark">@android:color/system_neutral1_800</color>
+
+    <color name="settingslib_colorSurface">@color/settingslib_surface_dark</color>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml
index 6adb789..c4dbc5e 100644
--- a/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values-v31/colors.xml
@@ -71,5 +71,12 @@
     <color name="settingslib_text_color_preference_category_title">@android:color/system_accent1_600</color>
 
     <color name="settingslib_ripple_color">?android:attr/colorControlHighlight</color>
+
     <color name="settingslib_material_grey_900">#ff212121</color>
+
+    <color name="settingslib_colorAccentPrimary">@color/settingslib_accent_primary_device_default</color>
+
+    <color name="settingslib_colorAccentSecondary">@color/settingslib_accent_secondary_device_default</color>
+
+    <color name="settingslib_colorSurface">@color/settingslib_surface_light</color>
 </resources>
diff --git a/packages/SettingsLib/res/color-night-v31/settingslib_tabs_indicator_color.xml b/packages/SettingsLib/res/color-night-v31/settingslib_tabs_indicator_color.xml
new file mode 100644
index 0000000..9a09360
--- /dev/null
+++ b/packages/SettingsLib/res/color-night-v31/settingslib_tabs_indicator_color.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@color/settingslib_colorAccentSecondary" />
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/color-night-v31/settingslib_tabs_text_color.xml b/packages/SettingsLib/res/color-night-v31/settingslib_tabs_text_color.xml
new file mode 100644
index 0000000..33f96df
--- /dev/null
+++ b/packages/SettingsLib/res/color-night-v31/settingslib_tabs_text_color.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="?android:attr/textColorPrimaryInverse"/>
+    <item android:state_enabled="false" android:color="?android:attr/textColorTertiary"/>
+    <item android:color="?android:attr/textColorSecondary"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/color-v31/settingslib_tabs_indicator_color.xml b/packages/SettingsLib/res/color-v31/settingslib_tabs_indicator_color.xml
new file mode 100644
index 0000000..57fef52f
--- /dev/null
+++ b/packages/SettingsLib/res/color-v31/settingslib_tabs_indicator_color.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@color/settingslib_colorAccentPrimary" />
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/color-v31/settingslib_tabs_text_color.xml b/packages/SettingsLib/res/color-v31/settingslib_tabs_text_color.xml
new file mode 100644
index 0000000..df2346d
--- /dev/null
+++ b/packages/SettingsLib/res/color-v31/settingslib_tabs_text_color.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:color="?android:attr/textColorPrimary"/>
+    <item android:state_enabled="false" android:color="?android:attr/textColorTertiary"/>
+    <item android:color="?android:attr/textColorSecondary"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml
new file mode 100644
index 0000000..f10b563
--- /dev/null
+++ b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_background.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:color="?android:colorControlHighlight">
+    <item android:id="@android:id/mask">
+        <inset
+            android:insetLeft="4dp"
+            android:insetRight="4dp">
+            <shape android:shape="rectangle">
+                <corners android:radius="12dp" />
+                <solid android:color="?android:colorControlHighlight" />
+            </shape>
+        </inset>
+    </item>
+
+    <item android:id="@android:id/background">
+        <inset
+               android:insetLeft="4dp"
+               android:insetRight="4dp">
+            <shape android:shape="rectangle">
+                <solid android:color="@color/settingslib_colorSurface" />
+                <corners android:radius="12dp" />
+            </shape>
+        </inset>
+    </item>
+</ripple>
diff --git a/packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml
new file mode 100644
index 0000000..f5a9782
--- /dev/null
+++ b/packages/SettingsLib/res/drawable-v31/settingslib_tabs_indicator_background.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:insetLeft="4dp"
+       android:insetRight="4dp">
+    <shape android:shape="rectangle">
+        <solid android:color="@color/settingslib_tabs_indicator_color" />
+        <corners android:radius="12dp" />
+    </shape>
+</inset>
\ No newline at end of file
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-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 734cc5d..24d1171 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalie (rooi-groen)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalie (blou-geel)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Kleurregstelling"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Verstel hoe kleure op jou toestel vertoon. Dit kan nuttig wees wanneer jy:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Kleure meer akkuraat wil sien&lt;/li&gt; &lt;li&gt;&amp;nbsp;Kleure wil verwyder om jou te help fokus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Kleurregstelling kan nuttig wees wanneer jy die volgende wil doen:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Om kleure meer akkuraat te sien&lt;/li&gt; &lt;li&gt;&amp;nbsp;Om kleure te verwyder om jou te help fokus&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> oor"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Laai nie"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Gekoppel, laai nie"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Gelaai"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Volgelaai"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Beheer deur administrateur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheer deur Beperkte Instellings"</string>
     <string name="disabled" msgid="8017887509554714950">"Gedeaktiveer"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Laat hierdie program toe om wekkers te stel en tydsensitiewe handelinge te skeduleer. Dit laat die program op die agtergrond werk, wat meer batterykrag kan gebruik.\n\nAs hierdie toestemming af is, sal bestaande wekkers en tydgegronde geleenthede wat deur hierdie program geskeduleer is, nie werk nie."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"skedule, wekker, onthounota, horlosie"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Skakel aan"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Skakel Moenie steur nie aan"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nooit"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Net prioriteit"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index bb4899e..e620141 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ፕሮታኖማሊ (ቀይ-አረንጓዴ)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ትራይታኖማሊ (ሰማያዊ-ቢጫ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"የቀለም ማስተካከያ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ቀለሞች በመሣሪያዎ ላይ እንዴት እንደሚታዩ ያስተካክሉ። የሚከተሉትን ለማድረግ በሚፈልጉበት ጊዜ ይህ ጠቃሚ ሊሆን ይችላል፦&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ቀለሞችን የበለጠ ትክክለኛ በሆነ መልኩ ለመመልከት&lt;/li&gt; &lt;li&gt;&amp;nbsp;ትኩረት ለማድረግ እንዲረዳዎ ቀለሞችን ለማስወገድ&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"የሚከተሉትን ለማድረግ ሲፈልጉ የቀለም ማስተካከያ ጠቃሚ ሊሆን ይችላል፡-&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ቀለሞችን ይበልጥ በትክክል ለመመልከት&lt;/li&gt; &lt;li&gt;&amp;nbsp;ትኩረት ለማድረግ እንዲያግዙዎ ቀለሞችን ለማስወገድ&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ገደማ ቀርቷል"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ባትሪ እየሞላ አይደለም"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ተገናኝቷል፣ ኃይል በመሙላት ላይ አይደለም"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ባትሪ ሞልቷል"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"ሙሉ ለሙሉ ኃይል ተሞልቷል"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"በአስተዳዳሪ ቁጥጥር የተደረገበት"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"በተገደበ ቅንብር ቁጥጥር የሚደረግበት"</string>
     <string name="disabled" msgid="8017887509554714950">"ቦዝኗል"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ይህ መተግበሪያ ማንቂያዎችን እንዲያቀናብር እና የጊዜ ትብነት ያላቸው እርምጃዎችን መርሐግብር እንዲያስይዝ ይፍቀዱለት። ይህ መተግበሪያው ከበስተጀርባ ማሄድ እንዲችል ያስችለዋል፣ ይህም የበለጠ ባትሪ ሊጠቀም ይችላል።\n\nይህ ፈቃድ ከጠፋ በዚህ መተግበሪያ መርሐግብር የተያዘላቸው ነባር ማንቂያዎች እና ጊዜ-ተኮር ክስተቶች አይሰሩም።"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"የጊዜ መርሐግብር፣ ማንቂያ፣ አስታዋሽ ሰዓት"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"አብራ"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"አትረብሽን አብራ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"በጭራሽ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"ቅድሚያ የሚሰጠው ብቻ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>። <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index f3df256..65e37e8 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"غطش الأحمر (الأحمر والأخضر)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"غمش الأزرق (الأزرق والأصفر)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"تصحيح الألوان"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"‏يمكنك تعديل كيفية عرض الألوان على جهازك. يساعدك هذا الخيار عندما تريد تنفيذ ما يلي:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;عرض الألوان بمزيد من الدقة&lt;/li&gt; &lt;li&gt;&amp;nbsp;إزالة الألوان لمساعدتك على التركيز&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"‏يمكنك الاستفادة من ميزة \"تصحيح الألوان\" عندما تريد:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;مشاهدة الألوان بدقة أكبر&lt;/li&gt; &lt;li&gt;&amp;nbsp;إزالة الألوان لمساعدتك على التركيز&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"يتبقى <xliff:g id="TIME_REMAINING">%1$s</xliff:g> تقريبًا."</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"لا يتم الشحن"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"الجهاز متصل بالشاحن، ولا يتم الشحن."</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"مشحونة"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"البطارية مشحونة بالكامل."</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"إعدادات يتحكم فيها المشرف"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"يتحكّم فيه إعداد محظور"</string>
     <string name="disabled" msgid="8017887509554714950">"غير مفعّل"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"يمكنك السماح لهذا التطبيق بضبط المنبّهات وجدولة الإجراءات لتنفيذها في الوقت المناسب. ويسمح هذا الإذن بتشغيل التطبيق في الخلفية، ما قد يستهلك المزيد من البطارية.\n\nفي حال عدم تفعيل هذا الإذن، لن تعمل المنبهات الحالية والأحداث المستندة إلى الوقت المضبوطة في هذا التطبيق."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"جدول زمني، جدولة، منبّه، تذكير، ساعة"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"تفعيل"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"تفعيل ميزة \"عدم الإزعاج\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"مطلقًا"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"الأولوية فقط"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 5499852..f965a34 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"প্ৰ’টানোমালি (ৰঙা-সেউজীয়া)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ট্ৰাইটান\'মেলী (নীলা-হালধীয়া)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ৰং শুধৰণী"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"আপোনাৰ ডিভাইচত ৰংবোৰ কেনেকৈ প্ৰদৰ্শিত হয় সেয়া মিলাওক। আপুনি এয়া কৰিবলৈ বিচাৰিলে এইটো সহায়ক হ’ব পাৰে:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ৰংবোৰ অধিক সঠিকভাৱে চোৱা&lt;/li&gt; &lt;li&gt;&amp;nbsp;আপোনাক মনোনিৱেশ কৰাৰ ক্ষেত্ৰত সহায় কৰিবলৈ ৰং আঁতৰোৱা&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"আপুনি এই কামসমূহ কৰিবলৈ বিচাৰিলে ৰং শুধৰণিৰ সুবিধাটো সহায়ক হ’ব পাৰে:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ৰঙবোৰ অধিক সঠিককৈ দেখা পোৱা&lt;/li&gt; &lt;li&gt;&amp;nbsp;আপোনাক মনোযোগ দিয়াত সহায় কৰিবলৈ ৰং আঁতৰোৱা&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g>ৰ দ্বাৰা অগ্ৰাহ্য কৰা হৈছে"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"প্রায় <xliff:g id="TIME_REMAINING">%1$s</xliff:g> বাকী আছে"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"চ্চাৰ্জ কৰা নাই"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"সংযোগ হৈ আছে, চাৰ্জ হৈ থকা নাই"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"চাৰ্জ হ’ল"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"সম্পূৰ্ণ চাৰ্জ হৈছে"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"এডমিনৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"প্ৰতিবন্ধিত ছেটিঙৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
     <string name="disabled" msgid="8017887509554714950">"নিষ্ক্ৰিয়"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"এই এপ্‌টোক এলাৰ্ম ছেট কৰিবলৈ আৰু সময় সংবেদনশীল কাৰ্যৰ সময়সূচী নিৰ্ধাৰণ কৰিবলৈ দিয়ক। ই এপ্‌টোক নেপথ্যত চলি থকাৰ অনুমতি দিয়ে যাৰ ফলত অধিক বেটাৰী ব্যৱহাৰ হয়।\n\nএই অনুমতিটো অফ কৰা থাকিলে, ইতিমধ্যে ছেট কৰা এলাৰ্ম আৰু এই এপ্‌টোৱে সময়সূচী নিৰ্ধাৰণ কৰা সময় ভিত্তিক অনুষ্ঠানসমূহে কাম নকৰা হ’ব।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"সময়সূচী, এলাৰ্ম, ৰিমাইণ্ডাৰ, ঘড়ী"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"অন কৰক"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"অসুবিধা নিদিব অন কৰক"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"কেতিয়াও নহয়"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"কেৱল গুৰুত্বপূৰ্ণ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index ee61930..3fb3f2c 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaliya (qırmızı-yaşıl)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaliya (göy-sarı)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Rəng korreksiyası"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ekranda rəngi korreksiya edə bilərsiniz. Mümkün olanlar:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;rəng ötürülməsinin yaxşılaşdırılması;&lt;/li&gt; &lt;li&gt;&amp;nbsp;rahat fokuslanmaq üçün ağ-qara rejimə keçid.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Rəng korreksiyası bunları etmək istədikdə faydalı ola bilər:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Rəngləri daha dəqiq görmək&lt;/li&gt; &lt;li&gt;&amp;nbsp;Fokuslanmaq üçün rəngləri ləğv etmək&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Təxminən <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qalıb"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Doldurulmur"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Qoşulub, şarj edilmir"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Şarj edilib"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Tam şarj edilib"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Admin tərəfindən nəzarət olunur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Məhdudlaşdırılmış Ayar ilə nəzarət edilir"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktiv"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu tətbiqə siqnallar ayarlamağa və vaxta əsaslanan əməliyyatları planlaşdırmağa icazə verin. Bu, tətbiqin arxa fonda işləməsinə imkan verir ki, nəticədə daha çox enerji istifadə edilə bilər.\n\nBu icazə deaktiv olsa, bu tətbiq tərəfindən planlaşdırılan mövcud siqnallar və vaxta əsaslanan tədbirlər işləməyəcəkdir."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"cədvəl, siqnal, xatırlatma, saat"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktiv edin"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Narahat Etməyin\" rejimini aktiv edin"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Heç vaxt"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"İcazəli şəxslər"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index f7834b7..a267b46 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalija (crveno-zeleno)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalija (plavo-žuto)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Korekcija boja"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Prilagodite način na koji se boje prikazuju na uređaju. To može da bude korisno kada želite:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;da vam se boje tačnije prikazuju&lt;/li&gt; &lt;li&gt;&amp;nbsp;da uklonite boje kako biste se fokusirali&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Korekcija boja može da bude korisna kada želite:to:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;da preciznije vidite boje&lt;/li&gt; &lt;li&gt;&amp;nbsp;da uklonite boje kako biste se fokusirali&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Napunjeno do kraja"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontroliše administrator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolišu ograničena podešavanja"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite ovoj aplikaciji da podešava alarme i zakazuje vremenski osetljive radnje. To omogućava da aplikacija bude pokrenuta u pozadini, što može da troši više baterije.\n\nAko je ova dozvola isključena, postojeći alarmi i događaji zasnovani na vremenu zakazani pomoću ove aplikacije neće raditi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"zakazati, alarm, podsetnik, sat"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite režim Ne uznemiravaj"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikad"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Samo prioritetni prekidi"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index e63cddd..4a1f387 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Пратанамалія (чырвоны-зялёны)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Трытанамалія (сіні-жоўты)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Карэкцыя колераў"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Наладзьце адлюстраванне колераў на экране прылады. Гэта налада можа быць карыснай, калі вы захочаце:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;бачыць колеры больш дакладна;&lt;/li&gt; &lt;li&gt;&amp;nbsp;выдаліць колеры, якія перашкаджаюць вам сканцэнтравацца&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Карэкцыя колераў можа спатрэбіцца, калі вы захочаце:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;бачыць колеры больш дакладна&lt;/li&gt; &lt;li&gt;&amp;nbsp;выдаліць колеры, каб сканцэнтраваць увагу&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Зараду хопіць прыблізна на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не зараджаецца"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Падключана, не зараджаецца"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Зараджаны"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Акумулятар поўнасцю зараджаны"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Кантралюецца адміністратарам"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Пад кіраваннем Абмежаванага наладжвання"</string>
     <string name="disabled" msgid="8017887509554714950">"Адключанае"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дазвольце гэтай праграме ўключаць будзільнікі і задаваць час дзеянняў. З такім дазволам праграма можа працаваць у фонавым рэжыме і ў выніку хутчэй разраджаць акумулятар.\n\nКалі вы не ўключыце гэты дазвол, існуючыя будзільнікі і запланаваны праграмай час падзей не будуць працаваць."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"расклад, будзільнік, напамін, гадзіннік"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Уключыць"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Уключэнне рэжыму \"Не турбаваць\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ніколі"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Толькі прыярытэтныя"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 538f0f1..c3fd060 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалия (червено – зелено)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалия (синьо – жълто)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекция на цветове"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Коригирайте как цветовете се показват на устройството ви. Това може да бъде полезно, когато искате:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да видите цветовете по-ясно;&lt;/li&gt; &lt;li&gt;&amp;nbsp;да премахнете цветовете, за да се фокусирате.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Функцията за корекция на цветовете може да бъде полезна, когато искате:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да виждате по-точни цветове;&lt;/li&gt; &lt;li&gt;&amp;nbsp;да премахнете цветовете, за да се съсредоточите.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Още около <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не се зарежда"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Свързано, не се зарежда"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Заредена"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Напълно заредено"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролира се от администратор"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Управлява се чрез ограничена настройка"</string>
     <string name="disabled" msgid="8017887509554714950">"Деактивирано"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Разрешаване на това приложение да задава будилници и да насрочва действия, ограничени във времето. Това му позволява да работи на заден план, при което може да се използва повече батерия.\n\nАко разрешението е изключено, съществуващите будилници и събитията въз основа на времето, насрочени от приложението, няма да работят."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, будилник, напомняне, часовник"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включване"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включване на режима „Не безпокойте“"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никога"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Само с приоритет"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 9a9fabb..2e9360e 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"প্রোটানোম্যালি (লাল-সবুজ)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ট্রিট্যানোম্যালি (নীল-হলুদ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"রঙ সংশোধন"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"আপনার ডিভাইসে রঙগুলি কেমন দেখাবে তা অ্যাডজাস্ট করুন। যেক্ষেত্রে এটি আপনাকে সহায়তা করতে পারে:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;আরও নির্ভুলভাবে রঙ দেখতে&lt;/li&gt; &lt;li&gt;&amp;nbsp;রঙ সরিয়ে দিয়ে ফোকাস করতে সহায়তা করবে&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"\'রঙ সংশোধন করা\' ফিচারের সাহায্যে এইসব কাজে করা যেতে পারে:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;আরও সঠিকভাবে রঙ দেখা&lt;/li&gt; &lt;li&gt;&amp;nbsp;ফোকাস করার জন্য রঙ সরানো&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"আর আনুমানিক <xliff:g id="TIME_REMAINING">%1$s</xliff:g> চলবে"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"চার্জ হচ্ছে না"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"কানেক্ট করা থাকলেও চার্জ করা হচ্ছে না"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"চার্জ হয়েছে"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"সম্পূর্ণ চার্জ আছে"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"প্রশাসকের দ্বারা নিয়ন্ত্রিত"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"এটি বিধিনিষেধ সেটিং থেকে নিয়ন্ত্রণ করা হয়"</string>
     <string name="disabled" msgid="8017887509554714950">"অক্ষম হয়েছে"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"অ্যালার্ম এবং সময়ের মধ্যে শেষ করতে হবে এমন অ্যাকশনের শিডিউল সেট করতে এই অ্যাপকে অনুমতি দিন। এর ফলে ব্যাকগ্রাউন্ডে অ্যাপ চলতে পারে, যার জন্য আরও ব্যাটারির চার্জ খরচ হতে পারে।\n\nএই অনুমতি বন্ধ করা থাকলে, আগে থেকে থাকা অ্যালার্ম এবং অ্যাপের মাধ্যমে শিডিউল করা সময় ভিত্তিক ইভেন্টের রিমাইন্ডার কাজ করবে না।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"শিডিউল, অ্যালার্ম, রিমাইন্ডার, ঘড়ি"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"চালু করুন"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'বিরক্ত করবে না\' মোড চালু করুন"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"কখনও নয়"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"শুধুমাত্র অগ্রাধিকার"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index ba5cc4e..77711cc 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalija (crveno-zeleno)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalija (plavo-žuto)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Ispravka boja"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Podesite način na koji se boje prikazuju na uređaju. To može biti korisno kada želite:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;preciznije prikazati boje&lt;/li&gt; &lt;li&gt;&amp;nbsp;ukloniti boje da se lakše fokusirate&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Ispravka boja može biti korisna kada želite da:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;vidite jasnije boje&lt;/li&gt; &lt;li&gt;&amp;nbsp;uklonite boje radi lakšeg fokusiranja&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Preostalo je još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Potpuno napunjeno"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Pod kontrolom administratora"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Dozvolite ovoj aplikaciji da postavlja alarme i zakazuje vremenski osjetljive radnje. Ovim će se omogućiti aplikaciji da radi u pozadini, čime se može povećati potrošnja baterije.\n\nAko je ovo odobrenje isključeno, postojeći alarmi i događaji zasnovani na vremenu koje je ova aplikacija zakazala neće funkcionirati."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključi način rada Ne ometaj"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikada"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Samo prioriteti"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 30dfbe5..92e7c1a 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalia (vermell-verd)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (blau-groc)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Correcció de color"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajusta com es mostren els colors al teu dispositiu. Això pot ser útil quan vulguis:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Veure els colors amb més claredat.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Suprimir colors per poder concentrar-te.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"La correcció de color pot ser útil si vols:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Veure els colors amb més precisió.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Suprimir els colors per concentrar-te millor.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>: <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Temps restant aproximat: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"No s\'està carregant"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connectat; no s\'està carregant"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Totalment carregada"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlat per l\'administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlat per la configuració restringida"</string>
     <string name="disabled" msgid="8017887509554714950">"Desactivat"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permet que aquesta aplicació configuri alarmes i programi accions. Això permet a l\'aplicació executar-se en segon pla i, per tant, és possible que consumeixi més bateria.\n\nSi aquest permís està desactivat, les alarmes i els esdeveniments que ja hagi programat l\'aplicació no funcionaran."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programació, alarma, recordatori, rellotge"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activa"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activa el mode No molestis"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mai"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Només amb prioritat"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>."</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 0006a76..014eda9 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomálie (červená a zelená)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomálie (modrá a žlutá)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Korekce barev"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Na svém zařízení si můžete upravit zobrazování barev. To se může hodit, když chcete:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;zobrazovat barvy přesněji&lt;/li&gt; &lt;li&gt;&amp;nbsp;odstranit barvy, abyste se mohli lépe soustředit&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Korekce barev se může hodit, když chcete:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Zobrazit přesnější barvy.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Odstranit barvy kvůli zlepšení soustředění.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Zbývá asi <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nenabíjí se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Připojeno, nenabíjí se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Nabito"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Plně nabito"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Spravováno administrátorem"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Spravováno omezeným nastavením"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktivováno"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Povolte aplikaci nastavovat budíky a plánovat akce závislé na čase. Aplikace poběží na pozadí, což může vést k vyšší spotřebě baterie.\n\nPokud je toto oprávnění vypnuté, stávající budíky a události závislé na čase naplánované touto aplikací nebudou fungovat."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, připomenutí, hodiny"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnout"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapněte funkci Nerušit"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikdy"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Pouze prioritní"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 63e462a..d10975d 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanopi (rød-grøn)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanopi (blå-gul)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Farvekorrigering"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Juster, hvordan farverne vises på din enhed. Dette kan være nyttigt, når du vil:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Se farver mere nøjagtigt&lt;/li&gt; &lt;li&gt;&amp;nbsp;Fjerne farver, så du bedre kan fokusere&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Farvekorrigering kan være en nyttig funktion, når du vil:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Se farver mere nøjagtigt&lt;/li&gt; &lt;li&gt;&amp;nbsp;Fjerne farver, så du nemmere kan fokusere&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ca. <xliff:g id="TIME_REMAINING">%1$s</xliff:g> tilbage"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Oplader ikke"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Tilsluttet, oplader ikke"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Opladet"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Fuldt opladet"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolleret af administratoren"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styres af en begrænset indstilling"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktiveret"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillad, at denne app indstiller alarmer og planlægger tidsbestemte handlinger. Appen vil køre i baggrunden, hvor den muligvis bruger mere batteri.\n\nHvis denne tilladelse er deaktiveret, vil eksisterende alarmer og tidsbestemte handlinger, der er planlagt af denne app, ikke fungere."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planlæg, alarm, påmindelse, ur"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivér"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivér Forstyr ikke"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrig"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Kun prioritet"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index db26c5d..9b8b3b5 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalie (Rot-Grün-Sehschwäche)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalie (Blau-Gelb-Sehschwäche)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Farbkorrektur"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Hier kannst du anpassen, wie Farben auf deinem Gerät dargestellt werden sollen. Das kann in folgenden Fällen hilfreich sein:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Wenn du Farben genauer erkennen möchtest&lt;/li&gt; &lt;li&gt;&amp;nbsp;Wenn du Farben entfernen möchtest, um dich besser konzentrieren zu können&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Die Farbkorrektur kann nützlich sein, wenn du:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Farben noch genauer sehen möchtest&lt;/li&gt; &lt;li&gt;&amp;nbsp;bestimmte Farben entfernen möchtest, um dich besser zu konzentrieren&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Noch etwa <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Wird nicht geladen"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Verbunden, wird nicht geladen"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Aufgeladen"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Vollständig geladen"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Durch den Administrator verwaltet"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gesteuert durch eingeschränkte Einstellung"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktiviert"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Dieser App erlauben, Wecker zu stellen und zeitgebundene Aktionen zu planen. Dadurch läuft die App im Hintergrund. Dies kann den Akkuverbrauch erhöhen. \n\nWenn diese Berechtigung deaktiviert ist, funktionieren bereits gestellte Wecker und zeitgebundene Ereignisse, die von dieser App geplant sind, nicht wie erwartet."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planen, Wecker, Erinnerung, Uhr"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivieren"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„Bitte nicht stören“ aktivieren"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nie"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Nur wichtige Unterbrechungen"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>."</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 3ca2115..cb6ec17 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Πρωτανοπία (κόκκινο-πράσινο)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Τριτανοπία (μπλε-κίτρινο)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Διόρθωση χρωμάτων"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Προσαρμόστε πώς θα εμφανίζονται τα χρώματα στη συσκευή σας. Αυτό μπορεί να είναι χρήσιμο όταν θέλετε:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Να βλέπετε τα χρώματα με μεγαλύτερη ακρίβεια&lt;/li&gt; &lt;li&gt;&amp;nbsp;Να καταργήσετε τα χρώματα για να συγκεντρωθείτε&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Η διόρθωση χρωμάτων μπορεί να σας φανεί χρήσιμη όταν θέλετε:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Μεγαλύτερη ακρίβεια στην απεικόνιση χρωμάτων&lt;/li&gt; &lt;li&gt;&amp;nbsp;Να καταργήσετε χρώματα για να συγκεντρωθείτε&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Απομένει/ουν περίπου <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Δεν φορτίζει"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Συνδεδεμένη, δεν φορτίζει"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Φορτισμένη"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Πλήρως φορτισμένο"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Ελέγχονται από το διαχειριστή"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ελέγχεται από τη Ρύθμιση με περιορισμό"</string>
     <string name="disabled" msgid="8017887509554714950">"Απενεργοποιημένο"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Επιτρέψτε σε αυτήν την εφαρμογή να ορίζει ξυπνητήρια και να προγραμματίζει ενέργειες που εξαρτώνται από τον χρόνο. Αυτό επιτρέπει στην εφαρμογή να εκτελείται στο παρασκήνιο και, ως εκ τούτου, μπορεί να καταναλώνει περισσότερη μπαταρία.\n\nΑν αυτή η άδεια δεν είναι ενεργή, τα υπάρχοντα ξυπνητήρια και συμβάντα βάσει χρόνου που έχουν προγραμματιστεί από αυτήν την εφαρμογή δεν θα λειτουργούν."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"χρονοδιάγραμμα, ξυπνητήρι, υπενθύμιση, ρολόι"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ενεργοποίηση"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ενεργοποίηση λειτουργίας \"Μην ενοχλείτε\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ποτέ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Μόνο προτεραιότητας"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 434e3a9..c2c14b4 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (red-green)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (blue-yellow)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Colour correction"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Adjust how colours display on your device. This can be helpful when you want to:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Colour correction can be helpful when you want to:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Fully charged"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priority only"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 0f2f9e7..91d4a31 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (red-green)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (blue-yellow)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Colour correction"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Adjust how colours display on your device. This can be helpful when you want to:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Colour correction can be helpful when you want to:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Fully charged"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priority only"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 434e3a9..c2c14b4 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (red-green)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (blue-yellow)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Colour correction"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Adjust how colours display on your device. This can be helpful when you want to:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Colour correction can be helpful when you want to:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Fully charged"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priority only"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 434e3a9..c2c14b4 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (red-green)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (blue-yellow)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Colour correction"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Adjust how colours display on your device. This can be helpful when you want to:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Colour correction can be helpful when you want to:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colours more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colours to help you focus&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"About <xliff:g id="TIME_REMAINING">%1$s</xliff:g> left"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Not charging"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connected, not charging"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Charged"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Fully charged"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlled by admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.\n\nIf this permission is off, existing alarms and time-based events scheduled by this app won’t work."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schedule, alarm, reminder, clock"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Turn on"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Turn on Do Not Disturb"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Never"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priority only"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index da1305a..ebb1d0e 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‎‎‎‎Protanomaly (red-green)‎‏‎‎‏‎"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎Tritanomaly (blue-yellow)‎‏‎‎‏‎"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎Color correction‎‏‎‎‏‎"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎Adjust how colors display on your device. This can be helpful when you want to:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colors more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colors to help you focus&lt;/li&gt; &lt;/ol&gt;‎‏‎‎‏‎"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‏‎Color correction can be helpful when you want to:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;See colors more accurately&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remove colors to help you focus&lt;/li&gt; &lt;/ol&gt;‎‏‎‎‏‎"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎Overridden by ‎‏‎‎‏‏‎<xliff:g id="TITLE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ - ‎‏‎‎‏‏‎<xliff:g id="TIME_STRING">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎About ‎‏‎‎‏‏‎<xliff:g id="TIME_REMAINING">%1$s</xliff:g>‎‏‎‎‏‏‏‎ left‎‏‎‎‏‎"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎Not charging‎‏‎‎‏‎"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‏‎Connected, not charging‎‏‎‎‏‎"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‎‎‎‎‎Charged‎‏‎‎‏‎"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎‎‎Fully Charged‎‏‎‎‏‎"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‎‏‎Controlled by admin‎‏‎‎‏‎"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‎Controlled by Restricted Setting‎‏‎‎‏‎"</string>
     <string name="disabled" msgid="8017887509554714950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‎Disabled‎‏‎‎‏‎"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎Allow this app to set alarms and schedule time-sensitive actions. This lets the app run in the background, which may use more battery.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎If this permission is off, existing alarms and time-based events scheduled by this app won’t work.‎‏‎‎‏‎"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎schedule, alarm, reminder, clock‎‏‎‎‏‎"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎Turn on‎‏‎‎‏‎"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎Turn on Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎Never‎‏‎‎‏‎"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‏‏‎Priority only‎‏‎‎‏‎"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="ZEN_MODE">%1$s</xliff:g>‎‏‎‎‏‏‏‎. ‎‏‎‎‏‏‎<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 63c56ba0..254d41e 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalía (rojo-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalía (azul-amarillo)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Corrección de color"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajusta cómo se muestran los colores en tu dispositivo. Esto puede ser útil cuando quieres:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver colores con más exactitud&lt;/li&gt; &lt;li&gt;&amp;nbsp;Quitar colores para tener un enfoque más claro&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"La corrección de colores puede ser útil cuando quieres hacer lo siguiente:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver los colores con mayor precisión&lt;/li&gt; &lt;li&gt;&amp;nbsp;Quitar colores para concentrarte&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tiempo restante: aproximadamente <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando."</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado; no se está cargando"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Carga completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada por la configuración restringida"</string>
     <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta app establezca alarmas y programe acciones para horarios específicos. De esta manera, la app puede ejecutarse en segundo plano, lo que podría aumentar el consumo de batería.\n\nSi se desactiva este permiso, no funcionarán las alarmas ni los eventos basados en el tiempo existentes que programe esta app."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar No interrumpir"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Solo prioridad"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 743e81c..447475f 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalía (rojo-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalía (azul-amarillo)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Corrección de color"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajusta el modo en que se muestran los colores en tu dispositivo. Esto puede ser útil cuando quieras hacer lo siguiente:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver los colores con más precisión&lt;/li&gt; &lt;li&gt;&amp;nbsp;Quitar colores para ayudarte a mantener la concentración&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Corrección de color puede ser útil si quieres:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver los colores mejor&lt;/li&gt; &lt;li&gt;&amp;nbsp;Quitar los colores para concentrarte mejor&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>: <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tiempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"No se está cargando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado pero sin cargar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Carga completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por ajustes restringidos"</string>
     <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación programe alarmas y otras acciones que se llevan a cabo a una hora determinada. Esto hace que la aplicación siga activa en segundo plano, lo que puede usar más batería.\n\nSi este permiso está desactivado, no funcionarán las alarmas ni los eventos que se activan a una hora determinada que programe esta aplicación."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarma, recordatorio, reloj"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar el modo No molestar"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Solo interrupciones prioritarias"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 63998f9..2c8a943 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaalia (punane-roheline)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaalia (sinine-kollane)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Värvide korrigeerimine"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Kohandage seadmes värvide kuvamist. Sellest võib olla kasu, kui soovite:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;värve täpsemalt näha;&lt;/li&gt; &lt;li&gt;&amp;nbsp;värve eemaldada, et paremini keskenduda.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Värvide korrigeerimisest võib abi olla, kui soovite:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;värve täpsemalt näha;&lt;/li&gt; &lt;li&gt;&amp;nbsp;värve eemaldada, et paremini keskenduda.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ligikaudu <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäänud"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ei lae"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ühendatud, ei laeta"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Laetud"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Täielikult laetud"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Juhib administraator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Haldavad piiranguga seaded"</string>
     <string name="disabled" msgid="8017887509554714950">"Keelatud"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lubage sellel rakendusel määrata alarme ja ajastada ajakriitilisi toiminguid. See võimaldab rakendusel töötada taustal, mistõttu võib akukasutus olla suurem.\n\nKui see luba on välja lülitatud, siis olemasolevad alarmid ja selle rakenduse ajastatud ajapõhised sündmused ei tööta."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajakava, äratus, meeldetuletus, kell"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Lülita sisse"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Valiku Mitte segada sisselülitamine"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mitte kunagi"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Ainult prioriteetsed"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 498f873..019119e 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanopia (gorri-berdeak)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanopia (urdin-horia)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Koloreen zuzenketa"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Doitu nola bistaratzen diren koloreak gailuan. Kasu hauetan izan daiteke lagungarria:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Koloreak zehatzago ikusi nahi dituzunean.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Hobeto fokuratzeko, koloreak kendu nahi dituzunean.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Koloreen zuzenketa lagungarria izan daiteke hauek egin nahi dituzunean:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Koloreak zehaztasun handiagoz ikusi.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Koloreak kendu, arreta gal ez dezazun.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> inguru gelditzen dira"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ez da kargatzen ari"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Konektatuta dago, baina ez da kargatzen ari"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Kargatuta"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Erabat kargatuta"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Administratzaileak kontrolatzen du"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ezarpen mugatuak kontrolatzen du"</string>
     <string name="disabled" msgid="8017887509554714950">"Desgaituta"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Eman alarmak ezartzeko eta denbora-muga duten ekintzak programatzeko baimena aplikazioari. Hala, aplikazioak atzeko planoan funtzionatuko du, eta litekeena da bateria gehiago kontsumitzea.\n\nEz baduzu ematen baimen hori, ez dute funtzionatuko aplikazio honen bidez programatutako alarmek eta denbora-muga duten ekintzek."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programazioa, alarma, abisua, erlojua"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktibatu"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktibatu ez molestatzeko modua"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Inoiz ez"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Lehentasunezkoak soilik"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 4152219..5e7ee60 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"قرمزدشواربینی (قرمز-سبز)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"آبی‌دشواربینی (آبی-زرد)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"تصحیح رنگ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"‏نحوه نمایش رنگ‌ها را در دستگاهتان تنظیم می‌کند. این ویژگی می‌تواند در موارد زیر مفید باشد:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp; وقتی می‌خواهید رنگ‌ها را با دقت بیشتری ببینید&lt;/li&gt; &lt;li&gt;&amp;nbsp;وقتی می‌خواهید رنگ‌ها را حذف کنید تا تمرکز بیشتری داشته باشید&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"‏«تصحیح رنگ» می‌تواند در مواقع زیر مفید باشد:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;وقتی می‌خواهید رنگ‌ها را دقیق‌تر ببینید&lt;/li&gt; &lt;li&gt;&amp;nbsp;وقتی می‌خواهید رنگ‌ها را حذف کنید تا بتوانید راحت‌تر تمرکز کنید&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> شارژ باقی مانده است"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"شارژ نمی‌شود"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"متصل، شارژ نمی‌شود"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"شارژ کامل شد"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"کاملاً شارژ شده است"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"توسط سرپرست سیستم کنترل می‌شود"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"با تنظیم «حالت محدود» کنترل می‌شود"</string>
     <string name="disabled" msgid="8017887509554714950">"غیر فعال شد"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"به این برنامه اجازه می‌دهد زنگ ساعت تنظیم کند و کنش‌های حساس به زمان زمان‌بندی کند. این تنظیم به برنامه اجازه می‌دهد در پس‌زمینه اجرا شود که ممکن است باتری بیشتری مصرف کند.\n\nاگر این اجازه خاموش باشد، زنگ‌های ساعت موجود و رویدادهای مبتنی بر زمان که این برنامه زمان‌بندی کرده است کار نخواهند کرد."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"زمان‌بندی، زنگ ساعت، یادآوری، ساعت"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"روشن کردن"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"روشن کردن «مزاحم نشوید»"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"هرگز"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"فقط اولویت‌دار"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 2b5b550..04df99f 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalia (puna-vihersokeus)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (sini-keltasokeus)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Värinkorjaus"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Muuta värien näkymistä laitteellasi. Tästä voi olla hyötyä, kun haluat&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;nähdä värit tarkemmin&lt;/li&gt; &lt;li&gt;&amp;nbsp;poistaa värejä voidaksesi keskittyä paremmin&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Värinkorjaus voi auttaa seuraavissa:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Värien tarkempi näkeminen&lt;/li&gt; &lt;li&gt;&amp;nbsp;Värien poistaminen keskittymisen parantamiseksi&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Noin <xliff:g id="TIME_REMAINING">%1$s</xliff:g> jäljellä"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ei laturissa"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Yhdistetty, ei ladata"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Ladattu"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Täyteen ladattu"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Järjestelmänvalvoja hallinnoi tätä asetusta."</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Rajoitettujen asetusten mukaisesti"</string>
     <string name="disabled" msgid="8017887509554714950">"Pois päältä"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Anna sovelluksen lisätä herätyksiä ja ajoittaa kiireellisiä tapahtumia. Näin sovellus voi toimia taustalla, mikä voi kuluttaa enemmän virtaa.\n\nIlman tätä lupaa sovelluksen ajoittamat herätykset ja aikaan perustuvat tapahtumat eivät toimi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajoitus, herätys, muistutus, kello"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ota käyttöön"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ota Älä häiritse ‑tila käyttöön"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ei koskaan"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Vain tärkeät"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 7ecaa38..88ddd28d 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalie (rouge/vert)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalie (bleu/jaune)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Correction des couleurs"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajustez l\'affichage des couleurs sur votre appareil. Ce paramètre peut être utile si vous voulez :&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Mieux distinguer les couleurs&lt;/li&gt; &lt;li&gt;&amp;nbsp;Enlever les couleurs pour vous aider à vous concentrer&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"La correction des couleurs peut être utile lorsque vous souhaitez :&lt;br/&gt; &lt;ol&gt; &lt;li&gt; voir les couleurs avec plus de précision;&lt;/li&gt; &lt;li&gt; retirer les couleurs pour vous aider à vous concentrer.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> : <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Il reste environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"N\'est pas en charge"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connecté, pas en charge"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Chargée"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Complètement rechargée"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Contrôlé par l\'administrateur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string>
     <string name="disabled" msgid="8017887509554714950">"Désactivée"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette application à créer des alarmes et à programmer des actions urgentes. Cela permet à l’application de s\'exécuter en arrière-plan, ce qui peut nécessiter plus de pile.\n\nSi cette autorisation est désactivée, les alarmes existantes et les événements en temps réel programmés par cette application ne fonctionneront pas."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"horaire, alarme, rappel, horloge"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Prioritaires seulement"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index dbc398e..c703484 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalie (rouge/vert)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalie (bleu-jaune)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Correction des couleurs"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajustez l\'affichage des couleurs sur votre appareil. Cette option peut vous être utile pour :&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Accentuer la précision des couleurs&lt;/li&gt; &lt;li&gt;&amp;nbsp;Supprimer les couleurs pour mieux vous concentrer&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"La correction des couleurs peut vous être utile pour :&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Distinguer les couleurs plus précisément&lt;/li&gt; &lt;li&gt;&amp;nbsp;Supprimer les couleurs afin de mieux vous concentrer&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Temps restant : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Pas en charge"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Connectée, pas en charge"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Chargée"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Complètement chargée"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Contrôlé par l\'administrateur"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string>
     <string name="disabled" msgid="8017887509554714950">"Désactivée"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Autorisez cette appli à définir des alarmes et à programmer des actions à certaines heures. Elle s\'exécutera alors en arrière-plan, ce qui peut solliciter davantage la batterie.\n\nSi l\'autorisation est désactivée, les alarmes existantes et les événements programmés par l\'appli ne fonctionneront pas."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"définir, alarme, rappel, horloge"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activer"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activer le mode Ne pas déranger"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jamais"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Prioritaires uniquement"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index b211606..02fa931f 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalía (vermello-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalía (azul-amarelo)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Corrección da cor"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Axusta a maneira en que se mostran as cores no teu dispositivo. Esta opción pode resultarche útil se queres:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver mellor as cores&lt;/li&gt; &lt;li&gt;&amp;nbsp;Quitar as cores para concentrarte mellor&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"A corrección da cor pode serche útil se queres:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver mellor as cores&lt;/li&gt; &lt;li&gt;&amp;nbsp;Quitar as cores para concentrarte mellor&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Non se está cargando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado, sen cargar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Cargada"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Carga completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Opción controlada polo administrador"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Baixo o control de opcións restrinxidas"</string>
     <string name="disabled" msgid="8017887509554714950">"Desactivada"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permite que esta aplicación defina alarmas e planifique accións que dependan da hora. Con este permiso, a aplicación pode executarse en segundo plano, o que pode provocar un maior consumo de batería.\n\nSe este permiso está desactivado, non funcionarán as alarmas que xa se definisen nin os eventos que dependan da hora planificados por esta aplicación."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planificar, alarma, recordatorio, reloxo"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activar"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activar modo Non molestar"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Só prioridade"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 203a298..b2a9ff3 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"પ્રોટેનોમલી (લાલ-લીલો)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ટ્રાઇટેનોમલી(વાદળી-પીળો)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"રંગ સુધારણા"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"તમારા ડિવાઇસ પર રંગો કેવી રીતે બતાવવામાં આવે તેની ગોઠવણી કરો. આ ત્યારે સહાયરૂપ થઈ શકે છે જ્યારે તમારે:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;રંગો વધુ યોગ્ય રીતે જોવા હોય&lt;/li&gt; &lt;li&gt;&amp;nbsp;તમને ફોકસ કરવામાં સહાયતા રહે તે માટે રંગો કાઢી નાખવા હોય&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"રંગમાં સુધારણા કરવાની સુવિધાનો ઉપયોગ ત્યારે સહાયરૂપ બની શકે છે કે જ્યારે તમે આ કરવા માગતા હો:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;વધુ સચોટપણે રંગ જોવા&lt;/li&gt; &lt;li&gt;&amp;nbsp;ફોકસ કરવામાં સહાય માટે અમુક રંગ કાઢી નાખવા&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"લગભગ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> બાકી છે"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ચાર્જ થઈ રહ્યું નથી"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"કનેક્ટ કરેલું છે, પણ ચાર્જ થઈ રહ્યું નથી"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ચાર્જ થયું"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"સંપૂર્ણપણે ચાર્જ છે"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"પ્રતિબંધિત સેટિંગ દ્વારા નિયંત્રિત"</string>
     <string name="disabled" msgid="8017887509554714950">"અક્ષમ કર્યો"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"આ ઍપને અલાર્મ સેટ કરવા અને સમય પ્રતિ સંવેદનશીલ ક્રિયાઓ શેડ્યૂલ કરવા માટે મંજૂરી આપો. આ ઍપને બૅકગ્રાઉન્ડમાં ચાલવા દે છે, જેને કારણે બૅટરીનો વધુ વપરાશ થઈ શકે છે.\n\nજો આ પરવાનગી બંધ હોય, તો આ ઍપ દ્વારા શેડ્યૂલ કરવામાં આવેલા વર્તમાન અલાર્મ અને સમય આધારિત ઇવેન્ટ કામ કરશે નહીં."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"શેડ્યૂલ, અલાર્મ, રિમાઇન્ડર, ઘડિયાળ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ચાલુ કરો"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ખલેલ પાડશો નહીં ચાલુ કરો"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ક્યારેય નહીં"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"માત્ર પ્રાધાન્યતા"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 75ff92e..fa51dd2 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"लाल रंग पहचान न पाना (लाल-हरा)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"नीला रंग पहचान न पाना (नीला-पीला)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"रंग में सुधार करने की सुविधा"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"आपके डिवाइस पर रंगों के दिखने के तरीके में बदलाव करें. इससे, आपको इन कामों में मदद मिलेगी:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;रंगों को बेहतर तरीके से देखने में&lt;/li&gt; &lt;li&gt;&amp;nbsp;आसानी से फ़ोकस के लिए, रंग हटाने में&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"रंग में सुधार करने की सुविधा का इस्तेमाल, इन मामलों में किया जा सकता है:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;आपको ज़्यादा सटीक तरह से रंग देखने हों&lt;/li&gt; &lt;li&gt;&amp;nbsp;ज़्यादा फ़ोकस करने के लिए, आपको कुछ खास रंग हटाने हों&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"बैटरी करीब <xliff:g id="TIME_REMAINING">%1$s</xliff:g> में खत्म हो जाएगी"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज नहीं हो रही है"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट किया गया, चार्ज नहीं हो रहा है"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"बैटरी चार्ज हो गई"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"बैटरी पूरी चार्ज है"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"इसका नियंत्रण एडमिन के पास है"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"इसे पाबंदी मोड वाली सेटिंग से कंट्रोल किया जाता है"</string>
     <string name="disabled" msgid="8017887509554714950">"बंद किया गया"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"इस ऐप्लिकेशन को अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर सेट करने की अनुमति दें. ऐसा करने से, ऐप्लिकेशन को बैकग्राउंड में चलने की अनुमति मिलती है. इससे बैटरी ज़्यादा खर्च होती है.\n\nअगर आप यह अनुमति नहीं देते हैं, तो इस ऐप्लिकेशन की मदद से सेट किए गए अलार्म और तय समय पर होने वाली कार्रवाइयों के रिमाइंडर काम नहीं करेंगे."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्यूल, अलार्म, रिमाइंडर, घड़ी"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"चालू करें"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'परेशान न करें\' चालू करें"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कभी नहीं"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"सिर्फ़ ज़रूरी"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index d934b46..12d9745 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalija (crveno – zeleno)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalija (plavo – žuto)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Korekcija boja"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Prilagodite način prikazivanja boja na svojem uređaju. To može biti korisno kad želite:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;vidjeti boje točnije&lt;/li&gt; &lt;li&gt;&amp;nbsp;ukloniti boje kako biste se lakše usredotočili.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Korekcija boja može biti korisna kad želite:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;preciznije vidjeti boje&lt;/li&gt; &lt;li&gt;&amp;nbsp;ukloniti boje kako biste se lakše usredotočili.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Još oko <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ne puni se"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, ne puni se"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napunjeno"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Posve puna"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolira administrator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Omogućite toj aplikaciji da postavlja alarme i zakazuje radnje u točno određeno vrijeme. To aplikaciji omogućuje da se izvodi u pozadini, pa je moguća dodatna potrošnja baterije.\n\nAko je to dopuštenje isključeno, postojeći alarmi i događaji zakazani putem te aplikacije neće funkcionirati."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"raspored, alarm, podsjetnik, sat"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Uključi"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Uključite opciju Ne uznemiravaj."</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikada"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Samo prioritetno"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index cd09a85..984df4a 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomália (piros– zöld)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomália (kék–sárga)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Színkorrekció"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Korrigálhatja a színek megjelenítését az eszközén. Ez a következő esetekben lehet hasznos:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ha pontosabb színeket szeretne látni;&lt;/li&gt; &lt;li&gt;&amp;nbsp;ha szeretné eltávolítani a színeket, hogy jobban tudjon koncentrálni.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"A színjavítás funkció például a következő esetekben lehet hasznos:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ha jobban szeretné látni a színeket.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Ha a lényeges részek kiemelése érdekében el szeretne távolítani bizonyos színeket.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Körülbelül <xliff:g id="TIME_REMAINING">%1$s</xliff:g> maradt hátra"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nem tölt"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Csatlakoztatva, nem töltődik"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Feltöltve"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Teljesen feltöltve"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Rendszergazda által irányítva"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Korlátozott beállítás vezérli"</string>
     <string name="disabled" msgid="8017887509554714950">"Letiltva"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lehetővé teszi ennek az alkalmazásnak, hogy ébresztéseket állítson be és időérzékeny feladatokat ütemezzen. Ezzel engedélyezi az alkalmazásnak, hogy a háttérben fusson, ami megnövekedett akkumulátorhasználattal járhat.\n\nHa ez az engedély ki van kapcsolva, az alkalmazás által beállított ébresztések és ütemezett időérzékeny események nem fognak működni."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ütemezés, ébresztés, emlékeztető, óra"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bekapcsolás"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"A Ne zavarjanak mód bekapcsolása"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Soha"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Csak prioritásos"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 0a2c406..1488aea 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Պրոտանոմալիա (կարմիր-կանաչ)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Տրիտանոմալիա (կապույտ-դեղին)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Գունաշտկում"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Կարգավորեք գույների ցուցադրումը ձեր սարքում։ Դա կարող է օգտակար լինել, երբ դուք ուզում եք՝&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ավելի հստակ տեսնել գույները&lt;/li&gt; &lt;li&gt;&amp;nbsp;Հեռացնել գույները՝ կենտրոնանալու համար&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Գունաշտկումը կարող է օգնել, երբ դուք ուզում եք՝&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ավելի հստակ տեսնել գույները&lt;/li&gt; &lt;li&gt;&amp;nbsp;Հեռացնել գույները, որպեսզի կարողանաք կենտրոնանալ&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Լիցքը կբավարարի մոտ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Չի լիցքավորվում"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Միացված է, չի լիցքավորվում"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Լիցքավորված է"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Լրիվ լիցքավորված է"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Կառավարվում է սահմանափակ ռեժիմի կարգավորումներով"</string>
     <string name="disabled" msgid="8017887509554714950">"Կասեցված է"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Թույլատրեք այս հավելվածին դնել զարթուցիչներ և ստեղծել գործողությունների կատարման ժամանակացույցներ։ Այդպես հավելվածը կկարողանա աշխատել ֆոնային ռեժիմում, ինչի արդյունքում ավելի շատ մարտկոցի լիցք կսպառվի։\n\nԵթե այս թույլտվությունն անջատված է, հավելվածի կողմից կարգավորված զարթուցիչները և միջոցառումների ժամանակացույցները չեն աշխատի։"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ժամանակացույց, զարթուցիչ, հիշեցում, ժամացույց"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Միացնել"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Միացրեք «Չանհանգստացնել» ռեժիմը"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Երբեք"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Միայն կարևորները"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>։ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 12e0691..ffa4d4a 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomali (merah-hijau)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomali (biru-kuning)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Koreksi warna"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Sesuaikan cara warna ditampilkan di perangkat Anda. Ini dapat bermanfaat saat Anda ingin:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Melihat warna dengan lebih akurat&lt;/li&gt; &lt;li&gt;&amp;nbsp;Menghapus warna untuk membantu Anda fokus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Koreksi warna dapat berguna jika Anda ingin:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Melihat warna dengan lebih akurat&lt;/li&gt; &lt;li&gt;&amp;nbsp;Menghapus warna untuk membantu Anda fokus&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Sekitar <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Tidak mengisi daya"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Terhubung, tidak mengisi daya"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Terisi"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Baterai Terisi Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Dikontrol oleh admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikontrol oleh Setelan Terbatas"</string>
     <string name="disabled" msgid="8017887509554714950">"Dinonaktifkan"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Izinkan aplikasi ini menyetel alarm dan menjadwalkan tindakan yang sensitif waktu. Hal ini memungkinkan aplikasi berjalan di latar belakang, sehingga mungkin menggunakan lebih banyak daya baterai.\n\nJika izin ini dinonaktifkan, alarm dan acara berbasis waktu yang dijadwalkan oleh aplikasi ini tidak akan berfungsi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadwal, alarm, pengingat, jam"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktifkan"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktifkan mode Jangan Ganggu"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Tidak pernah"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Hanya untuk prioritas"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index bf7021e..b8a75047 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Litblinda (rauðgræn)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Litblinda (blágul)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Litaleiðrétting"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Stilltu litabirtingu í tækinu þínu. Þetta getur gagnast þegar þú vilt:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Sjá liti skýrar&lt;/li&gt; &lt;li&gt;&amp;nbsp;Fjarlægja liti til að fókusa betur&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Litaleiðrétting kemur m.a. að gagni þegar þú vilt:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Sjá liti í aukinni skerpu&lt;/li&gt; &lt;li&gt;&amp;nbsp;Fjarlægja liti til að geta einbeitt þér betur&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Um það bil <xliff:g id="TIME_REMAINING">%1$s</xliff:g> eftir"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ekki í hleðslu"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Tengt, ekki í hleðslu"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Fullhlaðin"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Full hleðsla"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Stjórnað af kerfisstjóra"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Stýrt af takmarkaði stillingu"</string>
     <string name="disabled" msgid="8017887509554714950">"Óvirkt"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Leyfa þessu forriti að stilla vekjara og áætla aðgerðir sem þurfa að eiga sér stað innan ákveðins tímaramma. Þetta leyfir forritinu að keyra í bakgrunninum sem getur notað meiri rafhlöðuorku.\n\nEf slökkt er á þessari heimild munu núverandi vekjarar og tímasettir viðburðir sem þetta forrit stillir ekki virka."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"áætlun, vekjari, áminning, klukka"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Kveikja"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Kveikja á „Ónáðið ekki“"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrei"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Aðeins forgangur"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 5bccf24..1552006 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalìa (rosso-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalìa (blu-giallo)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Correzione del colore"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Regola la modalità di visualizzazione dei colori sul tuo dispositivo. Può essere utile se vuoi:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Vedere i colori con più precisione&lt;/li&gt; &lt;li&gt;&amp;nbsp;Rimuovere colori per mettere a fuoco più facilmente&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"La correzione del colore può essere utile quando vuoi:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Vedere i colori con più precisione&lt;/li&gt; &lt;li&gt;&amp;nbsp;Rimuovere colori per mettere meglio a fuoco&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo rimanente: <xliff:g id="TIME_REMAINING">%1$s</xliff:g> circa"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Non in carica"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Dispositivo connesso, non in carica"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carica"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Batteria completamente carica"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Gestita dall\'amministratore"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gestita tramite impostazioni con restrizioni"</string>
     <string name="disabled" msgid="8017887509554714950">"Disattivato"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Consenti a questa app di impostare sveglie e programmare azioni per le quali il fattore temporale è decisivo. L\'app potrà essere eseguita in background, comportando un consumo maggiore della batteria.\n\nSe questa autorizzazione viene disattivata, le sveglie esistenti e gli eventi basati sull\'orario programmati da questa app non funzioneranno."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programmare, sveglia, promemoria, orologio"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Attiva"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Attiva Non disturbare"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Mai"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Solo con priorità"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index bc17f9e..22810e9 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"פרוטנומליה (אדום-ירוק)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"טריטנומליה (כחול-צהוב)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"תיקון צבע"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"‏ניתן לשנות את האופן שבו צבעים מוצגים במכשיר. שינוי כזה עשוי לעזור:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;להבחין בצבעים בצורה יותר מדויקת&lt;/li&gt; &lt;li&gt;&amp;nbsp;להסיר צבעים מסוימים כדי להתמקד&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"‏תיקון הצבע יכול לעזור אם רוצים:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;לראות צבעים מדויקים יותר&lt;/li&gt; &lt;li&gt;&amp;nbsp;לראות פחות צבעים כדי לשפר את הריכוז&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"הזמן הנותר: בערך <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"לא בטעינה"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"מחובר, לא בטעינה"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"הסוללה טעונה"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"טעונה במלואה"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"נמצא בשליטת מנהל מערכת"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"בשליטה של הגדרה מוגבלת"</string>
     <string name="disabled" msgid="8017887509554714950">"מושבת"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ההרשאה הזו מתירה לאפליקציה להגדיר שעון מעורר ולתזמן פעולות דחופות. האפליקציה תוכל לפעול ברקע ובכך להגביר את צריכת הסוללה.\n\nאם ההרשאה מושבתת, ההתראות והאירועים מבוססי-הזמן שהוגדרו ותוזמנו על ידי האפליקציה לא יפעלו."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"תזמון, שעון מעורר, תזכורת, שעון"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"הפעלה"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"הפעלת מצב נא לא להפריע"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"אף פעם"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"עדיפות בלבד"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index aa274a5..be98ee4 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -408,7 +408,7 @@
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"マニフェストの値に関係なく、すべてのアプリを外部ストレージに書き込めるようになります"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"アクティビティをサイズ変更可能にする"</string>
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"マニフェストの値に関係なく、マルチウィンドウですべてのアクティビティのサイズを変更できるようにします。"</string>
-    <string name="enable_freeform_support" msgid="7599125687603914253">"フリーフォーム ウィンドウの有効化"</string>
+    <string name="enable_freeform_support" msgid="7599125687603914253">"フリーフォーム ウィンドウを有効にする"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"試験運用機能のフリーフォーム ウィンドウのサポートを有効にします。"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"PC バックアップ パスワード"</string>
     <string name="local_backup_password_summary_none" msgid="7646898032616361714">"デスクトップのフルバックアップは現在保護されていません"</string>
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"第一色弱(赤緑)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"第三色弱(青黄)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"色補正"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"デバイスで色をどのように表示するかを調整できます。この設定は以下の場合に役立ちます。&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;色をより正確に表示したい場合&lt;/li&gt; &lt;li&gt;&amp;nbsp;はっきり読み取れるよう色を取り除きたい場合&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"色補正は以下の場合に役立ちます。&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;色をより正確に表示したい場合&lt;/li&gt; &lt;li&gt;&amp;nbsp;はっきり読み取れるよう色を取り除きたい場合&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"残り時間: 約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"充電していません"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"接続済み、充電していません"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"充電が完了しました"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"充電完了"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"管理者により管理されています"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"制限付き設定によって管理されています"</string>
     <string name="disabled" msgid="8017887509554714950">"無効"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"アラームの設定や時間ベースのアクション設定を、このアプリに許可します。これによりアプリがバックグラウンドで実行できるようになるため、バッテリーの使用量が増えることがあります。\n\nこの権限が OFF の場合、このアプリで設定された既存のアラームと時間ベースのイベントは機能しなくなります。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"スケジュール, アラーム, リマインダー, 時計"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ON にする"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"サイレント モードを ON にする"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"なし"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"優先的な通知のみ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 395c7f9..f0006d3 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"პროტოანომალია (წითელი-მწვანე)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ტრიტანომალია (ლურჯი-ყვითელი)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ფერის კორექცია"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"დააკორექტირეთ, როგორ გამოჩნდება ფერები თქვენს მოწყობილობაზე. ეს შეიძლება დაგეხმაროთ, როდესაც გსურთ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ფერების მეტი სიზუსტით დანახვა&lt;/li&gt; &lt;li&gt;&amp;nbsp;ფერების მოცილება, რომ უკეთ კონცენტრირდეთ&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ფერთა კორექცია შეიძლება დაგეხმაროთ, როცა გსურთ:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ფერების მეტი სიზუსტით დანახვა&lt;/li&gt; &lt;li&gt;&amp;nbsp;ფერების მოცილება, რომ უკეთ კონცენტრირდეთ&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"დარჩა დაახლოებით <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"არ იტენება"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"დაკავშირებულია, არ იტენება"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"დატენილია"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"ბოლომდე დატენილი"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"იმართება ადმინისტრატორის მიერ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"კონტროლდება შეზღუდული რეჟიმის პარამეტრით"</string>
     <string name="disabled" msgid="8017887509554714950">"გამორთული"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ნებას რთავს ამ აპს, დააყენოს მაღვიძარები და დაგეგმოს დროზე დამოკიდებული მოქმედებები. ეს საშუალებას აძლევს აპს, იმუშაოს ფონურად, რამაც შეიძლება ბატარეის ხარჯი გაზარდოს.\n\nთუ ეს ნებართვა გამორთულია, ამ აპით დაგეგმილი მაღვიძარები და დროზე დამოკიდებული მოვლენები არ იმუშავებს."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"განრიგი, მაღვიძარა, შეხსენება, საათი"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ჩართვა"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"„არ შემაწუხოთ“ რეჟიმის ჩართვა"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"არასოდეს"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"მხოლოდ პრიორიტეტული"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 74e0957..3724ca5 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалия (қызыл-жасыл)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалия (көк-сары)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Түсті түзету"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Құрылғыңызда түстердің қалай көрсетілетінін реттеңіз. Бұл мыналар үшін пайдалы болуы мүмкін:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;түстерді анығырақ көру&lt;/li&gt; &lt;li&gt;&amp;nbsp;зейініңізді жақсарту үшін түстерді өшіру.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Түсті түзету мына жағдайларда пайдалы болуы мүмкін:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;түстерді анығырақ көру;&lt;/li&gt; &lt;li&gt;&amp;nbsp;зейін қоюға көмектесу үшін түстерді алып тастау.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Шамамен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> қалды"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Зарядталу орындалып жатқан жоқ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Жалғанған, зарядталып жатқан жоқ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Зарядталды"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Толық зарядталды."</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Әкімші басқарады"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Шектелген параметрлер арқылы басқарылады."</string>
     <string name="disabled" msgid="8017887509554714950">"Өшірілген"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бұл қолданбаға оятқыштарды орнатуға және уақытқа негізделген әрекеттерді жоспарлауға рұқсат береді. Мұндайда қолданба фондық режимде жұмыс істейді, сондықтан батарея шығыны артуы мүмкін.\n\nБұл рұқсат өшірулі болса, осы қолданбада жоспарланған ағымдағы оятқыштар мен уақытқа негізделген іс-шаралар жұмыс істемейді."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"кесте, оятқыш, еске салғыш, сағат"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Қосу"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Мазаламау режимін қосу"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ешқашан"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Маңыздылары ғана"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index cf043e7..28211f0 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (ក្រហម​ពណ៌​បៃតង​)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ពណ៌​ខៀវ​-លឿង​)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ការ​កែ​ពណ៌"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"កែតម្រូវ​របៀបដែលពណ៌​បង្ហាញនៅលើ​ឧបករណ៍​របស់អ្នក។ ចំណុចនេះ​អាចមានប្រយោជន៍ នៅពេលដែល​អ្នកចង់៖&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;មើលឃើញពណ៌​កាន់តែត្រឹមត្រូវ&lt;/li&gt; &lt;li&gt;&amp;nbsp;លុបពណ៌ ដើម្បីជួយអ្នក​ក្នុងការផ្ដោតអារម្មណ៍&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ការ​កែតម្រូវ​ពណ៌អាចមានប្រយោជន៍ នៅពេលអ្នកចង់៖&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;មើលពណ៌កាន់តែត្រឹមត្រូវ&lt;/li&gt; &lt;li&gt;&amp;nbsp;លុបពណ៌ចេញ ដើម្បីជួយឱ្យអ្នកផ្ដោតអារម្មណ៍&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"បដិសេធ​ដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"នៅសល់​ប្រហែល <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ទៀត"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"មិនកំពុង​សាក​ថ្ម"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"បានភ្ជាប់ មិនកំពុង​សាកថ្ម"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"បាន​សាក​ថ្មពេញ"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"បានសាក​ថ្មពេញ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"គ្រប់គ្រងដោយការកំណត់ដែលបានរឹតបន្តឹង"</string>
     <string name="disabled" msgid="8017887509554714950">"បិទ"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"អនុញ្ញាតឱ្យ​កម្មវិធីនេះ​កំណត់ម៉ោងរោទ៍ និងកំណត់កាលវិភាគសកម្មភាពដែលតម្រូវឱ្យទាន់ពេលវេលា។ ការធ្វើបែបនេះអនុញ្ញាតឱ្យកម្មវិធីនេះដំណើរការនៅផ្ទៃខាងក្រោយ ដែលអាចប្រើថ្មច្រើនជាងមុន។\n\nប្រសិនបើបិទការអនុញ្ញាតនេះ ម៉ោងរោទ៍ដែលមានស្រាប់ និងព្រឹត្តិការណ៍ផ្អែកលើពេលវេលាដែលកំណត់ដោយកម្មវិធីនេះ​នឹងមិនដំណើរការទេ។"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"កាលវិភាគ ម៉ោងរោទ៍ ការរំលឹក នាឡិកា"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"បើក"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"បើកមុខងារកុំរំខាន"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"កុំឱ្យសោះ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"អាទិភាពប៉ុណ្ណោះ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 708e47f..635c687 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ಪ್ರೊಟನೋಮಲಿ (ಕೆಂಪು-ಹಸಿರು)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ಟ್ರಿಟನೋಮಲಿ (ನೀಲಿ-ಹಳದಿ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ಬಣ್ಣ ತಿದ್ದುಪಡಿ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಬಣ್ಣಗಳು ಹೇಗೆ ಡಿಸ್‌ಪ್ಲೇ ಆಗುತ್ತವೆ ಎಂಬುದನ್ನು ಹೊಂದಿಸಿ. ನೀವು ಬಣ್ಣಗಳನ್ನು ಹೆಚ್ಚು ನಿಖರವಾಗಿ ನೋಡಲು ಬಯಸಿದಾಗ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ಇದು ಸಹಾಯಕವಾಗಿರುತ್ತದೆ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ನಿಮಗೆ ಗಮನಹರಿಸಲು ಸಹಾಯ ಮಾಡಲು ಬಣ್ಣಗಳನ್ನು ತೆಗೆದುಹಾಕಿ&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ನೀವು ಹೆಚ್ಚು ಸ್ಪಷ್ಟವಾದ ಬಣ್ಣಗಳನ್ನು ನೋಡಲು ಬಯಸಿದರೆ :&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp; ಬಣ್ಣದ ತಿದ್ದುಪಡಿಯು ಸಹಾಯಕವಾಗಿರುತ್ತದೆ; ಗಮನವನ್ನು ಕೇಂದ್ರೀಕರಿಸಲು ನಿಮಗೆ ಸಹಾಯ ಮಾಡಲು ಬಣ್ಣಗಳನ್ನು ತೆಗೆದುಹಾಕಿ &lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ಸಮಯ ಬಾಕಿ ಉಳಿದಿದೆ"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ಚಾರ್ಜ್‌ ಆಗುತ್ತಿಲ್ಲ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ಕನೆಕ್ಟ್ ಆಗಿದೆ, ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"ಪೂರ್ಣವಾಗಿ ಚಾರ್ಜ್ ಆಗಿದೆ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ನಿರ್ಬಂಧಿಸಲಾದ ಸೆಟ್ಟಿಂಗ್ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="disabled" msgid="8017887509554714950">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ಅಲಾರಂಗಳನ್ನು ಹೊಂದಿಸಲು ಮತ್ತು ಸಮಯ-ಸೂಕ್ಷ್ಮವಾದ ಕ್ರಿಯೆಗಳನ್ನು ನಿಗದಿಪಡಿಸಲು ಈ ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸಿ. ಇದು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ, ಅದರಿಂದ ಹೆಚ್ಚು ಬ್ಯಾಟರಿ ಬಳಕೆಯಾಗಬಹುದು.\n\nಈ ಅನುಮತಿ ಆಫ್ ಆಗಿದ್ದರೆ, ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅಲಾರಂಗಳು ಮತ್ತು ಈ ಆ್ಯಪ್ ನಿಗದಿಪಡಿಸಿದ ಸಮಯ-ಸೂಕ್ಷ್ಮ ಈವೆಂಟ್‌ಗಳು ಕೆಲಸ ಮಾಡುವುದಿಲ್ಲ."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ವೇಳಾಪಟ್ಟಿ, ಅಲಾರಂ, ರಿಮೈಂಡರ್, ಗಡಿಯಾರ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ಆನ್ ಮಾಡಿ"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ಎಂದೂ ಇಲ್ಲ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"ಆದ್ಯತೆ ಮಾತ್ರ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 31bd310..40acb1a 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"적색약(적녹)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"청색약(청황)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"색상 보정"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"기기에 색상이 표시되는 방식을 조정합니다. 다음과 같은 상황에서 유용합니다.&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;색상을 더욱 정확하게 보고 싶을 때&lt;/li&gt; &lt;li&gt;&amp;nbsp;집중을 위해 색상을 제거하고 싶을 때&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"색상 보정은 다음과 같은 경우에 유용할 수 있습니다.&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;색상을 보다 정확하게 확인하려는 경우&lt;/li&gt; &lt;li&gt;&amp;nbsp;집중에 도움이 되도록 색상을 제거하려는 경우&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>, <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"남은 시간: 약 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"충전 안함"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"연결됨, 충전 중 아님"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"충전됨"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"완전히 충전됨"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"관리자가 제어"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"제한된 설정으로 제어됨"</string>
     <string name="disabled" msgid="8017887509554714950">"사용 안함"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"이 앱이 알람을 설정하고 시간 기반 작업을 예약할 수 있도록 허용합니다. 이렇게 하면 백그라운드에서 앱 실행이 허용되어 배터리 사용량이 증가할 수 있습니다.\n\n이 권한을 사용 중지하면 이 앱에서 예약한 기존의 알람 및 시간 기반 일정이 작동하지 않습니다."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"일정 예약, 알람, 리마인더, 시계"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"사용 설정"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"방해 금지 모드 사용 설정"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"사용 안함"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"중요 알림만 허용"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index ad38373..7a50ece 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалия (кызыл-жашыл)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалия (көк-сары)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Түсүн тууралоо"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Түзмөгүңүздө түстөр кантип көрүнөрүн тууралаңыз. Бул төмөнкү учурларда пайдалуу болот:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Түстөрдү даана көрүү&lt;/li&gt; &lt;li&gt;&amp;nbsp;Ынтаа коюу үчүн түстөрдү өчүрүү&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Төмөнкү учурларда түстөрдү тууралоонун пайдасы тийиши мүмкүн:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Түстөрдү тагыраак көргүңүз келсе&lt;/li&gt; &lt;li&gt;&amp;nbsp;Көңүл топтоо үчүн түстөрдү өчүргүңүз келсе&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Болжол менен <xliff:g id="TIME_REMAINING">%1$s</xliff:g> калды"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Кубат алган жок"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Туташты, кубатталган жок"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Кубатталды"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Толук кубатталды"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Администратор тарабынан көзөмөлдөнөт"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Чектелген параметр аркылуу көзөмөлдөнөт"</string>
     <string name="disabled" msgid="8017887509554714950">"Өчүрүлгөн"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Бул колдонмого ойготкучтарды коюуга жана башка аракеттерди графикке киргизүүгө уруксат бересиз. Ушуну менен колдонмо фондо иштеп, батареяны көбүрөөк сарпташы мүмкүн.\n\nЭгер бул уруксат өчүрүлсө, колдонмодогу ойготкучтар жана графикке киргизилген башка аракеттер иштебейт."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"график, ойготкуч, эстеткич, саат"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Күйгүзүү"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"Тынчымды алба\" режимин күйгүзүү"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Эч качан"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Шашылыш билдирүүлөр гана"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 725a135..2aced9d 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (ສີ​ແດງ​-ສີ​ຂຽວ​)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ສີ​ຟ້າ​-ສີ​ເຫຼືອງ​)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ການ​ປັບ​ແຕ່ງ​ສີ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ປັບແກ້ການສະແດງສີຢູ່ອຸປະກອນຂອງທ່ານ. ນີ້ອາດມີປະໂຫຍດໃນເວລາທີ່ທ່ານຕ້ອງການ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ເບິ່ງເຫັນສີໄດ້ຖືກຕ້ອງຍິ່ງຂຶ້ນ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ລຶບສີອອກເພື່ອຊ່ວຍໃຫ້ທ່ານມີສະມາທິ&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ການແກ້ໄຂສີອາດມີປະໂຫຍດໃນເວລາທີ່ທ່ານຕ້ອງການ:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ເບິ່ງສີໃຫ້ມີຄວາມຖືກຕ້ອງຫຼາຍຂຶ້ນ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ລຶບສີອອກເພື່ອຊ່ວຍທ່ານໂຟກັສ&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"ເຫຼືອອີກປະມານ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ບໍ່ໄດ້ສາກໄຟ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ເຊື່ອມຕໍ່ແລ້ວ, ບໍ່ໄດ້ສາກໄຟ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ສາກເຕັມແລ້ວ"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"ສາກເຕັມແລ້ວ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ຄວບຄຸມໂດຍການຕັ້ງຄ່າທີ່ຈຳກັດໄວ້"</string>
     <string name="disabled" msgid="8017887509554714950">"ປິດການນຳໃຊ້"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ອະນຸຍາດໃຫ້ແອັບນີ້ຕັ້ງໂມງປຸກ ແລະ ກຳນົດເວລາຄຳສັ່ງທີ່ເນັ້ນເລື່ອງເວລາເປັນສຳຄັນໄດ້. ນີ້ຈະເຮັດໃຫ້ແອັບເຮັດວຽກໄດ້ໃນພື້ນຫຼັງ, ເຊິ່ງອາດໃຊ້ແບັດເຕີຣີຫຼາຍຂຶ້ນ.\n\nຫາກປິດການອະນຸຍາດນີ້ໄວ້, ໂມງປຸກທີ່ມີຢູ່ກ່ອນແລ້ວ ແລະ ເຫດການທີ່ອ້າງອີງເວລາທີ່ກຳນົດໄວ້ໂດຍແອັບນີ້ຈະບໍ່ສາມາດເຮັດວຽກໄດ້."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ກຳນົດເວລາ, ໂມງປຸກ, ການແຈ້ງເຕືອນ, ໂມງ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ເປີດ"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"ເປີດໂໝດຫ້າມລົບກວນ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ບໍ່ໃຊ້"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"ສຳຄັນເທົ່ານັ້ນ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 5d34208..6e7daa7 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalija (raudona, žalia)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalija (mėlyna, geltona)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Spalvų taisymas"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Koreguokite, kaip spalvos rodomos jūsų įrenginyje. Tai gali būti naudinga, kai norite:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;matyti tikslesnes spalvas;&lt;/li&gt; &lt;li&gt;&amp;nbsp;pašalinti spalvas, kad būtų lengviau susitelkti.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Spalvų taisymas gali būti naudingas, kai norite:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;aiškiau matyti spalvas;&lt;/li&gt; &lt;li&gt;&amp;nbsp;pašalinti spalvas, kad galėtumėte sutelkti dėmesį.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Liko maždaug <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nekraunama"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Prijungta, neįkraunama"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Įkrauta"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Visiškai įkrautas"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Valdo administratorius"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Valdoma pagal apribotą nustatymą"</string>
     <string name="disabled" msgid="8017887509554714950">"Neleidžiama"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Leisti šiai programai nustatyti signalus ir suplanuoti veiksmus, kuriems svarbus laiko veiksnys. Dėl to programa gali veikti fone ir sunaudoti daugiau akumuliatoriaus energijos.\n\nJei šis leidimas išjungtas, šios programos suplanuoti esami signalai ir laiku pagrįsti įvykiai neveiks."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tvarkaraštis, signalas, priminimas, laikrodis"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Įjungti"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Netrukdymo režimo įjungimas"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Niekada"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Tik prioritetiniai"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index ed4b8e6..0d6651a 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomālija (sarkans/zaļš)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomālija (zils/dzeltens)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Krāsu korekcija"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Pielāgojiet krāsu attēlojumu savā ierīcē. Izmantojot šo iestatījumu, varat:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;skatīt precīzāku krāsu attēlojumu;&lt;/li&gt; &lt;li&gt;&amp;nbsp;noņemt krāsas, lai būtu vieglāk koncentrēties.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Krāsu korekcija var būt noderīga šādiem mērķiem:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;precīzākai krāsu attēlošanai;&lt;/li&gt; &lt;li&gt;&amp;nbsp;krāsu noņemšanai, lai būtu vieglāk koncentrēties.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> — <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Aptuvenais atlikušais laiks: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nenotiek uzlāde"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ierīce pievienota, uzlāde nenotiek"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Uzlādēts"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Pilnībā uzlādēts"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolē administrators"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolē ierobežots iestatījums"</string>
     <string name="disabled" msgid="8017887509554714950">"Atspējots"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Atļaujiet šai lietotnei iestatīt signālus un ieplānot darbības, kas jāveic konkrētā laikā. Tādējādi lietotne darbosies fonā un, iespējams, patērēs vairāk akumulatora enerģijas.\n\nJa šī atļauja nav piešķirta, esošie signāli un šīs lietotnes ieplānotie notikumi, kas jāizpilda konkrētā laikā, nedarbosies."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ieplānot, signāls, atgādinājums, pulkstenis"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ieslēgt"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Režīma “Netraucēt” ieslēgšana"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nekad"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Tikai prioritārie pārtraukumi"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 663f355..8111ec0 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалија (слепило за црвена и зелена)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалија (слепило за сина и жолта)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекција на бои"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Приспособете го приказот на боите на уредот. Ова е корисно кога сакате:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да гледате попрецизни бои&lt;/li&gt; &lt;li&gt;&amp;nbsp;да отстраните бои за подобра концентрација&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекцијата на боите може да биде корисна кога сакате:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да ги гледате боите попрецизно&lt;/li&gt; &lt;li&gt;&amp;nbsp;да ги отстраните боите за да се фокусирате подобро&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Уште околу <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не се полни"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Поврзана, не се полни"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Полна"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Целосно полна"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролирано од администраторот"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролирано со ограничени поставки"</string>
     <string name="disabled" msgid="8017887509554714950">"Оневозможено"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволете ѝ на апликацијава да поставува аларми и да закажува дејства со временски рокови. Ова овозможува апликацијата да работи во заднина и така може повеќе да ја троши батеријата.\n\nАко дозволава е исклучена, нема да функционираат постојните аларми и настаните според време закажани од апликацијава."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"закажување, аларм, потсетник, часовник"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Вклучи"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Исклучување на „Не вознемирувај“"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никогаш"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Само приоритетно"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 7802d65..0ae164b 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"പ്രോട്ടാനോമലി (ചുവപ്പ്-പച്ച)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ട്രിട്ടാനോമലി (നീല-മഞ്ഞ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"നിറം ക്രമീകരിക്കൽ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"നിങ്ങളുടെ ഉപകരണത്തിൽ നിറങ്ങൾ എങ്ങനെ പ്രദർശിപ്പിക്കണമെന്ന് ക്രമീകരിക്കുക. ഇനിപ്പറയുന്ന കാര്യങ്ങൾ ചെയ്യാൻ ആഗ്രഹിക്കുമ്പോൾ ഇത് സഹായകരമാകും:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;നിറങ്ങൾ കൂടുതൽ കൃത്യമായി കാണാൻ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ഫോക്കസ് ചെയ്യാൻ നിങ്ങളെ സഹായിക്കുന്നതിന് നിറങ്ങൾ നീക്കം ചെയ്യാൻ&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ഇനിപ്പറയുന്ന കാര്യങ്ങൾ ചെയ്യാൻ ആഗ്രഹിക്കുമ്പോൾ നിറം ശരിയാക്കൽ സഹായകരമാകും:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;നിറങ്ങൾ കൂടുതൽ കൃത്യമായി കാണാൻ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ഫോക്കസ് ചെയ്യാൻ നിങ്ങളെ സഹായിക്കുന്നതിന് നിറങ്ങൾ നീക്കം ചെയ്യാൻ&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"ഏതാണ്ട് <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"കണക്റ്റ് ചെയ്‌തിരിക്കുന്നു, ചാർജ് ചെയ്യുന്നില്ല"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ചാർജായി"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"പൂർണ്ണമായി ചാർജ് ചെയ്തു"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"അഡ്‌മിൻ നിയന്ത്രിക്കുന്നത്"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"നിയന്ത്രിത ക്രമീകരണം ഉപയോഗിച്ച് നിയന്ത്രിക്കുന്നത്"</string>
     <string name="disabled" msgid="8017887509554714950">"പ്രവർത്തനരഹിതമാക്കി"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"അലാറങ്ങൾ സജ്ജീകരിക്കാനും സമയപ്രാധാന്യമുള്ള പ്രവർത്തനങ്ങൾ ഷെഡ്യൂൾ ചെയ്യാനും ഈ ആപ്പിനെ അനുവദിക്കുക. പശ്ചാത്തലത്തിൽ റൺ ചെയ്യാൻ ഇത് ഈ ആപ്പിന് അനുവാദം നൽകുന്നു, ഇതിന് കൂടുതൽ ബാറ്ററി ഉപയോഗിച്ചേക്കാം.\n\nഈ അനുമതി ഓഫാണെങ്കിൽ, ഈ ആപ്പ് നിലവിൽ ഷെഡ്യൂൾ ചെയ്‌ത അലാറങ്ങളും സമയാധിഷ്‌ഠിത ഇവന്റുകളും പ്രവർത്തിക്കില്ല."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ഷെഡ്യൂൾ, അലാറം, റിമെെൻഡർ, ക്ലോക്ക്"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ഓണാക്കുക"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ശല്യപ്പെടുത്തരുത്\' ഓണാക്കുക"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ഒരിക്കലും വേണ്ട"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"മുൻഗണന മാത്രം"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 7b1605a..7b74da2 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномаль (улаан-ногоон)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомаль (цэнхэр-шар)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Өнгө тохируулах"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Таны төхөөрөмж дээр өнгийг хэрхэн үзүүлэхийг тохируулна уу. Энэ нь танд дараахыг хийхийг хүссэн үед хэрэг болж магадгүй:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Өнгийг илүү оновчтой харах&lt;/li&gt; &lt;li&gt;&amp;nbsp;Танд төвлөрөхөд туслахын тулд өнгийг хасах&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Өнгөний засвар нь таныг дараахыг хийхийг хүсэх үед хэрэгтэй байж болно:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Өнгөнүүдийг илүү нарийвчилж харах&lt;/li&gt; &lt;li&gt;&amp;nbsp;Төвлөрөхийн тулд өнгөнүүдийг хасах&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Ойролцоогоор <xliff:g id="TIME_REMAINING">%1$s</xliff:g> үлдсэн"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Цэнэглэхгүй байна"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Холбогдсон, цэнэглээгүй байна"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Цэнэглэсэн"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Бүрэн цэнэглэсэн"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Админ удирдсан"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Хязгаарлагдсан тохиргоогоор хянадаг"</string>
     <string name="disabled" msgid="8017887509554714950">"Идэвхгүйжүүлсэн"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Энэ аппад сэрүүлэг тавих болон хугацаанд мэдрэг үйлдлийн хуваарь гаргахыг зөвшөөрнө үү. Энэ нь аппад ард ажиллахыг зөвшөөрөх бөгөөд ингэснээр илүү их батарей ашиглаж магадгүй.\n\nХэрэв энэ зөвшөөрөл унтраалттай бол энэ аппын аль хэдийн тавьсан сэрүүлэг болон хуваарь гаргасан хугацаанд мэдрэг үйл явдал ажиллахгүй."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"хуваарь, сэрүүлэг, сануулагч, цаг"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Асаах"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Бүү саад бол горимыг асаах"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Хэзээ ч үгүй"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Зөвхөн чухал зүйлс"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index c7f3a2f..451d834 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"क्षीण रक्तवर्णांधता (लाल-हिरवा)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"रंग दृष्टी कमतरता (निळा-पिवळा)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"रंग सुधारणा"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"तुमच्या डिव्हाइसवर रंग कसे प्रदर्शित केले जातात ते अ‍ॅडजस्ट करा. तुम्हाला :&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;अधिक स्पष्टपणे रंग पाहणे&lt;/li&gt; &lt;li&gt;&amp;nbsp;तुम्हाला फोकस करण्यात मदत करण्यासाठी रंग काढून टाकणे&lt;/li&gt; &lt;/ol&gt;हे करायचे असते तेव्हा हे उपयुक्त असू शकते"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"तुम्हाला पुढील गोष्टी करायच्या असतील, तेव्हा रंग सुधारणेची मदत होऊ शकते:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;रंग आणखी अचूकपणे पाहण्यासाठी&lt;/li&gt; &lt;li&gt;&amp;nbsp;तुम्हाला लक्ष केंद्रित करण्यात मदत करण्याकरिता रंग काढून टाकण्यासाठी&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"अंदाजे <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाकी आहे"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज होत नाही"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट केले, चार्ज होत नाही"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"चार्ज झाली"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"पूर्ण चार्ज झाली"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"प्रशासकाने नियंत्रित केलेले"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबंधित केलेल्या सेटिंग द्वारे नियंत्रित"</string>
     <string name="disabled" msgid="8017887509554714950">"अक्षम"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"या ॲपला अलार्म सेट करण्याची किंवा वेळेनुसार संवेदनशील असलेल्या कृती शेड्युल करण्याची अनुमती द्या. हे ॲपला बॅकग्राउंडमध्ये रन होऊ देते, ज्यामुळे जास्त बॅटरी वापरली जाऊ शकते.\n\nही परवानगी बंद असल्यास, सध्याचे अलार्म आणि या ॲपद्वारे शेड्युल केलेले वेळेवर आधारित इव्हेंट काम करणार नाहीत."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"शेड्युल, अलार्म, रिमाइंडर, घड्याळ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सुरू करा"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"व्यत्यय आणू नका सुरू करा"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कधीही नाही"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"केवळ प्राधान्य"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 8edf739..d3dfb62 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomali (merah-hijau)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomali (biru-kuning)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Pembetulan warna"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Laraskan cara warna dipaparkan pada peranti anda. Ini boleh membantu apabila anda ingin:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Lihat warna dengan lebih tepat&lt;/li&gt; &lt;li&gt;&amp;nbsp;Alih keluar warna untuk membantu anda fokus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Pembetulan warna dapat membantu apabila anda mahu:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Melihat warna dengan lebih tepat&lt;/li&gt; &lt;li&gt;&amp;nbsp;Mengalih keluar warna untuk membantu anda menumpukan perhatian&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Kira-kira <xliff:g id="TIME_REMAINING">%1$s</xliff:g> lagi"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Tidak mengecas"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Bersambung, tidak mengecas"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Sudah dicas"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Dicas Penuh"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Dikawal oleh pentadbir"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikawal oleh Tetapan Terhad"</string>
     <string name="disabled" msgid="8017887509554714950">"Dilumpuhkan"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Benarkan apl ini menetapkan penggera dan menjadualkan tindakan yang sensitif masa. Ini membolehkan apl berjalan di latar, yang mungkin menggunakan lebih banyak bateri.\n\nJika kebenaran ini dimatikan, penggera sedia ada dan acara berdasarkan masa yang dijadualkan oleh apl ini tidak akan berfungsi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"jadual, penggera, peringatan, jam"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Hidupkan"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Hidupkan Jangan Ganggu"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Jangan sekali-kali"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Keutamaan sahaja"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 061760f..cc6269f 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (အနီ-အစိမ်း)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (အပြာ-အဝါ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"အရောင်ပြင်ဆင်မှု"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"သင့်စက်ပစ္စည်းတွင် အရောင်များပြသပုံကို ချိန်ညှိပါ။ ၎င်းက အောက်ပါတို့တွင် အသုံးဝင်နိုင်သည်-&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;အရောင်များကို ပိုမိုတိကျစွာ မြင်လိုခြင်း&lt;/li&gt; &lt;li&gt;&amp;nbsp;သင်အာရုံစိုက်နိုင်ရန် အရောင်များကို ဖယ်ရှားခြင်း&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"အရောင် အမှန်ပြင်ခြင်းသည် အောက်ပါတို့အတွက် အသုံးဝင်နိုင်သည်-&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;အရောင်များကို ပိုမိုမှန်ကန်စွာ ကြည့်ရှုခြင်း&lt;/li&gt; &lt;li&gt;နှင့်nbsp;အာရုံစိုက်နိုင်ရန် အရောင်များ ဖယ်ရှားခြင်း&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ခန့် ကျန်သည်"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"အားသွင်းမနေပါ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ချိတ်ဆက်ထားသည်၊ အားသွင်းမနေပါ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"အားသွင်းပြီးပါပြီ"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"အားအပြည့်သွင်းထားသည်"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ကန့်သတ်ထားသော ဆက်တင်များဖြင့် ထိန်းချုပ်ထားသည်"</string>
     <string name="disabled" msgid="8017887509554714950">"ပိတ်ထားပြီး"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"နှိုးစက်သတ်မှတ်ရန်နှင့် အချိန်တိကျရန် လိုအပ်သည့် လုပ်ဆောင်ချက်များ အစီအစဉ်ဆွဲရန် ဤအက်ပ်ကို ခွင့်ပြုပါ။ ၎င်းက အက်ပ်ကို နောက်ခံတွင် လုပ်ဆောင်ခွင့်ပေးပြီး ဘက်ထရီပိုသုံးနိုင်သည်။\n\nဤခွင့်ပြုချက်ကို ပိတ်ထားပါက ဤအက်ပ်ဖြင့် အစီအစဉ်ဆွဲထားသော လက်ရှိနှိုးစက်နှင့် အချိန်သတ်မှတ်ထားသည့် အစီအစဉ်များ အလုပ်လုပ်တော့မည် မဟုတ်ပါ။"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"အချိန်ဇယား၊ နှိုးစက်၊ သတိပေးချက်၊ နာရီ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ဖွင့်ရန်"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'မနှောင့်ယှက်ရ\' ဖွင့်ခြင်း"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ဘယ်တော့မှ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"ဦးစားပေးများသာ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>။ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index f47fae3..8900fe7 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomali (rød-grønn)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomali (blå-gul)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Fargekorrigering"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Juster hvordan farger vises på enheten. Dette kan være nyttig når du vil&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;se farger mer nøyaktig&lt;/li&gt; &lt;li&gt;&amp;nbsp;fjerne farger for å gjøre det enklere å fokusere&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Fargekorrigering kan være nyttig når du vil&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;se farger mer nøyaktig&lt;/li&gt; &lt;li&gt;&amp;nbsp;fjerne farger for å gjøre det enklere å fokusere&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Omtrent <xliff:g id="TIME_REMAINING">%1$s</xliff:g> igjen"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Lader ikke"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Tilkoblet, lader ikke"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Ladet"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Fulladet"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrollert av administratoren"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollert av en begrenset innstilling"</string>
     <string name="disabled" msgid="8017887509554714950">"Slått av"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Gi denne appen tillatelse til å angi alarmer og planlegge tidssensitive handlinger. Dette gir appen tillatelse til å kjøre i bakgrunnen, noe som kan bruke mer batteri.\n\nHvis denne tillatelsen er av, fungerer ikke eksisterende alarmer og tidsbaserte hendelser som er planlagt av denne appen."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"tidsplan, alarm, påminnelse, klokke"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Slå på"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Slå på Ikke forstyrr"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldri"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Bare prioritet"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 3e19fd6..d0270a9 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"प्रोटानेमली (रातो, हरियो)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ट्रिटानोमेली (निलो-पंहेलो)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"रङ्गको सुधार"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"तपाईंको डिभाइसमा रङ्गहरू कस्ता देखिन्छन् भन्ने कुरा मिलाउनुहोस्। यो सुविधा निम्न अवस्थामा उपयोगी हुन सक्छ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;तपाईं अझ सटीक रूपमा रङ्गहरू देख्न चाहनुहुन्छ भने&lt;/li&gt; &lt;li&gt;&amp;nbsp;तपाईं कुनै कुरामा ध्यान केन्द्रित गर्न रङ्गहरू हटाउन चाहनुहुन्छ भने&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"तपाईं रङ सच्याउने सुविधाका सहायताले निम्न कार्य गर्न सक्नुहुन्छ:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;अझ सटीक तरिकाले रङहरू हेर्न&lt;/li&gt; &lt;li&gt;&amp;nbsp;फोकस गर्नका लागि रङहरू हटाउन&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"लगभग <xliff:g id="TIME_REMAINING">%1$s</xliff:g> बाँकी छ"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"चार्ज भइरहेको छैन"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"कनेक्ट गरिएको छ, चार्ज भइरहेको छैन"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"चार्ज भयो"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"पूर्ण रूपमा चार्ज भएको छ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"प्रशासकद्वारा नियन्त्रित"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबन्धित सेटिङले नियन्त्रण गरेको"</string>
     <string name="disabled" msgid="8017887509554714950">"असक्षम पारियो"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"यो एपलाई अलार्म सेट गर्ने र समयमै पूरा गर्नु पर्ने कारबाहीहरूको रुटिन बनाउने अनुमति दिनुहोस्। यो अनुमति दिइएको छ भने यो एप ब्याकग्राउन्डमा चल्छ र धेरै ब्याट्री खपत हुन्छ।\n\nयो अनुमति दिइएको छैन भने सेट गरिएका अलार्म बज्दैनन् र यो एपले तय गरेका गतिविधि चल्दैनन्।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"समयतालिका, अलार्म, रिमाइन्डर, घडी"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"सक्रिय गर्नुहोस्"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"बाधा नपुऱ्याउनुहोस् नामक मोडलाई सक्रिय गर्नुहोस्"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"कहिल्यै होइन"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"प्राथमिकता दिइएको मात्र"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>। <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 4eb4400..5c19a72 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalie (rood-groen)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalie (blauw-geel)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Kleurcorrectie"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Pas aan hoe kleuren worden getoond op je apparaat. In de volgende gevallen kan dit handig zijn:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Je wilt kleuren duidelijker zien.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Je wilt kleuren verwijderen zodat je je beter kunt focussen.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Kleurcorrectie kan handig zijn in de volgende situaties:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Je wilt kleuren nauwkeuriger zien.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Je wilt kleuren verwijderen zodat je je beter kunt focussen.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Nog ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Wordt niet opgeladen"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Verbonden, wordt niet opgeladen"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Opgeladen"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Volledig opgeladen"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Ingesteld door beheerder"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheerd door beperkte instelling"</string>
     <string name="disabled" msgid="8017887509554714950">"Uitgezet"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Sta toe dat deze app wekkers zet en tijdgevoelige acties plant. De app kan hierdoor op de achtergrond worden uitgevoerd, waardoor je misschien meer batterijlading verbruikt.\n\nAls dit recht uitstaat, werken door deze app geplande bestaande wekkers en tijdgebaseerde afspraken niet."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plannen, schema, wekker, alarm, herinnering, klok"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aanzetten"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zet Niet storen aan."</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nooit"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Alleen prioriteit"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 42b6038..14abf05 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ପ୍ରୋଟାନୋମାଲି (ଲାଲ୍‌-ସବୁଜ)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ନୀଳ-ହଳଦିଆ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ରଙ୍ଗ ସଂଶୋଧନ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ଆପଣଙ୍କ ଡିଭାଇସରେ ରଙ୍ଗଗୁଡ଼ିକ କିପରି ଡିସପ୍ଲେ ହୁଏ ତାହା ଆଡଜଷ୍ଟ କରନ୍ତୁ। ଆପଣ ଏହା କରିବାକୁ ଚାହିଁଲେ ଏହା ଉପଯୋଗୀ ହୋଇପାରେ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ଆହୁରି ସଠିକ୍ ଭାବେ ରଙ୍ଗଗୁଡ଼ିକୁ ଦେଖିବା&lt;/li&gt; &lt;li&gt;&amp;nbsp;ଆପଣଙ୍କୁ ଫୋକସ୍ କରିବାରେ ସାହାଯ୍ୟ କରିବାକୁ ରଙ୍ଗଗୁଡ଼ିକୁ କାଢ଼ିବା&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ଆପଣ ଏସବୁ କରିବାକୁ ଚାହିଁଲେ ରଙ୍ଗ ସଂଶୋଧନ ଉପଯୋଗୀ ହୋଇପାରିବ:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ଆହୁରି ସଠିକ୍ ଭାବେ ରଙ୍ଗଗୁଡ଼ିକ ଦେଖିବା&lt;/li&gt; &lt;li&gt;&amp;nbsp;ଆପଣଙ୍କୁ ଫୋକସ କରିବାରେ ସାହାଯ୍ୟ କରିବା ପାଇଁ ରଙ୍ଗଗୁଡ଼ିକୁ କାଢ଼ିବା&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ଦ୍ୱାରା ଓଭର୍‌ରାଇଡ୍‌ କରାଯାଇଛି"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"ପାଖାପାଖି <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ବଳକା ଅଛି"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ଚାର୍ଜ ହେଉନାହିଁ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ସଂଯୋଗ କରାଯାଇଛି, ଚାର୍ଜ ହେଉନାହିଁ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ଚାର୍ଜ ହୋଇଯାଇଛି"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ଚାର୍ଜ ହୋଇଛି"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ଆଡ୍‌ମିନ୍‌ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ପ୍ରତିବନ୍ଧିତ ସେଟିଂ ଦ୍ୱାରା ନିୟନ୍ତ୍ରଣ କରାଯାଇଛି"</string>
     <string name="disabled" msgid="8017887509554714950">"ଅକ୍ଷମ ହୋଇଛି"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ଏହି ଆପକୁ ଆଲାରାମ୍ ସେଟ୍ କରିବାକୁ ଏବଂ ସମୟ-ସମ୍ବେଦନଶୀଳ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ସିଡୁଲ୍ କରିବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ। ଏହା ଆପକୁ ପୃଷ୍ଠପଟରେ ଚାଲିବାକୁ ଦେଇଥାଏ, ଯାହା ଅଧିକ ବ୍ୟାଟେରୀ ବ୍ୟବହାର କରିପାରେ।\n\nଯଦି ଏହି ଅନୁମତି ବନ୍ଦ ଅଛି, ତେବେ ଏହି ଆପ୍ ଦ୍ୱାରା ସିଡୁଲ୍ କରାଯାଇଥିବା ପୂର୍ବରୁ ଥିବା ଆଲାରାମ୍ ଏବଂ ସମୟ-ଆଧାରିତ ଇଭେଣ୍ଟଗୁଡ଼ିକ କାମ କରିବ ନାହିଁ।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ସିଡୁଲ୍, ଆଲାରାମ୍, ରିମାଇଣ୍ଡର୍, ଘଣ୍ଟା"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ଚାଲୁ କରନ୍ତୁ"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅନ୍ କରନ୍ତୁ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"କଦାପି ନୁହେଁ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"କେବଳ ପ୍ରାଥମିକତା"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index a02cd5b..4671454 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (ਲਾਲ-ਹਰਾ)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (ਨੀਲਾ-ਪੀਲਾ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"ਰੰਗ ਸੁਧਾਈ"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ਆਪਣੇ ਡੀਵਾਈਸ \'ਤੇ ਰੰਗਾਂ ਨੂੰ ਦਿਖਾਉਣ ਦੇ ਤਰੀਕੇ ਨੂੰ ਵਿਵਸਥਿਤ ਕਰੋ। ਇਹ ਉਦੋਂ ਲਾਹੇਵੰਦ ਹੋ ਸਕਦਾ ਹੈ ਜਦੋਂ ਤੁਸੀਂ:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ਰੰਗਾਂ ਨੂੰ ਹੋਰ ਸਟੀਕਤਾ ਨਾਲ ਦੇਖਣਾ ਚਾਹੋ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਨ ਲਈ ਰੰਗਾਂ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੋ&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ਜਦੋਂ ਤੁਸੀਂ ਇਹ ਕੰਮ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ, ਤਾਂ ਰੰਗ ਸੁਧਾਈ ਲਾਹੇਵੰਦ ਹੋ ਸਕਦੀ ਹੈ:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ਰੰਗਾਂ ਨੂੰ ਹੋਰ ਸਹੀ ਢੰਗ ਨਾਲ ਦੇਖਣਾ&lt;/li&gt; &lt;li&gt;&amp;nbsp;ਫੋਕਸ ਕਰਨ ਵਿੱਚ ਮਦਦ ਲਈ ਰੰਗ ਹਟਾਉਣਾ&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"ਲਗਭਗ <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ਬਾਕੀ"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"ਕਨੈਕਟ ਹੈ, ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਹੀ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ਚਾਰਜ ਹੋ ਗਈ"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"ਪੂਰੀ ਚਾਰਜ ਹੋ ਗਈ ਹੈ"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ਪ੍ਰਤਿਬੰਧਿਤ ਸੈਟਿੰਗ ਰਾਹੀਂ ਕੰਟਰੋਲ ਕੀਤੀ ਜਾਂਦੀ ਹੈ"</string>
     <string name="disabled" msgid="8017887509554714950">"ਅਯੋਗ ਬਣਾਇਆ"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"ਇਸ ਐਪ ਨੂੰ ਅਲਾਰਮ ਸੈੱਟ ਕਰਨ ਜਾਂ ਹੋਰ ਸਮਾਂ-ਸੰਵੇਦਨਸ਼ੀਲ ਕਾਰਵਾਈਆਂ ਨੂੰ ਨਿਯਤ ਕਰਨ ਦਿਓ। ਇਸ ਨਾਲ ਐਪ ਨੂੰ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚਲਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਮਿਲਦੀ ਹੈ, ਜਿਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਵਰਤੋਂ ਵੱਧ ਸਕਦੀ ਹੈ।\n\nਜੇ ਇਹ ਇਜਾਜ਼ਤ ਬੰਦ ਹੈ, ਤਾਂ ਮੌਜੂਦਾ ਅਲਾਰਮ ਅਤੇ ਇਸ ਐਪ ਰਾਹੀਂ ਨਿਯਤ ਕੀਤੇ ਸਮਾਂ-ਆਧਾਰਿਤ ਇਵੈਂਟ ਕੰਮ ਨਹੀਂ ਕਰਨਗੇ।"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ਸਮਾਂ-ਸੂਚੀ, ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਘੜੀ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ਚਾਲੂ ਕਰੋ"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ਕਦੇ ਵੀ ਨਹੀਂ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"ਸਿਰਫ਼ ਤਰਜੀਹੀ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>। <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index f69ffb7..073ffbd 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalia (czerwony-zielony)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (niebieski-żółty)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Korekcja kolorów"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Dostosuj sposób wyświetlania kolorów na ekranie urządzenia. Może to być pomocne, gdy chcesz:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;dokładniej widzieć kolory;&lt;/li&gt; &lt;li&gt;&amp;nbsp;usunąć wybrane kolory, aby móc skuteczniej się skupić.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Korekcja kolorów może być pomocna, gdy:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;chcesz wyraźniej widzieć kolory;&lt;/li&gt; &lt;li&gt;&amp;nbsp;chcesz usunąć kolory, aby łatwiej było się skupić.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Jeszcze około <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nie podłączony"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Podłączono, brak ładowania"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Naładowana"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Bateria w pełni naładowana"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolowane przez administratora"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolowane przez ograniczone ustawienia"</string>
     <string name="disabled" msgid="8017887509554714950">"Wyłączone"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Zezwól na ustawianie alarmów i planowanie innych działań, w przypadku których czas jest istotny. Dzięki temu aplikacja będzie mogła działać w tle, co może zwiększyć wykorzystanie baterii.\n\nJeśli nie włączysz tych uprawnień, istniejące alarmy i zaplanowane wydarzenia z tej aplikacji nie będą działać."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"harmonogram, alarm, przypomnienie, zegar"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Włącz"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Włącz tryb Nie przeszkadzać"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nigdy"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Tylko priorytet"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index d856b48..8d93b31 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalia (vermelho-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (azul-amarelo)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Correção de cor"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajuste as cores exibidas no seu dispositivo. Essa opção pode ser útil quando você quer:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ver cores com mais precisão;&lt;/li&gt; &lt;li&gt;&amp;nbsp;remover cores para se concentrar melhor.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"A correção de cor pode ser útil caso você queira:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ver cores mais nítidas;&lt;/li&gt; &lt;li&gt;&amp;nbsp;remover cores para que você possa se concentrar.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está carregando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado sem carregar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Carga completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada pelo admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
     <string name="disabled" msgid="8017887509554714950">"Desativado"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações mais imediatas. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Somente prioridade"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index bc6880f..47a49e7 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalia (vermelho-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (azul-amarelo)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Correção da cor"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajuste a visualização das cores no dispositivo. Isto pode ser útil quando pretender:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver cores com maior precisão&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remover cores para melhorar a sua concentração&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"A correção da cor pode ser útil quando quiser:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ver cores com maior precisão&lt;/li&gt; &lt;li&gt;&amp;nbsp;Remover cores para ajudar a concentrar-se&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Resta(m) cerca de <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está a carregar"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ligado, não está a carregar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Totalmente carregada"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlado pelo gestor"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por uma definição restrita"</string>
     <string name="disabled" msgid="8017887509554714950">"Desativada"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permita que esta app defina alarmes e agende outras ações com base no tempo. Esta ação permite que a app seja executada em segundo plano, o que pode utilizar mais bateria.\n\nSe esta autorização estiver desativada, os alarmes existentes e os eventos com base no tempo agendados por esta app não funcionam."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"agendar, alarme, lembrete, relógio"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o modo Não incomodar"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Apenas prioridade"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index d856b48..8d93b31 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalia (vermelho-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalia (azul-amarelo)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Correção de cor"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajuste as cores exibidas no seu dispositivo. Essa opção pode ser útil quando você quer:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ver cores com mais precisão;&lt;/li&gt; &lt;li&gt;&amp;nbsp;remover cores para se concentrar melhor.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"A correção de cor pode ser útil caso você queira:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;ver cores mais nítidas;&lt;/li&gt; &lt;li&gt;&amp;nbsp;remover cores para que você possa se concentrar.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Tempo restante aproximado: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Não está carregando"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectado sem carregar"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Carregada"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Carga completa"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada pelo admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
     <string name="disabled" msgid="8017887509554714950">"Desativado"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permitir que o app defina alarmes e programe ações mais imediatas. Essa opção autoriza o app a ser executado em segundo plano, o que pode consumir mais bateria.\n\nSe a permissão for desativada, os alarmes e eventos programados pelo app não funcionarão."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programar, alarme, lembrete, relógio"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ativar"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ativar o Não perturbe"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nunca"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Somente prioridade"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 9fb13aa..b110c9c 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalie (roșu-verde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalie (albastru-galben)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Corecția culorii"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ajustați modul în care se afișează culorile pe dispozitiv. Acest lucru poate fi util când doriți să:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;vedeți culorile mai bine;&lt;/li&gt; &lt;li&gt;&amp;nbsp; eliminați culorile pentru a vă ajuta să vă concentrați.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Corecția culorii poate fi utilă dacă doriți:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;să vedeți mai precis culorile;&lt;/li&gt; &lt;li&gt;&amp;nbsp;să eliminați culorile pentru a vă concentra mai bine.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Timp aproximativ rămas: <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nu se încarcă"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Conectat, nu se încarcă"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Încărcată"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Complet încărcată"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlată de administrator"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlată de setarea restricționată"</string>
     <string name="disabled" msgid="8017887509554714950">"Dezactivată"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Permiteți acestei aplicații să stabilească alarme și să planifice acțiuni dependente de timp. Astfel, aplicația poate să ruleze în fundal, fapt care ar putea consuma mai multă baterie.\n\nDacă permisiunea este dezactivată, alarmele și evenimentele dependente de timp planificate de aplicație nu vor funcționa."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"programare, alarmă, memento, ceas"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Activați"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Activați Nu deranja"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Niciodată"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Numai cu prioritate"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index b0b3d14..6a2da7f 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалия (красный/зеленый)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалия (синий/желтый)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Коррекция цвета"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Настройте коррекцию цвета на экране устройства. Вы можете:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;улучшить цветопередачу;&lt;/li&gt; &lt;li&gt;&amp;nbsp;переключиться в черно-белый режим, чтобы вам проще было сфокусироваться.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Коррекция цвета поможет вам:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Добиться нужной цветопередачи.&lt;/li&gt; &lt;li&gt;&amp;nbsp;Убрать цвета, которые мешают сосредоточиться.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"Уровень заряда – <xliff:g id="PERCENTAGE">%1$s</xliff:g>. <xliff:g id="TIME_STRING">%2$s</xliff:g>."</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Заряда хватит примерно на <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не заряжается"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Подключено, не заряжается"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Батарея заряжена"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Батарея заряжена"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролируется администратором"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролируется настройками с ограниченным доступом"</string>
     <string name="disabled" msgid="8017887509554714950">"Отключено"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Если вы разрешите этому приложению устанавливать будильники и планировать на определенное время действия, оно будет работать в фоновом режиме. В таком случае заряд батареи может расходоваться быстрее.\n\nЕсли отключить эту настройку, текущие будильники и созданные приложением мероприятия перестанут запускаться."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"установить, будильник, напоминание, часы"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Включить"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Включите режим \"Не беспокоить\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никогда"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Только важные"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>."</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index a391e71..b75f548 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"වර්ණ දුර්වලතාවය (රතු-කොළ)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"වර්ණ අන්ධතාවය (නිල්-කහ)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"වර්ණ නිවැරදි කිරීම"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ඔබගේ උපාංගයේ වර්ණ සංදර්ශනය වන ආකාරය සීරුමාරු කරන්න. මෙය ඔබට පහත දේවල් සිදු කිරීමට අවශ්‍ය විට ප්‍රයෝජනවත් විය හැකිය:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;වර්ණ වඩාත් නිවැරදිව බැලීම&lt;/li&gt; &lt;li&gt;&amp;nbsp;ඔබට අවධානය යොමු කිරීමට උදව් වීමට වර්ණ ඉවත් කිරීම&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"ඔබට පහත දේවල් සිදු කිරීම අවශ්‍ය විට වර්ණ නිවැරදි කිරීම ප්‍රයෝජනවත් විය හැකිය:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;වඩාත් නිවැරදිව වර්ණ දැකීම&lt;/li&gt; &lt;li&gt;ඔබට අවධානය යොමු කිරීම‍ට උදවු වීමට වර්ණ ඉවත් කිරීම&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> ක් පමණ ඉතිරියි"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ආරෝපණය නොවේ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"සම්බන්ධයි, ආරෝපණය නොවේ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"අරෝපිතයි"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"සම්පූර්ණයෙන් ආරෝපණ වී ඇත"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"පරිපාලක විසින් පාලනය කරන ලදී"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"සීමා කළ සැකසීම මගින් පාලනය වේ"</string>
     <string name="disabled" msgid="8017887509554714950">"අබල කර ඇත"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"එලාම සැකසීමට සහ කාල සංවේදී ක්‍රියා කාලසටහන්ගත කිරීමට මෙම යෙදුමට ඉඩ දෙන්න. මෙය පසුබිමේ ධාවනය වීමට යෙදුමට ඉඩ දෙයි, එය වැඩි බැටරිය වැඩියෙන් භාවිත කළ හැකිය.\n\nමෙම අවසරය ක්‍රියාවිරහිත නම්, මෙම යෙදුම මඟින් සැලසුම් කර ඇති තිබෙන එලාම සහ වේලාව පදනම් කර ගත් සිදුවීම් ක්‍රියා නොකරනු ඇත."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"කාල සටහන, එලාමය, සිහිකැඳවීම, ඔරලෝසුව"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ක්‍රියාත්මක කරන්න"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"බාධා නොකරන්න ක්‍රියාත්මක කරන්න"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"කිසි විටක නැත"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"ප්‍රමුඛතා පමණි"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 1d3320e..83f880d 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomália (červená a zelená)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomália (modrá a žltá)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Úprava farieb"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Upravte si zobrazovanie farieb v zariadení. Môže to byť užitočné, ak chcete:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;presnejšie zobrazovať farby;&lt;/li&gt; &lt;li&gt;&amp;nbsp;odstrániť farby, aby ste sa mohli sústrediť.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Úprava farieb môže byť užitočná, keď chcete:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;zobrazovať farby presnejšie;&lt;/li&gt; &lt;li&gt;&amp;nbsp;odstrániť farby, aby ste sa mohli sústrediť.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Zostáva približne <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nenabíja sa"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Pripojené, nenabíja sa"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Nabité"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Úplne nabitá"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Ovládané správcom"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ovládané obmedzeným nastavením"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktivované"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Povoľte tejto aplikácii nastavovať budíky a plánovať akcie s časovým obmedzením. Aplikácii to umožní pracovať na pozadí, čo môže zvýšiť spotrebu batérie.\n\nAk je toto povolenie vypnuté, súčasné budíky a udalosti s časovým obmedzením naplánované touto aplikáciu nebudú fungovať."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"plán, budík, pripomenutie, hodiny"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Zapnúť"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Zapnite režim bez vyrušení"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikdy"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Iba prioritné"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index b130ab4..6d4078d 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomalija (rdeča in zelena)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomalija (modra in rumena)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Popravljanje barv"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Prilagodite prikaz barv v napravi. To je uporabno, ko želite:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;videti bolj prave barve;&lt;/li&gt; &lt;li&gt;&amp;nbsp;odstraniti barve, da se lažje osredotočite.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Popravljanje barv je lahko koristno, ko želite:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;natančneje videti barve;&lt;/li&gt; &lt;li&gt;&amp;nbsp;odstraniti barve, da se lažje osredotočite.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Še približno <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Se ne polni"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Povezano, se ne polni"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Napolnjeno"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Popolnoma napolnjena"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Nadzira skrbnik"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Pod nadzorom omejene nastavitve"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogočeno"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tej aplikaciji dovolite nastavljanje alarmov in načrtovanje časovno občutljivih dejanj. S tem aplikaciji omogočite izvajanje v ozadju, kar bo morda povečalo porabo energije baterije.\n\nČe je to dovoljenje izklopljeno, obstoječi alarmi in časovno občutljivi dogodki, ki jih nastavi ta aplikacija, ne bodo delovali."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"načrtovanje, urnik, alarm, opomnik, ura"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vklopi"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vklop načina »Ne moti«"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Nikoli"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Samo prednostno"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index d38ab74..ef1e59d 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomali (e kuqe - e gjelbër)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomali (e kaltër - e verdhë)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Korrigjimi i ngjyrës"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Rregullo mënyrën se si shfaqen ngjyrat në pajisjen tënde. Kjo mund të jetë e dobishme kur dëshiron që:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;T\'i shikosh ngjyrat me më shumë saktësi&lt;/li&gt; &lt;li&gt;&amp;nbsp;T\'i heqësh ngjyrat për të të ndihmuar të fokusohesh&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Korrigjimi i ngjyrës mund të jetë i dobishëm kur dëshiron:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Të shohësh ngjyrat më saktë&lt;/li&gt; &lt;li&gt;&amp;nbsp;Të heqësh ngjyrat për të të ndihmuar të fokusohesh&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Rreth <xliff:g id="TIME_REMAINING">%1$s</xliff:g> të mbetura"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nuk po karikohet"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Lidhur, jo në karikim"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Karikuar"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Karikuar plotësisht"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolluar nga administratori"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollohet nga \"Cilësimet e kufizuara\""</string>
     <string name="disabled" msgid="8017887509554714950">"Çaktivizuar"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Lejo që ky aplikacion të caktojë alarmet dhe të planifikojë veprime që kanë një afat të caktuar. Kjo mundëson që aplikacioni të ekzekutohet në sfond, gjë që mund të përdorë më shumë bateri.\n\nNëse kjo leje është caktuar si joaktive, alarmet ekzistuese dhe ngjarjet në bazë kohore të planifikuara nga ky aplikacion nuk do të funksionojnë."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"planifiko, alarm, alarm rikujtues, ora"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivizo"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivizo \"Mos shqetëso\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Asnjëherë"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Vetëm me prioritet"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 03ee28c..333720e 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалија (црвено-зелено)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалија (плаво-жуто)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекција боја"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Прилагодите начин на који се боје приказују на уређају. То може да буде корисно када желите:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да вам се боје тачније приказују&lt;/li&gt; &lt;li&gt;&amp;nbsp;да уклоните боје како бисте се фокусирали&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекција боја може да буде корисна када желите:to:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;да прецизније видите боје&lt;/li&gt; &lt;li&gt;&amp;nbsp;да уклоните боје како бисте се фокусирали&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g>–<xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Преостало је око <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не пуни се"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Повезано, не пуни се"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Напуњено"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Напуњено до краја"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Контролише администратор"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролишу ограничена подешавања"</string>
     <string name="disabled" msgid="8017887509554714950">"Онемогућено"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Омогућите овој апликацији да подешава аларме и заказује временски осетљиве радње. То омогућава да апликација буде покренута у позадини, што може да троши више батерије.\n\nАко је ова дозвола искључена, постојећи аларми и догађаји засновани на времену заказани помоћу ове апликације неће радити."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"заказати, аларм, подсетник, сат"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Укључи"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Укључите режим Не узнемиравај"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Никад"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Само приоритетни прекиди"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 1efae32..2522d7d 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomali (rött-grönt)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomali (blått-gult)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Färgkorrigering"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Ändra hur färger visas på enheten. Det kan vara ett bra hjälpmedel när du vill&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;att färger ska visas mer exakt&lt;/li&gt; &lt;li&gt;&amp;nbsp;ta bort färger för att fokusera bättre.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Färgkorrigering kan vara bra för att&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;urskilja färger bättre&lt;/li&gt; &lt;li&gt;&amp;nbsp;ta bort färger som distraherar&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Cirka <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kvar"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Laddar inte"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ansluten, laddas inte"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Laddat"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Fulladdad"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Strys av administratören"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styrs av spärrad inställning"</string>
     <string name="disabled" msgid="8017887509554714950">"Inaktiverad"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Tillåt att den här appen ställer in alarm och schemalägger tidskänsliga åtgärder. Om du tillåter detta kan appen köras i bakgrunden, vilket kan dra mer batteri.\n\nOm behörigheten är inaktiverad fungerar inte befintliga alarm och tidsbaserade händelser som schemalagts av den här appen."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"schema, alarm, påminnelse, klocka"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aktivera"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Aktivera Stör ej."</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Aldrig"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Endast prioriterade"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index d8d5629..d6deb2b 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (nyekundu-kijani)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (samawati-manjano)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Usahihishaji wa rangi"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Badilisha jinsi rangi zinavyoonekana kwenye kifaa chako. Hali hii inaweza kuwa muhimu unapotaka:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Kuona rangi kwa usahihi zaidi&lt;/li&gt; &lt;li&gt;&amp;nbsp;Kuondoa rangi ili kukusaidia kuwa makini&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Usahihishaji wa rangi unaweza kusaidia wakati unataka:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Kuona rangi kwa usahihi zaidi&lt;/li&gt; &lt;li&gt;&amp;nbsp;Kuondoa rangi ili ikusaidie kumakinika&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Zimesalia takribani <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Haichaji"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Imeunganishwa, haichaji"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Imechajiwa"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Imejaa Chaji"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Imedhibitiwa na msimamizi"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Imedhibitiwa na Mpangilio wenye Mipaka"</string>
     <string name="disabled" msgid="8017887509554714950">"Imezimwa"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Ruhusu programu hii iweke kengele na ratiba za vitendo vingine vinavyotegemea wakati. Hatua hii inairuhusu programu itumike chinichini, hali inayoweza kutumia chaji nyingi ya betri.\n\nIkiwa ruhusa hii itazimwa, kengele zilizopo na ratiba za vitendo vinavyotegemea wakati zilizowekwa na programu hii hazitafanya kazi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ratiba, kengele, kikumbusho, saa"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Washa"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Washa kipengele cha Usinisumbue"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Kamwe usiwashe"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Kipaumbele tu"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 2790ca7..8d5b876 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"நிறம் அடையாளங்காண முடியாமை (சிவப்பு-பச்சை)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"நிறம் அடையாளங்காண முடியாமை (நீலம்-மஞ்சள்)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"வண்ணத்திருத்தம்"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"சாதனத்தில் வண்ணங்கள் காண்பிக்கப்படும் விதத்தைச் சரிசெய்யலாம். இதன் மூலம் நீங்கள் விரும்பும்போதெல்லாம்:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;வண்ணங்களை மிகத் தெளிவாகப் பார்க்கலாம்&lt;/li&gt; &lt;li&gt;&amp;nbsp;கவனம் சிதறாமல் இருக்க வண்ணங்களை நீக்கலாம்&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"நீங்கள் இவற்றைச் செய்ய விரும்பும்போது கலர் கரெக்‌ஷன் உதவும்:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;வண்ணங்களை மிகத் துல்லியமாகப் பார்த்தல்&lt;/li&gt; &lt;li&gt;&amp;nbsp;கவனம் செலுத்துவதற்கு உதவ வண்ணங்களை அகற்றுதல்&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"கிட்டத்தட்ட <xliff:g id="TIME_REMAINING">%1$s</xliff:g> மீதமுள்ளது"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"சார்ஜ் செய்யப்படவில்லை"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"இணைக்கப்பட்டுள்ளது, சார்ஜாகவில்லை"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"சார்ஜாகிவிட்டது"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"முழுவதும் சார்ஜாகிவிட்டது"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"வரையறுக்கப்பட்ட அமைப்பால் கட்டுப்படுத்தப்படுகிறது"</string>
     <string name="disabled" msgid="8017887509554714950">"முடக்கப்பட்டது"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"அலாரங்களை அமைக்கவும் குறிப்பிட்ட கால இடைவெளியில் செயல்களைத் திட்டமிடவும் இந்த ஆப்ஸை அனுமதிக்கும். இது ஆப்ஸ் பின்னணியில் இயங்குவதை அனுமதிக்கும், இதற்காக அதிக பேட்டரியைப் பயன்படுத்தக்கூடும்.\n\nஇந்த அனுமதி முடக்கப்பட்டிருந்தால் இந்த ஆப்ஸ் மூலம் திட்டமிடப்பட்ட ஏற்கெனவே அமைத்த அலாரங்களும் நேர அடிப்படையிலான நிகழ்வுகளும் வேலை செய்யாது."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"திட்டமிடல், அலாரம், நினைவூட்டல், கடிகாரம்"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ஆன் செய்"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"தொந்தரவு செய்ய வேண்டாம் என்பதை ஆன் செய்யும்"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ஒருபோதும் வேண்டாம்"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"முக்கியமானவை மட்டும்"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 988cbd3..1744832 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ప్రొటానోమలీ (ఎరుపు-ఆకుపచ్చ రంగు)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ట్రైటనోమలీ (నీలం-పసుపు రంగు)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"కలర్ సరిచేయడం"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"మీ పరికరంపై రంగులు కనిపించే విధానాన్ని అడ్జస్ట్ చేయండి. ఇటువంటి సందర్భాలలో ఇది మీకు సహాయకరంగా ఉంటుంది:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;మరింత ఖచ్చితంగా రంగులను చూడాలనుకున్నప్పుడు&lt;/li&gt; &lt;li&gt;&amp;nbsp; ఫోకస్ చేయడంలో మీకు సహాయపడటానికి రంగులను తీసివేయాలనుకున్నప్పుడు&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"మీరు కింది వాటిని చేయాలనుకున్నప్పుడు కలర్ కరెక్షన్ సహాయకరంగా ఉంటుంది:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;రంగులను మరింత ఖచ్చితంగా చూడండి&lt;/li&gt; &lt;li&gt;&amp;nbsp;మీరు ఫోకస్ చేయడంలో సహాయపడటానికి రంగులను తీసివేయండి&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> సమయం మిగిలి ఉంది"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ఛార్జ్ కావడం లేదు"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"కనెక్ట్ చేయబడింది, ఛార్జ్ చేయబడలేదు"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ఛార్జ్ చేయబడింది"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"పూర్తి ఛార్జ్ అయింది"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"నిర్వాహకుని ద్వారా నియంత్రించబడింది"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"పరిమితం చేసిన సెట్టింగ్ ద్వారా నియంత్రించబడుతుంది"</string>
     <string name="disabled" msgid="8017887509554714950">"డిజేబుల్ చేయబడింది"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"అలారాలను సెట్ చేయడానికి, సమయ-సునిశిత చర్యలను షెడ్యూల్ చేయడానికి ఈ యాప్‌ను అనుమతించండి. ఇది యాప్‌ను బ్యాక్‌గ్రౌండ్‌లో రన్ అవడానికి అనుమతిస్తుంది, ఇది ఎక్కువ బ్యాటరీని ఉపయోగించవచ్చు.\n\nఈ అనుమతిని ఆఫ్ చేస్తే, ఈ యాప్ ద్వారా షెడ్యూల్ చేసిన ఇప్పటికే ఉన్న అలారాలు, సమయ-ఆధారిత ఈవెంట్‌లు పనిచేయవు."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"షెడ్యూల్, అలారం, రిమైండర్, గడియారం"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"ఆన్ చేయండి"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"అంతరాయం కలిగించవద్దును ఆన్ చేయండి"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ఎప్పటికీ వ‌ద్దు"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"ప్రాధాన్యత మాత్రమే"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 4bc0728..c2c34ed 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"ตาบอดจางสีแดง (สีแดง/เขียว)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"ตาบอดจางสีน้ำเงิน (สีน้ำเงิน/เหลือง)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"การแก้สี"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"ปรับวิธีแสดงสีในอุปกรณ์ การดำเนินการนี้จะเป็นประโยชน์เมื่อคุณต้องการดังนี้&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;เห็นสีได้ถูกต้องยิ่งขึ้น&lt;/li&gt; &lt;li&gt;&amp;nbsp;นำสีออกเพื่อช่วยให้เห็นชัดเจนยิ่งขึ้น&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"การแก้สีจะเป็นประโยชน์เมื่อคุณต้องการดังนี้&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;เห็นสีได้ถูกต้องยิ่งขึ้น&lt;/li&gt; &lt;li&gt;&amp;nbsp;นำสีออกเพื่อช่วยให้เห็นชัดเจนยิ่งขึ้น&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"เหลืออีกประมาณ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"ไม่ได้ชาร์จ"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"เชื่อมต่ออยู่ ไม่ได้ชาร์จ"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"ชาร์จแล้ว"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"ชาร์จเต็มแล้ว"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ควบคุมโดยการตั้งค่าที่จำกัด"</string>
     <string name="disabled" msgid="8017887509554714950">"ปิดอยู่"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"อนุญาตให้แอปนี้ตั้งปลุกและกำหนดเวลาการดำเนินการที่ต้องคำนึงถึงเวลาเป็นสำคัญ สิทธิ์นี้ช่วยให้แอปทำงานในเบื้องหลังได้ จึงอาจทำให้ใช้แบตเตอรี่มากขึ้น\n\nหากปิดใช้สิทธิ์นี้ การปลุกที่มีอยู่และกิจกรรมที่ต้องคำนึงถึงเวลาเป็นสำคัญซึ่งแอปนี้กำหนดเวลาไว้จะไม่ทำงาน"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"กำหนดเวลา การปลุก การช่วยเตือน นาฬิกา"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"เปิด"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"เปิด \"ห้ามรบกวน\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"ไม่เลย"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"เฉพาะเรื่องสำคัญ"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g> <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 5db99d9..a8dcb02 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaly (pula-berde)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaly (asul-dilaw)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Pagtatama ng kulay"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Isaayos kung paano ipinapakita ang mga kulay sa iyong device. Makakatulong ito kapag gusto mong:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Makakita ng mas tumpak na mga kulay&lt;/li&gt; &lt;li&gt;&amp;nbsp;Mag-alis ng mga kulay para matulungan kang mag-focus&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Puwedeng makatulong ang pagtatama ng kulay kapag gusto mong:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Makita nang mas tumpak ang mga kulay&lt;/li&gt; &lt;li&gt;&amp;nbsp;Alisin ang mga kulay para matulungan kang tumuon&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Humigit-kumulang <xliff:g id="TIME_REMAINING">%1$s</xliff:g> ang natitira"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Hindi nagcha-charge"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Nakakonekta, hindi nagcha-charge"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Nasingil"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Puno ang Baterya"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Pinapamahalaan ng admin"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kinokontrol ng Pinaghihigpitang Setting"</string>
     <string name="disabled" msgid="8017887509554714950">"Naka-disable"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Payagan ang app na ito na magtakda ng mga alarm at mag-iskedyul ng mga pagkilos na may limitadong oras. Papayagan nitong tumakbo ang app sa background, na posibleng gumamit ng mas maraming baterya.\n\nKung naka-off ang pahintulot na ito, hindi gagana ang mga kasalukuyang alarm at event na nakabatay sa oras na naiskedyul ng app na ito."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"iskedyul, alarm, paalala, orasan"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"I-on"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"I-on ang Huwag Istorbohin"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hindi kailanman"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Priyoridad lang"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 68fd199..592bbae 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomali (kırmızı-yeşil)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomali (mavi-sarı)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Renk düzeltme"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Renklerin cihazınızda nasıl görüntüleneceğini düzenleyin Bu, şunları yapmak istediğinizde kullanışlı olur:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Renkleri daha doğru görmek&lt;/li&gt; &lt;li&gt;&amp;nbsp;Odaklanmanıza yardımcı olması için renkleri kaldırmak&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Renk düzeltme aşağıdaki durumlarda faydalı olabilir:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Renkleri daha doğru görmek istediğinizde&lt;/li&gt; &lt;li&gt;&amp;nbsp;Odaklanmak için renkleri kaldırmak istediğinizde&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Yaklaşık <xliff:g id="TIME_REMAINING">%1$s</xliff:g> kaldı"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Şarj olmuyor"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Bağlandı, şarj olmuyor"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Şarj oldu"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Pilin Şarjı Tam"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Yönetici tarafından denetleniyor"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kısıtlanmış ayar tarafından kontrol ediliyor"</string>
     <string name="disabled" msgid="8017887509554714950">"Devre dışı"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu uygulamanın alarm kurmasına ve zamana bağlı işlemler programlamasına izin verin. Bu izin, uygulamanın arka planda çalışmasına olanak sağlayarak daha fazla pil harcanmasına neden olabilir.\n\nBu izin verilmezse bu uygulama tarafından programlanmış mevcut alarmlar ve zamana bağlı etkinlikler çalışmaz."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"program, alarm, hatırlatıcı, saat"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Aç"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Rahatsız Etmeyin\'i açın"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hiçbir zaman"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Yalnızca öncelikliler"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 207e890..a219f98 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Протаномалія (червоний – зелений)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Тританомалія (синій – жовтий)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Корекція кольору"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Налаштуйте відтворення кольорів на екрані пристрою. Це може бути корисно, якщо ви хочете:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;точніше відтворювати кольори;&lt;/li&gt; &lt;li&gt;&amp;nbsp;вилучити кольори, щоб зосередитися на головному.&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Корекція кольору корисна, якщо ви хочете:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;точніше бачити кольори;&lt;/li&gt; &lt;li&gt;&amp;nbsp;вилучити кольори, щоб легше зосереджуватися.&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Залишилося приблизно <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Не заряджається"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Підключено, не заряджається"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Заряджено"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Повністю заряджено"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Керується адміністратором"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Керується налаштуваннями з обмеженнями"</string>
     <string name="disabled" msgid="8017887509554714950">"Вимкнено"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Дозволити цьому додатку налаштовувати будильники й створювати розклад дій. Додаток зможе працювати у фоновому режимі й використовувати більше заряду акумулятора.\n\nЯкщо вимкнути такий дозвіл, наявні будильники й дії, створені цим додатком, не працюватимуть."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"запланувати, будильник, нагадування, годинник"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Увімкнути"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Увімкнути режим \"Не турбувати\""</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ніколи"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Лише пріоритетні"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 3163277..3a2d2efb 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"‏Protanomaly (سرخ سبز)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"‏Tritanomaly (نیلا پیلا)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"رنگ کی اصلاح"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"‏آپ کے آلے پر رنگوں کے ڈسپلے ہونے کے طریقے کو ایڈجسٹ کریں۔ یہ درج ذیل کے لیے مددگار ثابت ہوسکتا ہے:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;جب آپ رنگوں کو مزید درست طریقے سے دیکھنا چاہیں&lt;/li&gt; &lt;li&gt;&amp;nbsp;فوکس کرنے میں مدد کرنے کے لئے رنگوں کو ہٹانا چاہیں&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"‏درج ذیل کے لیے رنگ کی اصلاح مددگار ثابت ہو سکتی ہے:‏‎&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;‎جب آپ رنگوں کو مزید درست طریقے سے دیکھنا چاہیں‎&lt;/li&gt; &lt;li&gt;&amp;nbsp;‎فوکس کرنے میں مدد کرنے کے لئے رنگوں کو ہٹانا چاہیں‎&lt;/li&gt; &lt;/ol&gt;‎"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"تقریباً <xliff:g id="TIME_REMAINING">%1$s</xliff:g> باقی ہے"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"چارج نہیں ہو رہا ہے"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"منسلک ہے، چارج نہیں ہو رہی ہے"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"چارج ہو گئی"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"مکمل طور پر چارج ہو گئی"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"کنٹرول کردہ بذریعہ منتظم"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"محدود کردہ ترتیب کے زیر انتظام ہے"</string>
     <string name="disabled" msgid="8017887509554714950">"غیر فعال"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"اس ایپ کو الارمز سیٹ کرنے اور متعین وقت کے لحاظ سے حساس کارروائیوں کو شیڈول کرنے کی اجازت دیں۔ یہ ایپ کو پس منظر میں چلنے دیتا ہے، جس میں زیادہ بیٹری استعمال ہو سکتی ہے۔\n\n اگر یہ اجازت آف ہے تو موجودہ الارمز اور اس ایپ کے ذریعے شیڈول کردہ وقت پر مبنی ایونٹس کام نہیں کریں گے۔"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"شیڈول، الارم، یاد دہانی، گھڑی"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"آن کریں"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"\'ڈسٹرب نہ کریں\' کو آن کریں"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"کبھی نہیں"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"صرف ترجیحی"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 09dcdc0..3e3db69 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Protanomaliya (qizil/yashil)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Tritanomaliya (ko‘k/sariq)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Ranglarni tuzatish"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Qurilmadagi ranglar qanday chiqishini moslash Bu quyidagi amallarni bajarishga yordam beradi:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ranglarni yanada aniq koʻrish&lt;/li&gt; &lt;li&gt;&amp;nbsp;Diqqatni jamlash uchun ranglarni olib tashlash&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Ranglarni tuzatishning foydasi:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Ranglar yanada aniqroq koʻrinadi&lt;/li&gt; &lt;li&gt;&amp;nbsp;Diqqatni qaratish uchun ortiqcha ranglarni olib tashlash imkonini beradi&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> – <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Taxminan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> qoldi"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Quvvat olmayapti"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ulangan, quvvat olmayapti"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Quvvat oldi"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Toʻliq quvvatlandi"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Administrator tomonidan boshqariladi"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Cheklangan sozlama tomonidan boshqariladi"</string>
     <string name="disabled" msgid="8017887509554714950">"Yoqilmagan"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Bu ilovaga signal oʻrnatish va vaqtga asoslangan amallarni rejalashtirishga ruxsat berish. Bunda ilovaga orqa fonda ishlashiga imkon beriladi, shu sababli batareya ortiqcha sarflanishi mumkin.\n\nAgar bu ruxsat oʻchirilsa, ushbu ilova tomonidan rejalashtirilgan mavjud signallar va vaqtga asoslangan tadbirlar ishlamaydi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"reja, signal, eslatma, soat"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Yoqish"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bezovta qilinmasin rejimini yoqing"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Hech qachon"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Faqat muhimlari"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-v31/styles.xml b/packages/SettingsLib/res/values-v31/styles.xml
new file mode 100644
index 0000000..343de2c
--- /dev/null
+++ b/packages/SettingsLib/res/values-v31/styles.xml
@@ -0,0 +1,39 @@
+<?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.
+  -->
+<resources>
+    <style name="SettingsLibTabsTextAppearance" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
+        <item name="android:textSize">16sp</item>
+    </style>
+
+    <style name="SettingsLibTabsStyle" parent="Base.Widget.Design.TabLayout">
+        <item name="android:background">@android:color/transparent</item>
+        <item name="android:layout_width">match_parent</item>
+        <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="tabGravity">fill</item>
+        <item name="tabBackground">@drawable/settingslib_tabs_background</item>
+        <item name="tabIndicator">@drawable/settingslib_tabs_indicator_background</item>
+        <item name="tabIndicatorColor">@color/settingslib_tabs_indicator_color</item>
+        <item name="tabIndicatorFullWidth">true</item>
+        <item name="tabIndicatorGravity">stretch</item>
+        <item name="tabIndicatorAnimationMode">fade</item>
+        <item name="tabIndicatorAnimationDuration">0</item>
+        <item name="tabTextAppearance">@style/SettingsLibTabsTextAppearance</item>
+        <item name="tabTextColor">@color/settingslib_tabs_text_color</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 12af588..2094400 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"Mù màu đỏ không hoàn toàn (đỏ-xanh lục)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"Mù màu (xanh lam-vàng)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Chỉnh màu"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Điều chỉnh cách các màu hiển thị trên thiết bị. Tùy chọn này có thể hữu ích khi bạn muốn:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Xem các màu chính xác hơn&lt;/li&gt; &lt;li&gt;&amp;nbsp;Loại bỏ các màu để giúp bạn tập trung&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Tính năng chỉnh màu có thể giúp ích khi bạn muốn:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;Thấy màu sắc chính xác hơn&lt;/li&gt; &lt;li&gt;&amp;nbsp;Loại bỏ bớt màu để tập trung&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Còn khoảng <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Hiện không sạc"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Đã kết nối nhưng chưa sạc"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Đã sạc"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Đã sạc đầy"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Do quản trị viên kiểm soát"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Do chế độ Cài đặt hạn chế kiểm soát"</string>
     <string name="disabled" msgid="8017887509554714950">"Đã tắt"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Cho phép ứng dụng này đặt chuông báo và lên lịch các hành động cần chính xác về thời gian. Tùy chọn này cho phép ứng dụng chạy ở chế độ nền và có thể làm tiêu hao nhiều pin.\n\nNếu không cấp quyền này, các chuông báo và sự kiện theo thời gian do ứng dụng này lên lịch sẽ không hoạt động."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"lịch biểu, chuông báo, lời nhắc, đồng hồ"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Bật"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Bật chế độ Không làm phiền"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Không bao giờ"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Chỉ cho các mục ưu tiên"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index f6912b1..6d5b8e1 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"红色弱视(红绿不分)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"蓝色弱视(蓝黄不分)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"色彩校正"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"调整设备上的颜色显示方式。此设置对以下情况有帮助:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;您想更准确地看颜色&lt;/li&gt; &lt;li&gt;&amp;nbsp;您想去除一些颜色,以便集中注意力&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"“色彩校正”功能适用于以下情况:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;您想更准确地查看颜色&lt;/li&gt; &lt;li&gt;您想移除颜色以提高专注程度&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"大约还可使用<xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"未在充电"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已连接,未充电"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"已充满电"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"已充满电"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"由管理员控制"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限设置控制"</string>
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允许该应用设置闹钟以及安排在特定时间执行某些操作。这项权限开启后,该应用将在后台运行,可能会消耗更多电池电量。\n\n如果您关闭此权限,该应用设置的现有闹钟将不会响起,而且该应用安排在特定时间执行的现有活动也不会执行。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"设置, 闹钟, 提醒, 时钟, schedule, alarm, reminder, clock"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"开启"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"开启勿扰模式"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"仅限优先事项"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index de28a84..d18c0c9 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"紅色弱視 (紅綠)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"藍色弱視 (藍黃)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"色彩校正"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"調整裝置顯示顏色嘅方式。呢項設定喺以下情況適用:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;想令裝置更加準確咁顯示顏色&lt;/li&gt; &lt;li&gt;&amp;nbsp;移除顏色嚟提高專注力&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"色彩校正喺以下情況下適用:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;睇到更加準確嘅顏色&lt;/li&gt; &lt;li&gt;&amp;nbsp;移除色彩嚟提高專注力&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"還有大約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"非充電中"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已連接,非充電中"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"已充滿電"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"充電完成"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"已由管理員停用"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由「受限設定」控制"</string>
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許此應用程式設定鬧鐘及安排具時效性的操作。這讓應用程式在背景中執行,因此可能會較耗電。\n\n如果關閉此權限,此應用程式將不會在預定時間響起已設定的鬧鐘,亦不會就特定時間的活動傳送通知。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"日程表, 鬧鐘, 提醒, 時鐘"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「請勿騷擾」模式"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"只限優先"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 2580cde..bec3c93 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"紅色弱視 (紅-綠)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"藍色弱視 (藍-黃)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"色彩校正"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"調整裝置顯示顏色的方式。這項設定適用於以下情況:&lt;br/&gt;&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;想讓裝置更準確地顯示顏色&lt;/li&gt; &lt;li&gt;&amp;nbsp;移除顏色以提高專注力&lt;/li&gt; &lt;/ol&gt;"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"「色彩校正」功能適用於以下情況:&lt;br/&gt; &lt;ol&gt; &lt;li&gt;&amp;nbsp;你想讓裝置顯示更準確的色彩&lt;/li&gt; &lt;li&gt;&amp;nbsp;你想移除色彩以提升專注力&lt;/li&gt; &lt;/ol&gt;"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"還能使用約 <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"非充電中"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"已連接,尚未充電"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"充電完成"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"充電完成"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"已由管理員停用"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由限制設定控管"</string>
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"允許這個應用程式設定鬧鐘及安排有時效性的動作。這麼做會讓用程式在背景執行,可能比較耗電。\n\n如果關閉這項權限,這個應用程式設定的現有鬧鐘將不會響起,而且應用程式也無法在預定的時間發出活動提醒。"</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"時間表, 鬧鐘, 提醒, 時鐘"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"開啟"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"開啟「零打擾」模式"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"永不"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"僅限優先通知"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 5250aa5..16b601c 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -456,7 +456,7 @@
     <string name="daltonizer_mode_protanomaly" msgid="7805583306666608440">"I-Protanomaly (bomvu-luhlaza)"</string>
     <string name="daltonizer_mode_tritanomaly" msgid="7135266249220732267">"I-Tritanomaly (luhlaza okwesibhakabhaka-phuzi)"</string>
     <string name="accessibility_display_daltonizer_preference_title" msgid="1810693571332381974">"Ukulungiswa kombala"</string>
-    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="2333641630205214702">"Lungisa indlela imibala eboniswa ngayo kudivayisi yakkho. Lokhu kungasiza uma ufuna ukwenza lokhu:<br/><br/> <ol> <li>&amp;nbsp;Ukubona imibala ngokunembe kakhulu</li> <li>&amp;nbsp;Ukususa imibala ukukusiza ukuthi ugxile</li> </ol>"</string>
+    <string name="accessibility_display_daltonizer_preference_subtitle" msgid="1522101114585266455">"Ukulungiswa kombala kungasiza uma ufuna ukwenza lokhu:<br/><br/> <ol> <li>&amp;nbsp;Ukubona imibala ngokunembe kakhulu</li> <li>&amp;nbsp;Ukususa imibala ukukusiza ukuthi ugxile</li> </ol>"</string>
     <string name="daltonizer_type_overridden" msgid="4509604753672535721">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string>
     <string name="power_remaining_settings_home_page" msgid="4885165789445462557">"<xliff:g id="PERCENTAGE">%1$s</xliff:g> - <xliff:g id="TIME_STRING">%2$s</xliff:g>"</string>
     <string name="power_remaining_duration_only" msgid="8264199158671531431">"Cishe u-<xliff:g id="TIME_REMAINING">%1$s</xliff:g> osele"</string>
@@ -493,6 +493,7 @@
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Ayishaji"</string>
     <string name="battery_info_status_not_charging" msgid="3371084153747234837">"Ixhunyiwe, ayishaji"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Kushajiwe"</string>
+    <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Ishaje Ngokuphelele"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kulawulwa umqondisi"</string>
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kulawulwe Isethingi Elikhawulelwe"</string>
     <string name="disabled" msgid="8017887509554714950">"Akusebenzi"</string>
@@ -538,6 +539,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Vumela le app isethe ama-alamu futhi ushejule izenzo zesikhathi esizwelayo. Lokhu kuvumela i-app iqhubeke ngemuva okungasebenzisa ibhethri lakho eliningi.\n\nUma le mvume ivaliwe, ama-alamu asele nemicimbi esekelwe esikhathini ehlelwe yile app ngeke kusebenze."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ishejuli, i-alamu, isikhumbuzi, iwashi"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Vula"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Vula ukungaphazamisi"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Soze"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Okubalulekile kuphela"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
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 014a033..e524405 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1311,8 +1311,8 @@
 
     <!--  Do not disturb: Label for button in enable zen dialog that will turn on zen mode. [CHAR LIMIT=30] -->
     <string name="zen_mode_enable_dialog_turn_on">Turn on</string>
-    <!-- Priority mode: Title for the Priority mode dialog to turn on Priority mode. [CHAR LIMIT=50]-->
-    <string name="zen_mode_settings_turn_on_dialog_title" translatable="false">Turn on Priority mode</string>
+    <!-- Do not disturb: Title for the Do not Disturb dialog to turn on Do not disturb. [CHAR LIMIT=50]-->
+    <string name="zen_mode_settings_turn_on_dialog_title">Turn on Do Not Disturb</string>
     <!-- Sound: Summary for the Do not Disturb option when there is no automatic rules turned on. [CHAR LIMIT=NONE]-->
     <string name="zen_mode_settings_summary_off">Never</string>
     <!--[CHAR LIMIT=40] Zen Interruption level: Priority.  -->
@@ -1426,8 +1426,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>
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/devicestate/DeviceStateRotationLockSettingsManager.java b/packages/SettingsLib/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManager.java
index 961fab3..4ed7e19 100644
--- a/packages/SettingsLib/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManager.java
@@ -22,6 +22,7 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.Handler;
 import android.os.Looper;
@@ -34,7 +35,10 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.ArrayList;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -48,13 +52,14 @@
 
     private static DeviceStateRotationLockSettingsManager sSingleton;
 
-    private final String[] mDeviceStateRotationLockDefaults;
     private final Handler mMainHandler = new Handler(Looper.getMainLooper());
     private final Set<DeviceStateRotationLockSettingsListener> mListeners = new HashSet<>();
     private final SecureSettings mSecureSettings;
+    private String[] mDeviceStateRotationLockDefaults;
     private SparseIntArray mDeviceStateRotationLockSettings;
     private SparseIntArray mDeviceStateRotationLockFallbackSettings;
     private String mLastSettingValue;
+    private List<SettableDeviceState> mSettableDeviceStates;
 
     @VisibleForTesting
     DeviceStateRotationLockSettingsManager(Context context, SecureSettings secureSettings) {
@@ -79,6 +84,12 @@
         return sSingleton;
     }
 
+    /** Resets the singleton instance of this class. Only used for testing. */
+    @VisibleForTesting
+    public static synchronized void resetInstance() {
+        sSingleton = null;
+    }
+
     /** Returns true if device-state based rotation lock settings are enabled. */
     public static boolean isDeviceStateRotationLockEnabled(Context context) {
         return context.getResources()
@@ -186,6 +197,12 @@
         return true;
     }
 
+    /** Returns a list of device states and their respective auto-rotation setting availability. */
+    public List<SettableDeviceState> getSettableDeviceStates() {
+        // Returning a copy to make sure that nothing outside can mutate our internal list.
+        return new ArrayList<>(mSettableDeviceStates);
+    }
+
     private void initializeInMemoryMap() {
         String serializedSetting =
                 mSecureSettings.getStringForUser(
@@ -220,6 +237,17 @@
         }
     }
 
+    /**
+     * Resets the state of the class and saved settings back to the default values provided by the
+     * resources config.
+     */
+    @VisibleForTesting
+    public void resetStateForTesting(Resources resources) {
+        mDeviceStateRotationLockDefaults =
+                resources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults);
+        fallbackOnDefaults();
+    }
+
     private void fallbackOnDefaults() {
         loadDefaults();
         persistSettings();
@@ -259,6 +287,7 @@
     }
 
     private void loadDefaults() {
+        mSettableDeviceStates = new ArrayList<>(mDeviceStateRotationLockDefaults.length);
         mDeviceStateRotationLockSettings = new SparseIntArray(
                 mDeviceStateRotationLockDefaults.length);
         mDeviceStateRotationLockFallbackSettings = new SparseIntArray(1);
@@ -279,6 +308,8 @@
                                         + values.length);
                     }
                 }
+                boolean isSettable = rotationLockSetting != DEVICE_STATE_ROTATION_LOCK_IGNORED;
+                mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable));
                 mDeviceStateRotationLockSettings.put(deviceState, rotationLockSetting);
             } catch (NumberFormatException e) {
                 Log.wtf(TAG, "Error parsing settings entry. Entry was: " + entry, e);
@@ -308,4 +339,38 @@
         /** Called whenever the settings have changed. */
         void onSettingsChanged();
     }
+
+    /** Represents a device state and whether it has an auto-rotation setting. */
+    public static class SettableDeviceState {
+        private final int mDeviceState;
+        private final boolean mIsSettable;
+
+        SettableDeviceState(int deviceState, boolean isSettable) {
+            mDeviceState = deviceState;
+            mIsSettable = isSettable;
+        }
+
+        /** Returns the device state associated with this object. */
+        public int getDeviceState() {
+            return mDeviceState;
+        }
+
+        /** Returns whether there is an auto-rotation setting for this device state. */
+        public boolean isSettable() {
+            return mIsSettable;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof SettableDeviceState)) return false;
+            SettableDeviceState that = (SettableDeviceState) o;
+            return mDeviceState == that.mDeviceState && mIsSettable == that.mIsSettable;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mDeviceState, mIsSettable);
+        }
+    }
 }
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/license/LicenseHtmlGeneratorFromXml.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
index 2c2be03..c7eb682 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
@@ -70,7 +70,7 @@
             + "</style>\n"
             + "</head>"
             + "<body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">\n"
-            + "<div class=\"toc\">\n";
+            + "<div class=\"toc\">";
     private static final String LIBRARY_HEAD_STRING =
             "<strong>Libraries</strong>\n<ul class=\"libraries\">";
     private static final String LIBRARY_TAIL_STRING = "</ul>\n<strong>Files</strong>";
@@ -324,6 +324,8 @@
             writer.println(LIBRARY_TAIL_STRING);
         }
 
+        writer.println(FILES_HEAD_STRING);
+
         // Prints all the file list with a link to its license file content.
         for (String fileName : fileNameList) {
             for (Map.Entry<String, Set<String>> libToContentId :
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 7e47f45..9ca431d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -15,13 +15,13 @@
  */
 package com.android.settingslib.media;
 
+import static android.media.MediaRoute2Info.TYPE_BLE_HEADSET;
 import static android.media.MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
 import static android.media.MediaRoute2Info.TYPE_BUILTIN_SPEAKER;
 import static android.media.MediaRoute2Info.TYPE_DOCK;
 import static android.media.MediaRoute2Info.TYPE_GROUP;
 import static android.media.MediaRoute2Info.TYPE_HDMI;
 import static android.media.MediaRoute2Info.TYPE_HEARING_AID;
-import static android.media.MediaRoute2Info.TYPE_BLE_HEADSET;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_SPEAKER;
 import static android.media.MediaRoute2Info.TYPE_REMOTE_TV;
 import static android.media.MediaRoute2Info.TYPE_UNKNOWN;
@@ -163,6 +163,31 @@
         return sessionInfos.get(sessionInfos.size() - 1);
     }
 
+    boolean isRoutingSessionAvailableForVolumeControl() {
+        if (mVolumeAdjustmentForRemoteGroupSessions) {
+            return true;
+        }
+        List<RoutingSessionInfo> sessions =
+                mRouterManager.getRoutingSessions(mPackageName);
+        boolean foundNonSystemSession = false;
+        boolean isGroup = false;
+        for (RoutingSessionInfo session : sessions) {
+            if (!session.isSystemSession()) {
+                foundNonSystemSession = true;
+                int selectedRouteCount = session.getSelectedRoutes().size();
+                if (selectedRouteCount > 1) {
+                    isGroup = true;
+                    break;
+                }
+            }
+        }
+        if (!foundNonSystemSession) {
+            Log.d(TAG, "No routing session for " + mPackageName);
+            return false;
+        }
+        return !isGroup;
+    }
+
     /**
      * Remove a {@code device} from current media.
      *
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index 31d5921..5520ea4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -37,9 +37,9 @@
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LeAudioProfile;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfile;
-import com.android.settingslib.bluetooth.LeAudioProfile;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -198,6 +198,14 @@
     }
 
     /**
+     * Returns if the media session is available for volume control.
+     * @return True if this media session is available for colume control, false otherwise.
+     */
+    public boolean isMediaSessionAvailableForVolumeControl() {
+        return mInfoMediaManager.isRoutingSessionAvailableForVolumeControl();
+    }
+
+    /**
      * Start scan connected MediaDevice
      */
     public void startScan() {
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/AvatarPhotoController.java b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPhotoController.java
index 61b8911..0cb2c0b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPhotoController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPhotoController.java
@@ -21,7 +21,8 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.database.Cursor;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
@@ -30,15 +31,15 @@
 import android.graphics.RectF;
 import android.media.ExifInterface;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.StrictMode;
-import android.provider.ContactsContract;
 import android.provider.MediaStore;
 import android.util.EventLog;
 import android.util.Log;
 
 import androidx.core.content.FileProvider;
 
+import com.android.settingslib.utils.ThreadUtils;
+
 import libcore.io.Streams;
 
 import java.io.File;
@@ -47,39 +48,64 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.concurrent.ExecutionException;
 
 class AvatarPhotoController {
+
+    interface AvatarUi {
+        boolean isFinishing();
+
+        void returnUriResult(Uri uri);
+
+        void startActivityForResult(Intent intent, int resultCode);
+
+        boolean startSystemActivityForResult(Intent intent, int resultCode);
+
+        int getPhotoSize();
+    }
+
+    interface ContextInjector {
+        File getCacheDir();
+
+        Uri createTempImageUri(File parentDir, String fileName, boolean purge);
+
+        ContentResolver getContentResolver();
+    }
+
     private static final String TAG = "AvatarPhotoController";
 
-    private static final int REQUEST_CODE_CHOOSE_PHOTO = 1001;
-    private static final int REQUEST_CODE_TAKE_PHOTO = 1002;
-    private static final int REQUEST_CODE_CROP_PHOTO = 1003;
-    // in rare cases we get a null Cursor when querying for DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI
-    // so we need a default photo size
-    private static final int DEFAULT_PHOTO_SIZE = 500;
+    static final int REQUEST_CODE_CHOOSE_PHOTO = 1001;
+    static final int REQUEST_CODE_TAKE_PHOTO = 1002;
+    static final int REQUEST_CODE_CROP_PHOTO = 1003;
 
     private static final String IMAGES_DIR = "multi_user";
+    private static final String PRE_CROP_PICTURE_FILE_NAME = "PreCropEditUserPhoto.jpg";
     private static final String CROP_PICTURE_FILE_NAME = "CropEditUserPhoto.jpg";
     private static final String TAKE_PICTURE_FILE_NAME = "TakeEditUserPhoto.jpg";
 
     private final int mPhotoSize;
 
-    private final AvatarPickerActivity mActivity;
-    private final String mFileAuthority;
+    private final AvatarUi mAvatarUi;
+    private final ContextInjector mContextInjector;
 
     private final File mImagesDir;
+    private final Uri mPreCropPictureUri;
     private final Uri mCropPictureUri;
     private final Uri mTakePictureUri;
 
-    AvatarPhotoController(AvatarPickerActivity activity, boolean waiting, String fileAuthority) {
-        mActivity = activity;
-        mFileAuthority = fileAuthority;
+    AvatarPhotoController(AvatarUi avatarUi, ContextInjector contextInjector, boolean waiting) {
+        mAvatarUi = avatarUi;
+        mContextInjector = contextInjector;
 
-        mImagesDir = new File(activity.getCacheDir(), IMAGES_DIR);
+        mImagesDir = new File(mContextInjector.getCacheDir(), IMAGES_DIR);
         mImagesDir.mkdir();
-        mCropPictureUri = createTempImageUri(activity, CROP_PICTURE_FILE_NAME, !waiting);
-        mTakePictureUri = createTempImageUri(activity, TAKE_PICTURE_FILE_NAME, !waiting);
-        mPhotoSize = getPhotoSize(activity);
+        mPreCropPictureUri = mContextInjector
+                .createTempImageUri(mImagesDir, PRE_CROP_PICTURE_FILE_NAME, !waiting);
+        mCropPictureUri =
+                mContextInjector.createTempImageUri(mImagesDir, CROP_PICTURE_FILE_NAME, !waiting);
+        mTakePictureUri =
+                mContextInjector.createTempImageUri(mImagesDir, TAKE_PICTURE_FILE_NAME, !waiting);
+        mPhotoSize = mAvatarUi.getPhotoSize();
     }
 
     /**
@@ -102,16 +128,12 @@
 
         switch (requestCode) {
             case REQUEST_CODE_CROP_PHOTO:
-                mActivity.returnUriResult(pictureUri);
+                mAvatarUi.returnUriResult(pictureUri);
                 return true;
             case REQUEST_CODE_TAKE_PHOTO:
             case REQUEST_CODE_CHOOSE_PHOTO:
                 if (mTakePictureUri.equals(pictureUri)) {
-                    if (PhotoCapabilityUtils.canCropPhoto(mActivity)) {
-                        cropPhoto();
-                    } else {
-                        onPhotoNotCropped(pictureUri);
-                    }
+                    cropPhoto(pictureUri);
                 } else {
                     copyAndCropPhoto(pictureUri);
                 }
@@ -123,55 +145,52 @@
     void takePhoto() {
         Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE);
         appendOutputExtra(intent, mTakePictureUri);
-        mActivity.startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);
+        mAvatarUi.startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);
     }
 
     void choosePhoto() {
         Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES, null);
         intent.setType("image/*");
-        mActivity.startActivityForResult(intent, REQUEST_CODE_CHOOSE_PHOTO);
+        mAvatarUi.startActivityForResult(intent, REQUEST_CODE_CHOOSE_PHOTO);
     }
 
     private void copyAndCropPhoto(final Uri pictureUri) {
-        // TODO: Replace AsyncTask
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                final ContentResolver cr = mActivity.getContentResolver();
+        try {
+            ThreadUtils.postOnBackgroundThread(() -> {
+                final ContentResolver cr = mContextInjector.getContentResolver();
                 try (InputStream in = cr.openInputStream(pictureUri);
-                     OutputStream out = cr.openOutputStream(mTakePictureUri)) {
+                        OutputStream out = cr.openOutputStream(mPreCropPictureUri)) {
                     Streams.copy(in, out);
                 } catch (IOException e) {
                     Log.w(TAG, "Failed to copy photo", e);
+                    return;
                 }
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(Void result) {
-                if (!mActivity.isFinishing() && !mActivity.isDestroyed()) {
-                    cropPhoto();
-                }
-            }
-        }.execute();
+                ThreadUtils.postOnMainThread(() -> {
+                    if (!mAvatarUi.isFinishing()) {
+                        cropPhoto(mPreCropPictureUri);
+                    }
+                });
+            }).get();
+        } catch (InterruptedException | ExecutionException e) {
+            Log.e(TAG, "Error performing copy-and-crop", e);
+        }
     }
 
-    private void cropPhoto() {
+    private void cropPhoto(final Uri pictureUri) {
         // TODO: Use a public intent, when there is one.
         Intent intent = new Intent("com.android.camera.action.CROP");
-        intent.setDataAndType(mTakePictureUri, "image/*");
+        intent.setDataAndType(pictureUri, "image/*");
         appendOutputExtra(intent, mCropPictureUri);
         appendCropExtras(intent);
-        if (intent.resolveActivity(mActivity.getPackageManager()) != null) {
-            try {
-                StrictMode.disableDeathOnFileUriExposure();
-                mActivity.startActivityForResult(intent, REQUEST_CODE_CROP_PHOTO);
-            } finally {
-                StrictMode.enableDeathOnFileUriExposure();
+        try {
+            StrictMode.disableDeathOnFileUriExposure();
+            if (mAvatarUi.startSystemActivityForResult(intent, REQUEST_CODE_CROP_PHOTO)) {
+                return;
             }
-        } else {
-            onPhotoNotCropped(mTakePictureUri);
+        } finally {
+            StrictMode.enableDeathOnFileUriExposure();
         }
+        onPhotoNotCropped(pictureUri);
     }
 
     private void appendOutputExtra(Intent intent, Uri pictureUri) {
@@ -192,24 +211,22 @@
     }
 
     private void onPhotoNotCropped(final Uri data) {
-        // TODO: Replace AsyncTask to avoid possible memory leaks and handle configuration change
-        new AsyncTask<Void, Void, Bitmap>() {
-            @Override
-            protected Bitmap doInBackground(Void... params) {
+        try {
+            ThreadUtils.postOnBackgroundThread(() -> {
                 // Scale and crop to a square aspect ratio
                 Bitmap croppedImage = Bitmap.createBitmap(mPhotoSize, mPhotoSize,
                         Bitmap.Config.ARGB_8888);
                 Canvas canvas = new Canvas(croppedImage);
                 Bitmap fullImage;
                 try {
-                    InputStream imageStream = mActivity.getContentResolver()
+                    InputStream imageStream = mContextInjector.getContentResolver()
                             .openInputStream(data);
                     fullImage = BitmapFactory.decodeStream(imageStream);
                 } catch (FileNotFoundException fe) {
-                    return null;
+                    return;
                 }
                 if (fullImage != null) {
-                    int rotation = getRotation(mActivity, data);
+                    int rotation = getRotation(data);
                     final int squareSize = Math.min(fullImage.getWidth(),
                             fullImage.getHeight());
                     final int left = (fullImage.getWidth() - squareSize) / 2;
@@ -222,29 +239,27 @@
                     matrix.setRectToRect(rectSource, rectDest, Matrix.ScaleToFit.CENTER);
                     matrix.postRotate(rotation, mPhotoSize / 2f, mPhotoSize / 2f);
                     canvas.drawBitmap(fullImage, matrix, new Paint());
-                    return croppedImage;
-                } else {
-                    // Bah! Got nothin.
-                    return null;
-                }
-            }
+                    saveBitmapToFile(croppedImage, new File(mImagesDir, CROP_PICTURE_FILE_NAME));
 
-            @Override
-            protected void onPostExecute(Bitmap bitmap) {
-                saveBitmapToFile(bitmap, new File(mImagesDir, CROP_PICTURE_FILE_NAME));
-                mActivity.returnUriResult(mCropPictureUri);
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
+                    ThreadUtils.postOnMainThread(() -> {
+                        mAvatarUi.returnUriResult(mCropPictureUri);
+                    });
+                }
+            }).get();
+        } catch (InterruptedException | ExecutionException e) {
+            Log.e(TAG, "Error performing internal crop", e);
+        }
     }
 
     /**
      * Reads the image's exif data and determines the rotation degree needed to display the image
      * in portrait mode.
      */
-    private int getRotation(Context context, Uri selectedImage) {
+    private int getRotation(Uri selectedImage) {
         int rotation = -1;
         try {
-            InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
+            InputStream imageStream =
+                    mContextInjector.getContentResolver().openInputStream(selectedImage);
             ExifInterface exif = new ExifInterface(imageStream);
             rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
         } catch (IOException exception) {
@@ -274,24 +289,74 @@
         }
     }
 
-    private static int getPhotoSize(Context context) {
-        try (Cursor cursor = context.getContentResolver().query(
-                ContactsContract.DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
-                new String[]{ContactsContract.DisplayPhoto.DISPLAY_MAX_DIM}, null, null, null)) {
-            if (cursor != null) {
-                cursor.moveToFirst();
-                return cursor.getInt(0);
-            } else {
-                return DEFAULT_PHOTO_SIZE;
+    static class AvatarUiImpl implements AvatarUi {
+        private final AvatarPickerActivity mActivity;
+
+        AvatarUiImpl(AvatarPickerActivity activity) {
+            mActivity = activity;
+        }
+
+        @Override
+        public boolean isFinishing() {
+            return mActivity.isFinishing() || mActivity.isDestroyed();
+        }
+
+        @Override
+        public void returnUriResult(Uri uri) {
+            mActivity.returnUriResult(uri);
+        }
+
+        @Override
+        public void startActivityForResult(Intent intent, int resultCode) {
+            mActivity.startActivityForResult(intent, resultCode);
+        }
+
+        @Override
+        public boolean startSystemActivityForResult(Intent intent, int code) {
+            ActivityInfo info = intent.resolveActivityInfo(mActivity.getPackageManager(),
+                    PackageManager.MATCH_SYSTEM_ONLY);
+            if (info == null) {
+                Log.w(TAG, "No system package activity could be found for code " + code);
+                return false;
             }
+            intent.setPackage(info.packageName);
+            mActivity.startActivityForResult(intent, code);
+            return true;
+        }
+
+        @Override
+        public int getPhotoSize() {
+            return mActivity.getResources()
+                    .getDimensionPixelSize(com.android.internal.R.dimen.user_icon_size);
         }
     }
 
-    private Uri createTempImageUri(Context context, String fileName, boolean purge) {
-        final File fullPath = new File(mImagesDir, fileName);
-        if (purge) {
-            fullPath.delete();
+    static class ContextInjectorImpl implements ContextInjector {
+        private final Context mContext;
+        private final String mFileAuthority;
+
+        ContextInjectorImpl(Context context, String fileAuthority) {
+            mContext = context;
+            mFileAuthority = fileAuthority;
         }
-        return FileProvider.getUriForFile(context, mFileAuthority, fullPath);
+
+        @Override
+        public File getCacheDir() {
+            return mContext.getCacheDir();
+        }
+
+        @Override
+        public Uri createTempImageUri(File parentDir, String fileName, boolean purge) {
+            final File fullPath = new File(parentDir, fileName);
+            if (purge) {
+                fullPath.delete();
+            }
+            return FileProvider.getUriForFile(mContext, mFileAuthority, fullPath);
+        }
+
+        @Override
+        public ContentResolver getContentResolver() {
+            return mContext.getContentResolver();
+        }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
index 1e1dfae..75bb70a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
@@ -95,7 +95,9 @@
         restoreState(savedInstanceState);
 
         mAvatarPhotoController = new AvatarPhotoController(
-                this, mWaitingForActivityResult, getFileAuthority());
+                new AvatarPhotoController.AvatarUiImpl(this),
+                new AvatarPhotoController.ContextInjectorImpl(this, getFileAuthority()),
+                mWaitingForActivityResult);
     }
 
     private void setUpButtons() {
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/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 1343895..4332bd2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -30,6 +30,7 @@
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiNetworkScoreCache;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.provider.Settings;
 
@@ -53,20 +54,14 @@
     private final WifiManager mWifiManager;
     private final NetworkScoreManager mNetworkScoreManager;
     private final ConnectivityManager mConnectivityManager;
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
+    private final Handler mHandler;
+    private final Handler mMainThreadHandler;
     private final Set<Integer> mNetworks = new HashSet<>();
     // Save the previous HISTORY_SIZE states for logging.
     private final String[] mHistory = new String[HISTORY_SIZE];
     // Where to copy the next state into.
     private int mHistoryIndex;
-    private final WifiNetworkScoreCache.CacheListener mCacheListener =
-            new WifiNetworkScoreCache.CacheListener(mHandler) {
-                @Override
-                public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) {
-                    updateStatusLabel();
-                    mCallback.run();
-                }
-            };
+    private final WifiNetworkScoreCache.CacheListener mCacheListener;
     private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
             .clearCapabilities()
             .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
@@ -113,7 +108,7 @@
             }
             updateWifiInfo(wifiInfo);
             updateStatusLabel();
-            mCallback.run();
+            mMainThreadHandler.post(() -> postResults());
         }
 
         @Override
@@ -128,7 +123,7 @@
                 mNetworks.remove(network.getNetId());
                 updateWifiInfo(null);
                 updateStatusLabel();
-                mCallback.run();
+                mMainThreadHandler.post(() -> postResults());
             }
         }
     };
@@ -143,7 +138,7 @@
             mDefaultNetwork = network;
             mDefaultNetworkCapabilities = nc;
             updateStatusLabel();
-            mCallback.run();
+            mMainThreadHandler.post(() -> postResults());
         }
         @Override
         public void onLost(Network network) {
@@ -151,7 +146,7 @@
             mDefaultNetwork = null;
             mDefaultNetworkCapabilities = null;
             updateStatusLabel();
-            mCallback.run();
+            mMainThreadHandler.post(() -> postResults());
         }
     };
     private Network mDefaultNetwork = null;
@@ -174,12 +169,35 @@
     public WifiStatusTracker(Context context, WifiManager wifiManager,
             NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager,
             Runnable callback) {
+        this(context, wifiManager, networkScoreManager, connectivityManager, callback, null, null);
+    }
+
+    public WifiStatusTracker(Context context, WifiManager wifiManager,
+            NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager,
+            Runnable callback, Handler foregroundHandler, Handler backgroundHandler) {
         mContext = context;
         mWifiManager = wifiManager;
         mWifiNetworkScoreCache = new WifiNetworkScoreCache(context);
         mNetworkScoreManager = networkScoreManager;
         mConnectivityManager = connectivityManager;
         mCallback = callback;
+        if (backgroundHandler == null) {
+            HandlerThread handlerThread = new HandlerThread("WifiStatusTrackerHandler");
+            handlerThread.start();
+            mHandler = new Handler(handlerThread.getLooper());
+        } else {
+            mHandler = backgroundHandler;
+        }
+        mMainThreadHandler = foregroundHandler == null
+                ? new Handler(Looper.getMainLooper()) : foregroundHandler;
+        mCacheListener =
+                new WifiNetworkScoreCache.CacheListener(mHandler) {
+                    @Override
+                    public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) {
+                        updateStatusLabel();
+                        mMainThreadHandler.post(() -> postResults());
+                    }
+                };
     }
 
     public void setListening(boolean listening) {
@@ -332,7 +350,7 @@
     /** Refresh the status label on Locale changed. */
     public void refreshLocale() {
         updateStatusLabel();
-        mCallback.run();
+        mMainThreadHandler.post(() -> postResults());
     }
 
     private String getValidSsid(WifiInfo info) {
@@ -348,6 +366,10 @@
         mHistoryIndex = (mHistoryIndex + 1) % HISTORY_SIZE;
     }
 
+    private void postResults() {
+        mCallback.run();
+    }
+
     /** Dump function. */
     public void dump(PrintWriter pw) {
         pw.println("  - WiFi Network History ------");
diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml
index da808dd..2a4dfdd 100644
--- a/packages/SettingsLib/tests/integ/AndroidManifest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml
@@ -25,10 +25,19 @@
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
 
-
     <application>
         <uses-library android:name="android.test.runner" />
         <activity android:name=".drawer.SettingsDrawerActivityTest$TestActivity"/>
+
+        <provider
+            android:name="androidx.core.content.FileProvider"
+            android:authorities="com.android.settingslib.test"
+            android:grantUriPermissions="true"
+            android:exported="false">
+            <meta-data
+                android:name="android.support.FILE_PROVIDER_PATHS"
+                android:resource="@xml/file_paths" />
+        </provider>
     </application>
 
     <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
diff --git a/packages/SystemUI/res/values-w650dp-land/dimens.xml b/packages/SettingsLib/tests/integ/res/xml/file_paths.xml
similarity index 69%
copy from packages/SystemUI/res/values-w650dp-land/dimens.xml
copy to packages/SettingsLib/tests/integ/res/xml/file_paths.xml
index 97b6da1..ccd11a4 100644
--- a/packages/SystemUI/res/values-w650dp-land/dimens.xml
+++ b/packages/SettingsLib/tests/integ/res/xml/file_paths.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-  ~ 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,7 +13,8 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<resources>
-    <!-- Standard notification width + gravity -->
-    <dimen name="notification_panel_width">-1px</dimen> <!-- match_parent -->
-</resources>
+
+<paths xmlns:android="http://schemas.android.com/apk/res/android">
+    <!-- Offer access to files under Context.getCacheDir() -->
+    <cache-path name="my_cache" />
+</paths>
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
index 1a45384..81006dd 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
@@ -30,12 +30,17 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.R;
+import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DeviceStateRotationLockSettingsManagerTest {
@@ -94,4 +99,22 @@
 
         assertThat(mNumSettingsChanges).isEqualTo(3);
     }
+
+    @Test
+    public void getSettableDeviceStates_returnsExpectedValuesInOriginalOrder() {
+        when(mMockResources.getStringArray(
+                R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
+                new String[]{"2:2", "4:0", "1:1", "0:0"});
+
+        List<SettableDeviceState> settableDeviceStates =
+                DeviceStateRotationLockSettingsManager.getInstance(
+                        mMockContext).getSettableDeviceStates();
+
+        assertThat(settableDeviceStates).containsExactly(
+                new SettableDeviceState(/* deviceState= */ 2, /* isSettable= */ true),
+                new SettableDeviceState(/* deviceState= */ 4, /* isSettable= */ false),
+                new SettableDeviceState(/* deviceState= */ 1, /* isSettable= */ true),
+                new SettableDeviceState(/* deviceState= */ 0, /* isSettable= */ false)
+        ).inOrder();
+    }
 }
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
new file mode 100644
index 0000000..1d08711
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.users;
+
+import static com.android.settingslib.users.AvatarPhotoController.REQUEST_CODE_CHOOSE_PHOTO;
+import static com.android.settingslib.users.AvatarPhotoController.REQUEST_CODE_CROP_PHOTO;
+import static com.android.settingslib.users.AvatarPhotoController.REQUEST_CODE_TAKE_PHOTO;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.provider.MediaStore;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+@RunWith(AndroidJUnit4.class)
+public class AvatarPhotoControllerTest {
+
+    private static final long TIMEOUT_MILLIS = 5000;
+    private static final int PHOTO_SIZE = 200;
+
+    @Mock AvatarPhotoController.AvatarUi mMockAvatarUi;
+
+    private File mImagesDir;
+    private AvatarPhotoController mController;
+    private Uri mTakePhotoUri = Uri.parse(
+            "content://com.android.settingslib.test/my_cache/multi_user/TakeEditUserPhoto.jpg");
+    private Uri mCropPhotoUri = Uri.parse(
+            "content://com.android.settingslib.test/my_cache/multi_user/CropEditUserPhoto.jpg");
+    private Context mContext = InstrumentationRegistry.getTargetContext();
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockAvatarUi.getPhotoSize()).thenReturn(PHOTO_SIZE);
+        when(mMockAvatarUi.startSystemActivityForResult(any(), anyInt())).thenReturn(true);
+
+        mImagesDir = new File(
+                InstrumentationRegistry.getTargetContext().getCacheDir(), "multi_user");
+        mImagesDir.mkdir();
+
+        AvatarPhotoController.ContextInjector contextInjector =
+                new AvatarPhotoController.ContextInjectorImpl(
+                        InstrumentationRegistry.getTargetContext(), "com.android.settingslib.test");
+        mController = new AvatarPhotoController(mMockAvatarUi, contextInjector, false);
+    }
+
+    @After
+    public void tearDown() {
+        mImagesDir.delete();
+    }
+
+    @Test
+    public void takePhotoHasCorrectIntentAndResultCode() {
+        mController.takePhoto();
+
+        verifyStartActivityForResult(
+                MediaStore.ACTION_IMAGE_CAPTURE_SECURE, REQUEST_CODE_TAKE_PHOTO);
+    }
+
+    @Test
+    public void choosePhotoHasCorrectIntentAndResultCode() {
+        mController.choosePhoto();
+
+        verifyStartActivityForResult(
+                MediaStore.ACTION_PICK_IMAGES, REQUEST_CODE_CHOOSE_PHOTO);
+    }
+
+    @Test
+    public void takePhotoIsFollowedByCrop() throws IOException {
+        new File(mImagesDir, "file.txt").createNewFile();
+
+        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);
+
+        verifyStartSystemActivityForResult(
+                "com.android.camera.action.CROP", REQUEST_CODE_CROP_PHOTO);
+    }
+
+    @Test
+    public void takePhotoIsNotFollowedByCropWhenResultCodeNotOk() throws IOException {
+        new File(mImagesDir, "file.txt").createNewFile();
+
+        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_CANCELED, intent);
+
+        verify(mMockAvatarUi, never()).startActivityForResult(any(), anyInt());
+        verify(mMockAvatarUi, never()).startSystemActivityForResult(any(), anyInt());
+    }
+
+    @Test
+    public void takePhotoIsFollowedByCropWhenTakePhotoUriReturned() throws IOException {
+        new File(mImagesDir, "TakeEditUserPhoto.jpg").createNewFile();
+
+        Intent intent = new Intent();
+        intent.setData(mTakePhotoUri);
+        mController.onActivityResult(
+                REQUEST_CODE_TAKE_PHOTO, Activity.RESULT_OK, intent);
+
+        verifyStartSystemActivityForResult(
+                "com.android.camera.action.CROP", REQUEST_CODE_CROP_PHOTO);
+    }
+
+    @Test
+    public void choosePhotoIsFollowedByCrop() throws IOException {
+        new File(mImagesDir, "file.txt").createNewFile();
+
+        Intent intent = new Intent();
+        intent.setData(Uri.parse(
+                "content://com.android.settingslib.test/my_cache/multi_user/file.txt"));
+        mController.onActivityResult(
+                REQUEST_CODE_CHOOSE_PHOTO, Activity.RESULT_OK, intent);
+
+        verifyStartSystemActivityForResult(
+                "com.android.camera.action.CROP", REQUEST_CODE_CROP_PHOTO);
+    }
+
+    @Test
+    public void choosePhotoIsNotFollowedByCropWhenResultCodeNotOk() throws IOException {
+        new File(mImagesDir, "file.txt").createNewFile();
+
+        Intent intent = new Intent();
+        intent.setData(Uri.parse(
+                "content://com.android.settingslib.test/my_cache/multi_user/file.txt"));
+        mController.onActivityResult(
+                REQUEST_CODE_CHOOSE_PHOTO, Activity.RESULT_CANCELED, intent);
+
+        verify(mMockAvatarUi, never()).startActivityForResult(any(), anyInt());
+        verify(mMockAvatarUi, never()).startSystemActivityForResult(any(), anyInt());
+    }
+
+    @Test
+    public void choosePhotoIsFollowedByCropWhenTakePhotoUriReturned() throws IOException {
+        new File(mImagesDir, "TakeEditUserPhoto.jpg").createNewFile();
+
+        Intent intent = new Intent();
+        intent.setData(mTakePhotoUri);
+        mController.onActivityResult(
+                REQUEST_CODE_CHOOSE_PHOTO, Activity.RESULT_OK, intent);
+
+        verifyStartSystemActivityForResult(
+                "com.android.camera.action.CROP", REQUEST_CODE_CROP_PHOTO);
+    }
+
+    @Test
+    public void cropPhotoResultIsReturnedIfResultOkAndContent() {
+        Intent intent = new Intent();
+        intent.setData(mCropPhotoUri);
+        mController.onActivityResult(REQUEST_CODE_CROP_PHOTO, Activity.RESULT_OK, intent);
+        verify(mMockAvatarUi, timeout(TIMEOUT_MILLIS)).returnUriResult(mCropPhotoUri);
+    }
+
+    @Test
+    public void cropPhotoResultIsNotReturnedIfResultCancel() {
+        Intent intent = new Intent();
+        intent.setData(mCropPhotoUri);
+        mController.onActivityResult(REQUEST_CODE_CROP_PHOTO, Activity.RESULT_CANCELED, intent);
+        verify(mMockAvatarUi, timeout(TIMEOUT_MILLIS).times(0)).returnUriResult(mCropPhotoUri);
+    }
+
+    @Test
+    public void cropPhotoResultIsNotReturnedIfResultNotContent() {
+        Intent intent = new Intent();
+        intent.setData(Uri.parse("file://test"));
+        mController.onActivityResult(REQUEST_CODE_CROP_PHOTO, Activity.RESULT_OK, intent);
+        verify(mMockAvatarUi, timeout(TIMEOUT_MILLIS).times(0)).returnUriResult(mCropPhotoUri);
+    }
+
+    @Test
+    public void cropDoesNotUseTakePhotoUri() throws IOException {
+        new File(mImagesDir, "file.txt").createNewFile();
+
+        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);
+
+        Intent startIntent = verifyStartSystemActivityForResult(
+                "com.android.camera.action.CROP", REQUEST_CODE_CROP_PHOTO);
+        assertThat(startIntent.getData()).isNotEqualTo(mTakePhotoUri);
+    }
+
+    @Test
+    public void internalCropUsedIfNoSystemCropperFound() throws IOException {
+        when(mMockAvatarUi.startSystemActivityForResult(any(), anyInt())).thenReturn(false);
+
+        new File(mImagesDir, "file.txt").createNewFile();
+
+        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);
+
+        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);
+        Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
+        assertThat(bitmap.getWidth()).isEqualTo(PHOTO_SIZE);
+        assertThat(bitmap.getHeight()).isEqualTo(PHOTO_SIZE);
+    }
+
+    private Intent verifyStartActivityForResult(String action, int resultCode) {
+        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockAvatarUi, timeout(TIMEOUT_MILLIS))
+                .startActivityForResult(captor.capture(), eq(resultCode));
+        Intent intent = captor.getValue();
+        assertThat(intent.getAction()).isEqualTo(action);
+        return intent;
+    }
+
+    private Intent verifyStartSystemActivityForResult(String action, int resultCode) {
+        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockAvatarUi, timeout(TIMEOUT_MILLIS))
+                .startSystemActivityForResult(captor.capture(), eq(resultCode));
+        Intent intent = captor.getValue();
+        assertThat(intent.getAction()).isEqualTo(action);
+        return intent;
+    }
+
+    private void saveBitmapToFile(File file) throws IOException {
+        Bitmap bitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
+        OutputStream os = new FileOutputStream(file);
+        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
+        os.flush();
+        os.close();
+    }
+
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java
index 47556da..b3843a8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ActionDisabledLearnMoreButtonLauncherTest.java
@@ -54,7 +54,7 @@
 public final class ActionDisabledLearnMoreButtonLauncherTest {
 
     private static final int CONTEXT_USER_ID = -ENFORCEMENT_ADMIN_USER_ID;
-    private static final UserHandle CONTEXT_USER = UserHandle.of(CONTEXT_USER_ID);
+    private static final UserHandle CONTEXT_USER = new UserHandle(CONTEXT_USER_ID);
 
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java
index 06b6fc8..b2258e1 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminControllerTest.java
@@ -80,8 +80,8 @@
         assertEquals(Settings.ACTION_MANAGE_SUPERVISOR_RESTRICTED_SETTING,
                 intentCaptor.getValue().getAction());
         assertEquals(Settings.SUPERVISOR_VERIFICATION_SETTING_BIOMETRICS,
-                intentCaptor.getValue().getStringExtra(
-                        Settings.EXTRA_SUPERVISOR_RESTRICTED_SETTING_KEY));
+                intentCaptor.getValue().getIntExtra(
+                        Settings.EXTRA_SUPERVISOR_RESTRICTED_SETTING_KEY, -1));
         assertEquals(componentName.getPackageName(), intentCaptor.getValue().getPackage());
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
index 509e12d..bc9bdec 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/enterprise/ManagedDeviceActionDisabledByAdminControllerTest.java
@@ -47,7 +47,7 @@
 @RunWith(RobolectricTestRunner.class)
 public class ManagedDeviceActionDisabledByAdminControllerTest {
 
-    private static UserHandle MANAGED_USER = UserHandle.of(123);
+    private static UserHandle MANAGED_USER = new UserHandle(123);
     private static final String RESTRICTION = UserManager.DISALLOW_ADJUST_VOLUME;
     private static final String EMPTY_URL = "";
     private static final String SUPPORT_TITLE_FOR_RESTRICTION = DISALLOW_ADJUST_VOLUME_TITLE;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
index bf07004..09b0d7f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -36,7 +35,6 @@
 import java.util.Set;
 
 @RunWith(RobolectricTestRunner.class)
-@Ignore
 public class LicenseHtmlGeneratorFromXmlTest {
     private static final String VALID_OLD_XML_STRING =
             "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
@@ -122,7 +120,7 @@
             + "</div><!-- table of contents -->\n"
             + "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n"
             + "<tr id=\"id0\"><td class=\"same-license\">\n"
-            + "<div class=\"label\">Notices for file(s):</div>\n"
+            + "<div class=\"label\"><strong>libA</strong> used by:</div>\n"
             + "<div class=\"file-list\">\n"
             + "/file0 <br/>\n"
             + "/file1 <br/>\n"
@@ -132,7 +130,7 @@
             + "</pre><!-- license-text -->\n"
             + "</td></tr><!-- same-license -->\n"
             + "<tr id=\"id1\"><td class=\"same-license\">\n"
-            + "<div class=\"label\">Notices for file(s):</div>\n"
+            + "<div class=\"label\"><strong>libB</strong> used by:</div>\n"
             + "<div class=\"file-list\">\n"
             + "/file0 <br/>\n"
             + "</div><!-- file-list -->\n"
@@ -160,10 +158,12 @@
         LicenseHtmlGeneratorFromXml.parse(
                 new InputStreamReader(new ByteArrayInputStream(VALID_OLD_XML_STRING.getBytes())),
                 fileNameToLibraryToContentIdMap, contentIdToFileContentMap);
-        assertThat(fileNameToLibraryToContentIdMap.size()).isEqualTo(1);
-        assertThat(fileNameToLibraryToContentIdMap.get("").size()).isEqualTo(2);
-        assertThat(fileNameToLibraryToContentIdMap.get("").get("/file0")).containsExactly("0");
-        assertThat(fileNameToLibraryToContentIdMap.get("").get("/file1")).containsExactly("0");
+
+        assertThat(fileNameToLibraryToContentIdMap).hasSize(2);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0").get(null)).containsExactly("0");
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1").get(null)).containsExactly("0");
         assertThat(contentIdToFileContentMap.size()).isEqualTo(1);
         assertThat(contentIdToFileContentMap.get("0")).isEqualTo("license content #0");
     }
@@ -176,11 +176,12 @@
         LicenseHtmlGeneratorFromXml.parse(
                 new InputStreamReader(new ByteArrayInputStream(VALID_NEW_XML_STRING.getBytes())),
                 fileNameToLibraryToContentIdMap, contentIdToFileContentMap);
-        assertThat(fileNameToLibraryToContentIdMap.size()).isEqualTo(2);
-        assertThat(fileNameToLibraryToContentIdMap.get("libA").size()).isEqualTo(1);
-        assertThat(fileNameToLibraryToContentIdMap.get("libB").size()).isEqualTo(1);
-        assertThat(fileNameToLibraryToContentIdMap.get("libA").get("/file0")).containsExactly("0");
-        assertThat(fileNameToLibraryToContentIdMap.get("libB").get("/file1")).containsExactly("0");
+
+        assertThat(fileNameToLibraryToContentIdMap).hasSize(2);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0").get("libA")).containsExactly("0");
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1").get("libB")).containsExactly("0");
         assertThat(contentIdToFileContentMap.size()).isEqualTo(1);
         assertThat(contentIdToFileContentMap.get("0")).isEqualTo("license content #0");
     }
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/utils/PowerUtilTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
index 3029736..ae54206 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/utils/PowerUtilTest.java
@@ -122,9 +122,9 @@
                 true /* basedOnUsage */);
 
         // additional battery percentage in this string
-        assertThat(info).isEqualTo("Phone may shut down soon (10%)");
+        assertThat(info.contains("may shut down soon (10%)")).isTrue();
         // shortened string should not have percentage
-        assertThat(info2).isEqualTo("Phone may shut down soon");
+        assertThat(info2.contains("may shut down soon")).isTrue();
     }
 
     @Test
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 8e35ee96..c7673aa 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -193,8 +193,10 @@
         Settings.Secure.NOTIFICATION_BUBBLES,
         Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
         Settings.Secure.LOCKSCREEN_SHOW_CONTROLS,
+        Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS,
         Settings.Secure.LOCKSCREEN_SHOW_WALLET,
         Settings.Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER,
         Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
+        Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 5f549fd..fa3360c 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -152,9 +152,11 @@
         VALIDATORS.put(Secure.CONTROLS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.POWER_MENU_LOCKED_SHOW_CONTENT, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.LOCKSCREEN_SHOW_CONTROLS, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.LOCKSCREEN_SHOW_WALLET, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.LOCK_SCREEN_SHOW_QR_CODE_SCANNER, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.STATUS_BAR_SHOW_VIBRATE_ICON, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.DOZE_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.DOZE_ALWAYS_ON, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.DOZE_PICK_UP_GESTURE, BOOLEAN_VALIDATOR);
@@ -229,6 +231,7 @@
         VALIDATORS.put(Secure.SKIP_DIRECTION, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SILENCE_GESTURE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, JSON_OBJECT_VALIDATOR);
+        VALIDATORS.put(Secure.NAV_BAR_FORCE_VISIBLE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.NAV_BAR_KIDS_MODE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(
                 Secure.NAVIGATION_MODE, new DiscreteValueValidator(new String[] {"0", "1", "2"}));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a2b6992..3c29a80 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2252,9 +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.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 f0b180e..dae63a8 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" />
@@ -588,8 +589,14 @@
     <uses-permission android:name="android.permission.MANAGE_HOTWORD_DETECTION" />
     <uses-permission android:name="android.permission.BIND_HOTWORD_DETECTION_SERVICE" />
 
+    <!-- Permission required for CTS test - KeyguardLockedStateApiTest -->
+    <uses-permission android:name="android.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE" />
+
     <uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION"/>
 
+    <!-- Permission required for CTS test - MediaCodecResourceTest -->
+    <uses-permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID" />
+
     <!-- Permission required for CTS test - ResourceObserverNativeTest -->
     <uses-permission android:name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" />
 
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index ad6074a..7f8b2f5 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -154,7 +154,7 @@
     <!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked -->
     <uses-permission android:name="android.permission.SET_WALLPAPER"/>
 
-    <!-- Needed for WallpaperManager.getWallpaperDimAmount in StatusBar.updateTheme -->
+    <!-- Needed for WallpaperManager.getWallpaperDimAmount in CentralSurfaces.updateTheme -->
     <uses-permission android:name="android.permission.SET_WALLPAPER_DIM_AMOUNT"/>
 
     <!-- Wifi Display -->
@@ -311,6 +311,9 @@
     <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
     <uses-permission android:name="android.permission.SUPPRESS_CLIPBOARD_ACCESS_NOTIFICATION" />
 
+    <!-- To change system captions state -->
+    <uses-permission android:name="android.permission.SET_SYSTEM_AUDIO_CAPTION" />
+
     <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" />
@@ -767,22 +770,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".chooser.ChooserActivity"
-                android:theme="@*android:style/Theme.NoDisplay"
-                android:finishOnCloseSystemDialogs="true"
-                android:excludeFromRecents="true"
-                android:documentLaunchMode="never"
-                android:relinquishTaskIdentity="true"
-                android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
-                android:process=":ui"
-                android:visibleToInstantApps="true"
-                android:exported="true">
-            <intent-filter>
-                <action android:name="android.intent.action.CHOOSER" />
-                <category android:name="android.intent.category.VOICE" />
-            </intent-filter>
-        </activity>
-
         <activity android:name=".clipboardoverlay.EditTextActivity"
                   android:theme="@style/EditTextActivity"
                   android:exported="false"
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 0da60f0..74b759f 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -172,7 +172,7 @@
         if (packageName != null && animationAdapter != null) {
             try {
                 ActivityTaskManager.getService().registerRemoteAnimationForNextActivityStart(
-                    packageName, animationAdapter)
+                    packageName, animationAdapter, null /* launchCookie */)
             } catch (e: RemoteException) {
                 Log.w(TAG, "Unable to register the remote animation", e)
             }
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/docs/corestartable.md b/packages/SystemUI/docs/corestartable.md
new file mode 100644
index 0000000..fe34893
--- /dev/null
+++ b/packages/SystemUI/docs/corestartable.md
@@ -0,0 +1,46 @@
+# Starting SystemUI CoreStartables
+
+## Overview
+
+A [CoreStartable](/packages/SystemUI/src/com/android/systemui/CoreStartable.java) class represents
+a chunk of SystemUI functionality that is initialized at startup time, independent of the rest of
+the system. Which CoreStartables are included and run can be customized per-build via Dagger.
+
+The base class contains nominal functionality, making it lightweight and inexpensive to construct.
+Unlike Activities, Services, and similar Android constructs, CoreStartables do not have  unique
+context, and have no lifecycle methods except for a singular `#start` method that is called once.
+
+## How to Define a CoreStartable
+
+1) Subclass `CoreStartable`. Put any initialization logic in its `#start` method. Preferably, put it
+   in its own source package (with related code) to keep it organizationally distinct from other
+   code in SystemUI.
+
+2) Mark its class with `@SysUISingleton` and its constructor with `@Inject`.
+
+3) Define a corresponding Dagger module in the same package. The name of the module should follow
+   the pattern: “Start<Feature>Module” where <Feature> is replaced with the name of the
+   CoreStartable.
+
+4) Put the following definition inside your new module:
+
+```java
+     @Binds
+     @IntoMap
+     @ClassKey(Feature.class)
+     abstract CoreStartable bindFeature(Feature impl);
+```
+
+5) Include the new module in any clients that may need it. For AOSP, this is the
+   SystemUICoreStartableModule.
+
+## Tips and Tricks
+
+**CoreStartables should be single-feature focused.** If you need something run at startup time
+that doesn't have a clear initialization path in existing code, strongly consider defining a _new_
+CoreStartable instead of inserting into a random place in an existing one.
+
+**CoreStartables should be order independent.** They currently are started in an arbitrary but
+deterministic order. We do not promise that this order won't change in the future, however. We do
+not provide a mechanism for changing the order. If you need some other part of the system to
+come online first, consider adding a listener to that part of the system.
\ No newline at end of file
diff --git a/packages/SystemUI/docs/keyguard.md b/packages/SystemUI/docs/keyguard.md
index 5e7bc1c..8914042 100644
--- a/packages/SystemUI/docs/keyguard.md
+++ b/packages/SystemUI/docs/keyguard.md
@@ -40,7 +40,7 @@
 
 [1]: /frameworks/base/packages/SystemUI/docs/keyguard/bouncer.md
 [2]: /frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
-[3]: /frameworks/base/packages/SystemUI/docs/keyguard/aod.md
+[3]: /frameworks/base/packages/SystemUI/docs/keyguard/doze.md
 [4]: /frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
 
 
diff --git a/packages/SystemUI/docs/keyguard/aod.md b/packages/SystemUI/docs/keyguard/aod.md
deleted file mode 100644
index 7f89984..0000000
--- a/packages/SystemUI/docs/keyguard/aod.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Always-on Display (AOD)
-
-AOD provides an alternatative 'screen-off' experience. Instead, of completely turning the display off, it provides a distraction-free, glanceable experience for the phone in a low-powered mode. In this low-powered mode, the display will have a lower refresh rate and the UI should frequently shift its displayed contents in order to prevent burn-in.
-
-The default doze component is specified by `config_dozeComponent` in the [framework config][1]. SystemUI provides a default Doze Component: [DozeService][2]. [DozeService][2] builds a [DozeMachine][3] with dependencies specified in [DozeModule][4] and configurations in [AmbientDisplayConfiguration][13] and [DozeParameters][14].
-
-[DozeMachine][3] handles the following main states:
-* AOD - persistently showing UI when the device is in a low-powered state
-* Pulsing - waking up the screen to show notifications (from AOD and screen off)
-* Docked UI - UI to show when the device is docked
-* Wake-up gestures - including lift to wake and tap to wake (from AOD and screen off)
-
-## Doze States ([see DozeMachine.State][3])
-### DOZE
-Device is asleep and listening for enabled pulsing and wake-up gesture triggers. In this state, no UI shows.
-
-### DOZE_AOD
-Device is asleep, showing UI, and listening for enabled pulsing and wake-up triggers. In this state, screen brightness is handled by [DozeScreenBrightness][5] which uses the brightness sensor specified by `doze_brightness_sensor_type` in the [SystemUI config][6]. To save power, this should be a low-powered sensor that shouldn't trigger as often as the light sensor used for on-screen adaptive brightness.
-
-### DOZE_AOD_PAUSED
-Device is asleep and would normally be in state `DOZE_AOD`; however, instead the display is temporarily off since the proximity sensor reported near for a minimum abount of time. [DozePauser][7] handles transitioning from `DOZE_AOD_PAUSING` after the minimum timeout after the NEAR is reported by the proximity sensor from [DozeTriggers][8]).
-
-### DOZE_PULSING
-Device is awake and showing UI. This is state typically occurs in response to incoming notification, but may also be from other pulse triggers specified in [DozeTriggers][8].
-
-### DOZE_AOD_DOCKED
-Device is awake, showing docking UI and listening for enabled pulsing and wake-up triggers. The default DockManager is provided by an empty interface at [DockManagerImpl][9]. SystemUI should override the DockManager for the DozeService to handle docking events.
-
-[DozeDockHandler][11] listens for Dock state changes from [DockManager][10] and updates the doze docking state.
-
-## Wake-up gestures
-Doze sensors are registered in [DozeTriggers][8] via [DozeSensors][12]. Sensors can be configured per posture for foldable devices.
-
-Relevant sensors include:
-* Proximity sensor
-* Brightness sensor
-* Wake-up gestures
-  * tap to wake
-  * double tap to wake
-  * lift to wake
-  * significant motion
-
-And are configured in the [AmbientDisplayConfiguration][13] with some related configurations specified in [DozeParameters][14].
-
-## Debugging Tips
-Enable DozeLog to print directly to logcat:
-```
-adb shell settings put global systemui/buffer/DozeLog v
-```
-
-Enable all DozeService logs to print directly to logcat:
-```
-adb shell setprop log.tag.DozeService DEBUG
-```
-
-Other helpful dumpsys commands (`adb shell dumpsys <service>`):
-* activity service com.android.systemui/.doze.DozeService
-* activity service com.android.systemui/.SystemUIService
-* display
-* power
-* dreams
-* sensorservice
-
-[1]: /frameworks/base/core/res/res/values/config.xml
-[2]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
-[3]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
-[4]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
-[5]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
-[6]: /frameworks/base/packages/SystemUI/res/values/config.xml
-[7]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java
-[8]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
-[9]: /frameworks/base/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java
-[10]: /frameworks/base/packages/SystemUI/src/com/android/systemui/dock/DockManager.java
-[11]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
-[12]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
-[13]: /frameworks/base/core/java/android/hardware/display/AmbientDisplayConfiguration.java
-[14]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
diff --git a/packages/SystemUI/docs/keyguard/doze.md b/packages/SystemUI/docs/keyguard/doze.md
new file mode 100644
index 0000000..a6ccab9
--- /dev/null
+++ b/packages/SystemUI/docs/keyguard/doze.md
@@ -0,0 +1,100 @@
+# Doze
+
+Always-on Display (AOD) provides an alternative 'screen-off' experience. Instead, of completely turning the display off, it provides a distraction-free, glanceable experience for the phone in a low-powered mode. In this low-powered mode, the display will have a lower refresh rate and the UI should frequently shift its displayed contents in order to prevent burn-in. The recommended max on-pixel-ratio (OPR) is 5% to reduce battery consumption.
+
+The default doze component controls AOD and is specified by `config_dozeComponent` in the [framework config][1]. SystemUI provides a default Doze Component: [DozeService][2]. [DozeService][2] builds a [DozeMachine][3] with dependencies specified in [DozeModule][4] and configurations in [AmbientDisplayConfiguration][13] and [DozeParameters][14].
+
+Note: The default UI used in AOD shares views with the Lock Screen and does not create its own new views. Once dozing begins, [DozeUI][17] informs SystemUI's [DozeServiceHost][18] that dozing has begun - which sends this signal to relevant SystemUI Lock Screen views to animate accordingly. Within SystemUI, [StatusBarStateController][19] #isDozing and #getDozeAmount can be used to query dozing state.
+[DozeMachine][3] handles the following main states:
+* AOD - persistently showing UI when the device is in a low-powered state
+* Pulsing - waking up the screen to show notifications (from AOD and screen off)
+* Docked UI - UI to show when the device is docked
+* Wake-up gestures - including lift to wake and tap to wake (from AOD and screen off)
+
+## Doze States ([see DozeMachine.State][3])
+### DOZE
+Device is asleep and listening for enabled pulsing and wake-up gesture triggers. In this state, no UI shows.
+
+### DOZE_AOD
+Device is asleep, showing UI, and listening for enabled pulsing and wake-up triggers. In this state, screen brightness is handled by [DozeScreenBrightness][5] which uses the brightness sensor specified by `doze_brightness_sensor_type` in the [SystemUI config][6]. To save power, this should be a low-powered sensor that shouldn't trigger as often as the light sensor used for on-screen adaptive brightness.
+
+### DOZE_AOD_PAUSED
+Device is asleep and would normally be in state `DOZE_AOD`; however, instead the display is temporarily off since the proximity sensor reported near for a minimum abount of time. [DozePauser][7] handles transitioning from `DOZE_AOD_PAUSING` after the minimum timeout after the NEAR is reported by the proximity sensor from [DozeTriggers][8]).
+
+### DOZE_PULSING
+Device is awake and showing UI. This is state typically occurs in response to incoming notification, but may also be from other pulse triggers specified in [DozeTriggers][8].
+
+### DOZE_AOD_DOCKED
+Device is awake, showing docking UI and listening for enabled pulsing and wake-up triggers. The default DockManager is provided by an empty interface at [DockManagerImpl][9]. SystemUI should override the DockManager for the DozeService to handle docking events.
+
+[DozeDockHandler][11] listens for Dock state changes from [DockManager][10] and updates the doze docking state.
+
+## Wake-up gestures
+Doze sensors are registered in [DozeTriggers][8] via [DozeSensors][12]. Sensors can be configured per posture for foldable devices.
+
+Relevant sensors include:
+* Proximity sensor
+* Brightness sensor
+* Wake-up gestures
+  * tap to wake
+  * double tap to wake
+  * lift to wake
+  * significant motion
+
+And are configured in the [AmbientDisplayConfiguration][13] with some related configurations specified in [DozeParameters][14].
+
+## Doze Suppressors
+When Dozing is enabled, it can still be suppressed based on the device state. On a high-level, doze and/or AOD may be suppressed if the device is:
+* in CAR_MODE
+* not provisioned
+* in power saver mode
+* being suppressed by an app (see [PowerManager#suppressAmbientDisplay][16])
+
+Refer to the documentation in [DozeSuppressors][15] for more information.
+
+## AOD burn-in and image retention
+Because AOD will show an image on the screen for an elogated period of time, AOD designs must take into consideration burn-in (leaving a permanent mark on the screen). Temporary burn-in is called image-retention.
+
+To prevent burn-in, it is recommended to often shift UI on the screen. [DozeUi][17] schedules a call to dozeTimeTick every minute to request a shift in UI for all elements on AOD. The amount of shift can be determined by undergoing simulated AOD testing since this may vary depending on the display.
+
+For manual local testing, set [DozeUI][17]#BURN_IN_TESTING_ENABLED to true, and then manual time broadcasts (ie: `adb shell 'date 022202222022.00 ; am broadcast -a android.intent.action.TIME_SET'`) will update the burn-in translations of the views. For a general idea where burn-in may be an issue, run the [software burn-in script][20].
+
+## Debugging Tips
+Enable DozeLog to print directly to logcat:
+```
+adb shell settings put global systemui/buffer/DozeLog v
+```
+
+Enable all DozeService logs to print directly to logcat:
+```
+adb shell setprop log.tag.DozeService DEBUG
+```
+
+Other helpful dumpsys commands (`adb shell dumpsys <service>`):
+* activity service com.android.systemui/.doze.DozeService
+* activity service com.android.systemui/.SystemUIService
+* display
+* power
+* dreams
+* sensorservice
+
+[1]: /frameworks/base/core/res/res/values/config.xml
+[2]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+[3]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+[4]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
+[5]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+[6]: /frameworks/base/packages/SystemUI/res/values/config.xml
+[7]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozePauser.java
+[8]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+[9]: /frameworks/base/packages/SystemUI/src/com/android/systemui/dock/DockManagerImpl.java
+[10]: /frameworks/base/packages/SystemUI/src/com/android/systemui/dock/DockManager.java
+[11]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
+[12]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+[13]: /frameworks/base/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+[14]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+[15]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
+[16]: /frameworks/base/core/java/android/os/PowerManager.java
+[17]: /frameworks/base/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+[18]: /frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+[19]: /frameworks/base/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
+[20]: /frameworks/base/packages/SystemUI/docs/clock-plugins.md
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
index 0a0530c0..3d2f570 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
@@ -60,7 +60,6 @@
 
     boolean areCaptionsEnabled();
     void setCaptionsEnabled(boolean isEnabled);
-    boolean isCaptionStreamOptedOut();
 
     void getCaptionsComponentState(boolean fromTooltip);
 
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 6352f81..e74b6c7 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -3,7 +3,7 @@
 
 -keep class com.android.systemui.recents.OverviewProxyRecentsImpl
 -keep class com.android.systemui.statusbar.car.CarStatusBar
--keep class com.android.systemui.statusbar.phone.StatusBar
+-keep class com.android.systemui.statusbar.phone.CentralSurfaces
 -keep class com.android.systemui.statusbar.tv.TvStatusBar
 -keep class com.android.systemui.car.CarSystemUIFactory
 -keep class com.android.systemui.SystemUIFactory
@@ -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/bouncer_user_switcher_header_bg.xml b/packages/SystemUI/res-keyguard/drawable/bouncer_user_switcher_header_bg.xml
index 1119935..6986961 100644
--- a/packages/SystemUI/res-keyguard/drawable/bouncer_user_switcher_header_bg.xml
+++ b/packages/SystemUI/res-keyguard/drawable/bouncer_user_switcher_header_bg.xml
@@ -17,10 +17,8 @@
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
             android:paddingMode="stack"
-            android:paddingStart="24dp"
-            android:paddingEnd="44dp"
-            android:paddingLeft="0dp"
-            android:paddingRight="0dp">
+            android:paddingStart="0dp"
+            android:paddingEnd="0dp">
     <item>
         <shape android:shape="rectangle">
           <solid android:color="?androidprv:attr/colorSurface" />
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-keyguard/drawable/num_pad_key_background.xml b/packages/SystemUI/res-keyguard/drawable/num_pad_key_background.xml
index 3a7a8ae..7455ad2 100644
--- a/packages/SystemUI/res-keyguard/drawable/num_pad_key_background.xml
+++ b/packages/SystemUI/res-keyguard/drawable/num_pad_key_background.xml
@@ -16,14 +16,7 @@
 * limitations under the License.
 */
 -->
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="?android:attr/colorControlHighlight">
-  <item android:id="@+id/background">
-    <shape>
-      <solid android:color="?android:attr/colorControlNormal" />
-      <corners android:radius="10dp" />
-    </shape>
-  </item>
-</ripple>
-
+<shape xmlns:android="http://schemas.android.com/apk/res/android" >
+  <solid android:color="?android:attr/colorControlNormal" />
+  <corners android:radius="10dp" />
+</shape>
diff --git a/packages/SystemUI/res-keyguard/layout/fgs_footer.xml b/packages/SystemUI/res-keyguard/layout/fgs_footer.xml
index 59f87da..9d801d2 100644
--- a/packages/SystemUI/res-keyguard/layout/fgs_footer.xml
+++ b/packages/SystemUI/res-keyguard/layout/fgs_footer.xml
@@ -28,7 +28,7 @@
         android:layout_height="match_parent"
         android:layout_marginEnd="@dimen/new_qs_footer_action_inset"
         android:background="@drawable/qs_security_footer_background"
-        android:layout_gravity="center"
+        android:layout_gravity="end"
         android:gravity="center"
         android:paddingHorizontal="@dimen/qs_footer_padding"
         >
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 31d848d..16a1d94 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -26,6 +26,7 @@
     systemui:layout_constraintStart_toStartOf="parent"
     systemui:layout_constraintEnd_toEndOf="parent"
     systemui:layout_constraintTop_toTopOf="parent"
+    android:layout_marginHorizontal="@dimen/status_view_margin_horizontal"
     android:layout_width="0dp"
     android:layout_height="wrap_content">
     <LinearLayout
diff --git a/packages/SystemUI/res-keyguard/values-land/dimens.xml b/packages/SystemUI/res-keyguard/values-land/dimens.xml
index 6342b9c..4e92884f 100644
--- a/packages/SystemUI/res-keyguard/values-land/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values-land/dimens.xml
@@ -26,4 +26,6 @@
 
     <!-- The size of PIN text in the PIN unlock method. -->
     <integer name="scaled_password_text_size">26</integer>
+
+    <dimen name="bouncer_user_switcher_y_trans">@dimen/status_bar_height</dimen>
 </resources>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index dad4c19..8d205c1 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -117,12 +117,15 @@
     <dimen name="bouncer_user_switcher_popup_divider_height">4dp</dimen>
     <dimen name="bouncer_user_switcher_item_padding_vertical">10dp</dimen>
     <dimen name="bouncer_user_switcher_item_padding_horizontal">12dp</dimen>
+    <dimen name="bouncer_user_switcher_header_padding_end">44dp</dimen>
+    <dimen name="bouncer_user_switcher_y_trans">0dp</dimen>
 
     <!-- 2 * the margin + size should equal the plus_margin -->
     <dimen name="user_switcher_icon_large_margin">16dp</dimen>
     <dimen name="bouncer_user_switcher_icon_size">190dp</dimen>
     <dimen name="bouncer_user_switcher_icon_size_plus_margin">222dp</dimen>
 
+    <dimen name="user_switcher_fullscreen_horizontal_gap">64dp</dimen>
     <dimen name="user_switcher_icon_selected_width">8dp</dimen>
     <dimen name="user_switcher_fullscreen_button_text_size">14sp</dimen>
     <dimen name="user_switcher_fullscreen_button_padding">12dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 5048f85..6375698 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -155,6 +155,7 @@
     <style name="Bouncer.UserSwitcher.Spinner.Header">
         <item name="android:background">@drawable/bouncer_user_switcher_header_bg</item>
         <item name="android:textSize">@dimen/bouncer_user_switcher_header_text_size</item>
+        <item name="android:paddingEnd">@dimen/bouncer_user_switcher_header_padding_end</item>
     </style>
 
     <style name="Bouncer.UserSwitcher.Spinner.Item">
diff --git a/packages/SystemUI/res/color/caption_tint_color_selector.xml b/packages/SystemUI/res/color/caption_tint_color_selector.xml
index 30843ec..5239d26 100644
--- a/packages/SystemUI/res/color/caption_tint_color_selector.xml
+++ b/packages/SystemUI/res/color/caption_tint_color_selector.xml
@@ -16,8 +16,5 @@
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
           xmlns:sysui="http://schemas.android.com/apk/res-auto">
-    <item sysui:optedOut="true"
-          android:color="?android:attr/colorButtonNormal"/>
-
     <item android:color="?android:attr/colorAccent"/>
 </selector>
\ No newline at end of file
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-mdpi/dream_preview_back_arrow.png b/packages/SystemUI/res/drawable-mdpi/dream_preview_back_arrow.png
new file mode 100644
index 0000000..2c2f94e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/dream_preview_back_arrow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/dream_preview_back_arrow.png b/packages/SystemUI/res/drawable-xhdpi/dream_preview_back_arrow.png
new file mode 100644
index 0000000..881b9af
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/dream_preview_back_arrow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/dream_preview_back_arrow.png b/packages/SystemUI/res/drawable-xxhdpi/dream_preview_back_arrow.png
new file mode 100644
index 0000000..6063b42
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/dream_preview_back_arrow.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
index 0ae5dc7..5084ca4 100644
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_fp.xml
@@ -1,254 +1 @@
-<?xml version="1.0" encoding="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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-                 xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector android:height="60dp" android:width="60dp" android:viewportHeight="60"
-                android:viewportWidth="60">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_1_G" android:translateX="-0.05000000000000071">
-                    <group android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0" android:translateX="30"
-                           android:translateY="38.75" android:scaleX="1" android:scaleY="1">
-                        <path android:name="_R_G_L_1_G_D_0_P_0"
-                              android:fillColor="@color/biometric_dialog_error"
-                              android:fillAlpha="1" android:fillType="nonZero"
-                              android:pathData=" M-1.2 -1.25 C-1.2,-1.25 1.2,-1.25 1.2,-1.25 C1.2,-1.25 1.2,1.25 1.2,1.25 C1.2,1.25 -1.2,1.25 -1.2,1.25 C-1.2,1.25 -1.2,-1.25 -1.2,-1.25c "/>
-                    </group>
-                    <group android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0" android:translateX="30"
-                           android:translateY="25" android:pivotX="0.002" android:pivotY="7.488"
-                           android:scaleX="1" android:scaleY="1">
-                        <path android:name="_R_G_L_1_G_D_1_P_0"
-                              android:fillColor="@color/biometric_dialog_error"
-                              android:fillAlpha="1" android:fillType="nonZero"
-                              android:pathData=" M-1.2 -7.5 C-1.2,-7.5 1.2,-7.5 1.2,-7.5 C1.2,-7.5 1.2,7.5 1.2,7.5 C1.2,7.5 -1.2,7.5 -1.2,7.5 C-1.2,7.5 -1.2,-7.5 -1.2,-7.5c "/>
-                    </group>
-                    <path android:name="_R_G_L_1_G_D_2_P_0"
-                          android:strokeColor="@color/biometric_dialog_error"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2.5" android:strokeAlpha="1"
-                          android:trimPathStart="0" android:trimPathEnd="1"
-                          android:trimPathOffset="0"
-                          android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "/>
-                </group>
-                <group android:name="_R_G_L_0_G" android:translateX="-10.325"
-                       android:translateY="-10.25">
-                    <path android:name="_R_G_L_0_G_D_0_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="0" android:trimPathOffset="0"
-                          android:pathData=" M31.41 48.43 C30.78,46.69 30.78,44.91 30.78,44.91 C30.78,40.09 34.88,36.16 40.32,36.16 C45.77,36.16 49.87,40.09 49.87,44.91 C49.87,44.91 49.87,45.17 49.87,45.17 C49.87,46.97 48.41,48.43 46.61,48.43 C45.28,48.43 44.09,47.63 43.6,46.39 C43.6,46.39 42.51,43.66 42.51,43.66 C42.02,42.42 40.82,41.61 39.49,41.61 C37.69,41.61 36.23,43.07 36.23,44.87 C36.23,47.12 37.26,49.26 39.02,50.67 C39.02,50.67 39.64,51.16 39.64,51.16 "/>
-                    <path android:name="_R_G_L_0_G_D_1_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="0" android:trimPathOffset="0"
-                          android:pathData=" M32.14 27.3 C34.5,26 37.31,25.25 40.33,25.25 C43.34,25.25 46.15,26 48.51,27.3 "/>
-                    <path android:name="_R_G_L_0_G_D_2_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="0" android:trimPathOffset="0"
-                          android:pathData=" M29.42 36.16 C31.35,32.94 35.51,30.71 40.33,30.71 C45.14,30.71 49.3,32.94 51.23,36.16 "/>
-                    <path android:name="_R_G_L_0_G_D_3_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="0" android:trimPathOffset="0"
-                          android:pathData=" M47.14 52.52 C45.33,54.21 42.94,55.25 40.33,55.25 C37.71,55.25 35.32,54.21 33.51,52.52 "/>
-                </group>
-            </group>
-            <group android:name="time_group"/>
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="67"
-                                android:startOffset="0" android:valueFrom="1" android:valueTo="1.1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.853,0 0.6,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="67"
-                                android:startOffset="0" android:valueFrom="1" android:valueTo="1.1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.853,0 0.6,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="100"
-                                android:startOffset="67" android:valueFrom="1.1" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.06 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="100"
-                                android:startOffset="67" android:valueFrom="1.1" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.06 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="67"
-                                android:startOffset="0" android:valueFrom="1" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.659,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="67"
-                                android:startOffset="0" android:valueFrom="1" android:valueTo="1.1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="100"
-                                android:startOffset="67" android:valueFrom="1" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="100"
-                                android:startOffset="67" android:valueFrom="1.1" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.096 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="67"
-                                android:startOffset="0" android:valueFrom="1" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="133"
-                                android:startOffset="67" android:valueFrom="1" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="83"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="250"
-                                android:startOffset="83" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="83"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="250"
-                                android:startOffset="83" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="83"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="250"
-                                android:startOffset="83" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="83"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="trimPathEnd" android:duration="250"
-                                android:startOffset="83" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="translateX" android:duration="417"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType"/>
-            </set>
-        </aapt:attr>
-    </target>
-</animated-vector>
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="80dp" android:width="80dp" android:viewportHeight="80" android:viewportWidth="80"><group android:name="_R_G"><group android:name="_R_G_L_3_G" android:translateX="-0.25" android:translateY="-0.25"><path android:name="_R_G_L_3_G_D_0_P_0" android:fillColor="#474747" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M40.21 0.25 C18.13,0.25 0.25,18.17 0.25,40.25 C0.25,62.33 18.13,80.25 40.21,80.25 C62.33,80.25 80.25,62.33 80.25,40.25 C80.25,18.17 62.33,0.25 40.21,0.25c "/></group><group android:name="_R_G_L_2_G" android:translateX="-0.25" android:translateY="-0.25" android:pivotX="40.25" android:pivotY="40.25" android:scaleX="0.975" android:scaleY="0.975"><path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#f2b8b5" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M40.21 0.25 C18.13,0.25 0.25,18.17 0.25,40.25 C0.25,62.33 18.13,80.25 40.21,80.25 C62.33,80.25 80.25,62.33 80.25,40.25 C80.25,18.17 62.33,0.25 40.21,0.25c "/></group><group android:name="_R_G_L_1_G" android:translateX="9.950000000000003" android:translateY="10" android:pivotX="30" android:pivotY="30" android:scaleX="1.2" android:scaleY="1.2"><group android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0" android:translateX="30" android:translateY="38.75" android:scaleX="1" android:scaleY="1"><path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#f2b8b5" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1.2 -1.25 C-1.2,-1.25 1.2,-1.25 1.2,-1.25 C1.2,-1.25 1.2,1.25 1.2,1.25 C1.2,1.25 -1.2,1.25 -1.2,1.25 C-1.2,1.25 -1.2,-1.25 -1.2,-1.25c "/></group><group android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0" android:translateX="30" android:translateY="25" android:pivotX="0.002" android:pivotY="7.488" android:scaleX="1" android:scaleY="1"><path android:name="_R_G_L_1_G_D_1_P_0" android:fillColor="#f2b8b5" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1.2 -7.5 C-1.2,-7.5 1.2,-7.5 1.2,-7.5 C1.2,-7.5 1.2,7.5 1.2,7.5 C1.2,7.5 -1.2,7.5 -1.2,7.5 C-1.2,7.5 -1.2,-7.5 -1.2,-7.5c "/></group></group><group android:name="_R_G_L_0_G" android:translateX="20.659" android:translateY="15.75"><path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="0" android:trimPathOffset="0" android:pathData=" M27.52 38.98 C26.49,39.95 25.29,40.73 23.98,41.29 C23.17,41.65 22.31,41.91 21.41,42.07 C20.74,42.19 20.05,42.25 19.34,42.25 C18.44,42.25 17.56,42.15 16.72,41.96 C15.93,41.77 15.16,41.51 14.43,41.18 C13.23,40.63 12.13,39.88 11.16,38.98 "/><path android:name="_R_G_L_0_G_D_1_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="0" android:trimPathOffset="0" android:pathData=" M8.64 34.07 C7.89,31.97 7.89,29.85 7.89,29.85 C7.89,24.05 12.81,19.34 19.34,19.34 C25.87,19.34 30.8,24.05 30.8,29.85 C30.8,29.85 30.8,30.16 30.8,30.16 C30.8,32.32 29.04,34.07 26.89,34.07 C25.28,34.07 23.86,33.1 23.27,31.61 C23.27,31.61 21.96,28.34 21.96,28.34 C21.37,26.85 19.93,25.89 18.34,25.89 C16.18,25.89 14.43,27.64 14.43,29.8 C14.43,31.42 14.87,32.99 15.68,34.36 C16.22,35.26 16.93,36.08 17.77,36.75 C17.77,36.75 18.52,37.34 18.52,37.34 "/><path android:name="_R_G_L_0_G_D_2_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="0" android:trimPathOffset="0" android:pathData=" M6.25 19.34 C7.48,17.3 9.46,15.58 11.9,14.42 C12.93,13.94 14.03,13.55 15.2,13.27 C16.51,12.96 17.9,12.8 19.34,12.8 C20.77,12.8 22.14,12.96 23.45,13.26 C24.9,13.6 26.26,14.12 27.48,14.78 C29.6,15.92 31.32,17.5 32.43,19.34 "/><path android:name="_R_G_L_0_G_D_3_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="0" android:trimPathOffset="0" android:pathData=" M9.52 8.7 C10.98,7.91 12.58,7.28 14.28,6.86 C15.89,6.46 17.58,6.25 19.34,6.25 C21.06,6.25 22.72,6.45 24.3,6.83 C26.04,7.25 27.67,7.89 29.16,8.7 "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_3_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="67" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="fillAlpha" android:duration="167" android:startOffset="67" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeWidth" android:duration="167" android:startOffset="0" android:valueFrom="2.5" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeAlpha" android:duration="83" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="strokeAlpha" android:duration="83" android:startOffset="83" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="0.975" android:valueType="floatType"/></set></aapt:attr></target><target android:name="_R_G_L_2_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="167" android:valueFrom="0.975" android:valueTo="0" android:valueType="floatType"/></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.853,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.853,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="100" android:startOffset="67" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.06 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="100" android:startOffset="67" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.06 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.659,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="100" android:startOffset="67" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="100" android:startOffset="67" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.096 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathEnd" android:duration="83" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="trimPathEnd" android:duration="250" android:startOffset="83" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathEnd" android:duration="83" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="trimPathEnd" android:duration="250" android:startOffset="83" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_2_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathEnd" android:duration="83" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="trimPathEnd" android:duration="250" android:startOffset="83" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_3_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathEnd" android:duration="83" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="trimPathEnd" android:duration="250" android:startOffset="83" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.543,0 0.299,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="417" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_unlock.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_unlock.xml
new file mode 100644
index 0000000..c4f8181
--- /dev/null
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_error_to_unlock.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="80dp" android:width="80dp" android:viewportHeight="80" android:viewportWidth="80"><group android:name="_R_G"><group android:name="_R_G_L_3_G" android:translateX="-0.25" android:translateY="-0.25"><path android:name="_R_G_L_3_G_D_0_P_0" android:fillColor="#474747" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M40.21 0.25 C18.13,0.25 0.25,18.17 0.25,40.25 C0.25,62.33 18.13,80.25 40.21,80.25 C62.33,80.25 80.25,62.33 80.25,40.25 C80.25,18.17 62.33,0.25 40.21,0.25c "/></group><group android:name="_R_G_L_2_G" android:translateX="-0.25" android:translateY="-0.25" android:pivotX="40.25" android:pivotY="40.25" android:scaleX="0.975" android:scaleY="0.975"><path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#f2b8b5" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2.5" android:strokeAlpha="1" android:pathData=" M40.21 0.25 C18.13,0.25 0.25,18.17 0.25,40.25 C0.25,62.33 18.13,80.25 40.21,80.25 C62.33,80.25 80.25,62.33 80.25,40.25 C80.25,18.17 62.33,0.25 40.21,0.25c "/></group><group android:name="_R_G_L_1_G" android:translateX="9.950000000000003" android:translateY="10" android:pivotX="30" android:pivotY="30" android:scaleX="1.2" android:scaleY="1.2"><group android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0" android:translateX="30" android:translateY="38.75" android:scaleX="1" android:scaleY="1"><path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#f2b8b5" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1.2 -1.25 C-1.2,-1.25 1.2,-1.25 1.2,-1.25 C1.2,-1.25 1.2,1.25 1.2,1.25 C1.2,1.25 -1.2,1.25 -1.2,1.25 C-1.2,1.25 -1.2,-1.25 -1.2,-1.25c "/></group><group android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0" android:translateX="30" android:translateY="25" android:pivotX="0.002" android:pivotY="7.488" android:scaleX="1" android:scaleY="1"><path android:name="_R_G_L_1_G_D_1_P_0" android:fillColor="#f2b8b5" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1.2 -7.5 C-1.2,-7.5 1.2,-7.5 1.2,-7.5 C1.2,-7.5 1.2,7.5 1.2,7.5 C1.2,7.5 -1.2,7.5 -1.2,7.5 C-1.2,7.5 -1.2,-7.5 -1.2,-7.5c "/></group></group><group android:name="_R_G_L_0_G" android:translateX="20.75" android:translateY="15.75" android:pivotX="19.341" android:pivotY="24.25" android:scaleX="0.5" android:scaleY="0"><path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M30.64 30.14 C30.64,30.14 30.64,38.14 30.64,38.14 C30.64,38.77 30.36,39.32 29.91,39.69 C29.57,39.97 29.12,40.14 28.64,40.14 C28.64,40.14 10.14,40.14 10.14,40.14 C9.04,40.14 8.14,39.25 8.14,38.14 C8.14,38.14 8.14,30.14 8.14,30.14 "/><path android:name="_R_G_L_0_G_D_1_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M19.42 31.53 C18.15,31.52 18.11,30.33 18.11,30.33 C18.11,29.59 18.66,28.98 19.4,28.98 C20.13,28.98 20.69,29.59 20.69,30.33 C20.69,30.33 20.69,30.37 20.69,30.37 C20.69,30.64 20.49,30.87 20.25,30.87 C20.07,30.87 19.91,30.74 19.84,30.55 C19.84,30.55 19.69,30.14 19.69,30.14 C19.63,29.94 19.46,29.82 19.28,29.82 C19.04,29.82 18.61,30.02 18.61,30.29 C18.61,30.43 18.6,30.75 18.76,31.03 C18.87,31.21 19.21,31.77 19.96,31.41 C20.69,31.01 20.69,30.34 20.69,30.34 "/><path android:name="_R_G_L_0_G_D_2_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M8.14 30.22 C8.14,30.22 8.14,22.22 8.14,22.22 C8.14,21.71 8.33,21.25 8.64,20.9 C9,20.48 9.54,20.22 10.14,20.22 C10.14,20.22 28.64,20.22 28.64,20.22 C29.75,20.22 30.64,21.11 30.64,22.22 C30.64,22.22 30.64,30.14 30.64,30.14 "/><path android:name="_R_G_L_0_G_D_3_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_3_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="67" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="fillAlpha" android:duration="167" android:startOffset="67" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeWidth" android:duration="167" android:startOffset="0" android:valueFrom="2.5" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeAlpha" android:duration="83" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="strokeAlpha" android:duration="83" android:startOffset="83" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="0.975" android:valueType="floatType"/></set></aapt:attr></target><target android:name="_R_G_L_2_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="167" android:valueFrom="0.975" android:valueTo="0" android:valueType="floatType"/></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.853,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.853,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="100" android:startOffset="67" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.06 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="100" android:startOffset="67" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.06 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.659,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="67" android:startOffset="0" android:valueFrom="1" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="100" android:startOffset="67" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.6,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="100" android:startOffset="67" android:valueFrom="1.1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.8,0 0.92,1.096 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_3_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="233" android:startOffset="0" android:valueFrom="M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueTo="M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="267" android:startOffset="233" android:valueFrom="M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueTo="M37.91 20.05 C37.91,20.05 37.89,14.16 37.89,14.16 C37.89,10.79 35.15,8.05 31.86,8.03 C28.46,8.01 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="167" android:startOffset="0" android:valueFrom="0.5" android:valueTo="0.5" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.05,1.4 0.1,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="167" android:startOffset="0" android:valueFrom="0.5" android:valueTo="0.5" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.05,1.4 0.1,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="333" android:startOffset="167" android:valueFrom="0.5" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.05,1.4 0.1,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="333" android:startOffset="167" android:valueFrom="0.5" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.05,1.4 0.1,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="167" android:valueFrom="0" android:valueTo="0.5" android:valueType="floatType"/></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="683" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
index fc2c7d0..c05a8d5 100644
--- a/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_error.xml
@@ -1,247 +1 @@
-<?xml version="1.0" encoding="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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-                 xmlns:aapt="http://schemas.android.com/aapt">
-    <aapt:attr name="android:drawable">
-        <vector android:height="60dp" android:width="60dp" android:viewportHeight="60"
-                android:viewportWidth="60">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_1_G" android:translateX="-0.05000000000000071">
-                    <group android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0" android:translateX="30"
-                           android:translateY="38.75" android:scaleX="0" android:scaleY="0">
-                        <path android:name="_R_G_L_1_G_D_0_P_0"
-                              android:fillColor="@color/biometric_dialog_error"
-                              android:fillAlpha="1" android:fillType="nonZero"
-                              android:pathData=" M-1.2 -1.25 C-1.2,-1.25 1.2,-1.25 1.2,-1.25 C1.2,-1.25 1.2,1.25 1.2,1.25 C1.2,1.25 -1.2,1.25 -1.2,1.25 C-1.2,1.25 -1.2,-1.25 -1.2,-1.25c "/>
-                    </group>
-                    <group android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0" android:translateX="30"
-                           android:translateY="25" android:pivotX="0.002" android:pivotY="7.488"
-                           android:scaleX="1" android:scaleY="0">
-                        <path android:name="_R_G_L_1_G_D_1_P_0"
-                              android:fillColor="@color/biometric_dialog_error"
-                              android:fillAlpha="1" android:fillType="nonZero"
-                              android:pathData=" M-1.2 -7.5 C-1.2,-7.5 1.2,-7.5 1.2,-7.5 C1.2,-7.5 1.2,7.5 1.2,7.5 C1.2,7.5 -1.2,7.5 -1.2,7.5 C-1.2,7.5 -1.2,-7.5 -1.2,-7.5c "/>
-                    </group>
-                    <path android:name="_R_G_L_1_G_D_2_P_0"
-                          android:strokeColor="@color/biometric_dialog_error"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2.5" android:strokeAlpha="1"
-                          android:trimPathStart="1" android:trimPathEnd="1"
-                          android:trimPathOffset="0"
-                          android:pathData=" M30 6.2 C16.9,6.2 6.3,16.8 6.3,30 C6.3,43.2 16.9,53.8 30,53.8 C43.1,53.8 53.8,43.2 53.8,30 C53.8,16.8 43.1,6.2 30,6.2c "/>
-                </group>
-                <group android:name="_R_G_L_0_G" android:translateX="-10.325"
-                       android:translateY="-10.25">
-                    <path android:name="_R_G_L_0_G_D_0_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="1" android:trimPathOffset="0"
-                          android:pathData=" M31.41 48.43 C30.78,46.69 30.78,44.91 30.78,44.91 C30.78,40.09 34.88,36.16 40.32,36.16 C45.77,36.16 49.87,40.09 49.87,44.91 C49.87,44.91 49.87,45.17 49.87,45.17 C49.87,46.97 48.41,48.43 46.61,48.43 C45.28,48.43 44.09,47.63 43.6,46.39 C43.6,46.39 42.51,43.66 42.51,43.66 C42.02,42.42 40.82,41.61 39.49,41.61 C37.69,41.61 36.23,43.07 36.23,44.87 C36.23,47.12 37.26,49.26 39.02,50.67 C39.02,50.67 39.64,51.16 39.64,51.16 "/>
-                    <path android:name="_R_G_L_0_G_D_1_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="1" android:trimPathOffset="0"
-                          android:pathData=" M32.14 27.3 C34.5,26 37.31,25.25 40.33,25.25 C43.34,25.25 46.15,26 48.51,27.3 "/>
-                    <path android:name="_R_G_L_0_G_D_2_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="1" android:trimPathOffset="0"
-                          android:pathData=" M29.42 36.16 C31.35,32.94 35.51,30.71 40.33,30.71 C45.14,30.71 49.3,32.94 51.23,36.16 "/>
-                    <path android:name="_R_G_L_0_G_D_3_P_0"
-                          android:strokeColor="@color/biometric_dialog_accent"
-                          android:strokeLineCap="round" android:strokeLineJoin="round"
-                          android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0"
-                          android:trimPathEnd="1" android:trimPathOffset="0"
-                          android:pathData=" M47.14 52.52 C45.33,54.21 42.94,55.25 40.33,55.25 C37.71,55.25 35.32,54.21 33.51,52.52 "/>
-                </group>
-            </group>
-            <group android:name="time_group"/>
-        </vector>
-    </aapt:attr>
-    <target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="167"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="167"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="100"
-                                android:startOffset="167" android:valueFrom="0"
-                                android:valueTo="1.1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="100"
-                                android:startOffset="167" android:valueFrom="0"
-                                android:valueTo="1.1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="67"
-                                android:startOffset="267" android:valueFrom="1.1"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.147,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="67"
-                                android:startOffset="267" android:valueFrom="1.1"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.147,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="scaleX" android:duration="167"
-                                android:startOffset="0" android:valueFrom="1" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="167"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.096 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="100"
-                                android:startOffset="167" android:valueFrom="1" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="100"
-                                android:startOffset="167" android:valueFrom="0"
-                                android:valueTo="1.1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.096 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleX" android:duration="67"
-                                android:startOffset="267" android:valueFrom="1" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.341,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator android:propertyName="scaleY" android:duration="67"
-                                android:startOffset="267" android:valueFrom="1.1"
-                                android:valueTo="1" android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathStart" android:duration="267"
-                                android:startOffset="0" android:valueFrom="1" android:valueTo="0"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathStart" android:duration="167"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathStart" android:duration="167"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathStart" android:duration="167"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="trimPathStart" android:duration="167"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/>
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator android:propertyName="translateX" android:duration="350"
-                                android:startOffset="0" android:valueFrom="0" android:valueTo="1"
-                                android:valueType="floatType"/>
-            </set>
-        </aapt:attr>
-    </target>
-</animated-vector>
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="80dp" android:width="80dp" android:viewportHeight="80" android:viewportWidth="80"><group android:name="_R_G"><group android:name="_R_G_L_3_G" android:translateX="-0.25" android:translateY="-0.25"><path android:name="_R_G_L_3_G_D_0_P_0" android:fillColor="#474747" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40.21 0.25 C18.13,0.25 0.25,18.17 0.25,40.25 C0.25,62.33 18.13,80.25 40.21,80.25 C62.33,80.25 80.25,62.33 80.25,40.25 C80.25,18.17 62.33,0.25 40.21,0.25c "/></group><group android:name="_R_G_L_2_G" android:translateX="-0.25" android:translateY="-0.25" android:pivotX="40.25" android:pivotY="40.25" android:scaleX="0.975" android:scaleY="0"><path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#f2b8b5" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="0" android:strokeAlpha="0" android:pathData=" M40.21 0.25 C18.13,0.25 0.25,18.17 0.25,40.25 C0.25,62.33 18.13,80.25 40.21,80.25 C62.33,80.25 80.25,62.33 80.25,40.25 C80.25,18.17 62.33,0.25 40.21,0.25c "/></group><group android:name="_R_G_L_1_G" android:translateX="9.950000000000003" android:translateY="10" android:pivotX="30" android:pivotY="30" android:scaleX="1.2" android:scaleY="1.2"><group android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0" android:translateX="30" android:translateY="38.75" android:scaleX="0" android:scaleY="0"><path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#f2b8b5" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1.2 -1.25 C-1.2,-1.25 1.2,-1.25 1.2,-1.25 C1.2,-1.25 1.2,1.25 1.2,1.25 C1.2,1.25 -1.2,1.25 -1.2,1.25 C-1.2,1.25 -1.2,-1.25 -1.2,-1.25c "/></group><group android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0" android:translateX="30" android:translateY="25" android:pivotX="0.002" android:pivotY="7.488" android:scaleX="1" android:scaleY="0"><path android:name="_R_G_L_1_G_D_1_P_0" android:fillColor="#f2b8b5" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-1.2 -7.5 C-1.2,-7.5 1.2,-7.5 1.2,-7.5 C1.2,-7.5 1.2,7.5 1.2,7.5 C1.2,7.5 -1.2,7.5 -1.2,7.5 C-1.2,7.5 -1.2,-7.5 -1.2,-7.5c "/></group></group><group android:name="_R_G_L_0_G" android:translateX="20.659" android:translateY="15.75"><path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="1" android:trimPathOffset="0" android:pathData=" M27.52 38.98 C26.49,39.95 25.29,40.73 23.98,41.29 C23.17,41.65 22.31,41.91 21.41,42.07 C20.74,42.19 20.05,42.25 19.34,42.25 C18.44,42.25 17.56,42.15 16.72,41.96 C15.93,41.77 15.16,41.51 14.43,41.18 C13.23,40.63 12.13,39.88 11.16,38.98 "/><path android:name="_R_G_L_0_G_D_1_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="1" android:trimPathOffset="0" android:pathData=" M8.64 34.07 C7.89,31.97 7.89,29.85 7.89,29.85 C7.89,24.05 12.81,19.34 19.34,19.34 C25.87,19.34 30.8,24.05 30.8,29.85 C30.8,29.85 30.8,30.16 30.8,30.16 C30.8,32.32 29.04,34.07 26.89,34.07 C25.28,34.07 23.86,33.1 23.27,31.61 C23.27,31.61 21.96,28.34 21.96,28.34 C21.37,26.85 19.93,25.89 18.34,25.89 C16.18,25.89 14.43,27.64 14.43,29.8 C14.43,31.42 14.87,32.99 15.68,34.36 C16.22,35.26 16.93,36.08 17.77,36.75 C17.77,36.75 18.52,37.34 18.52,37.34 "/><path android:name="_R_G_L_0_G_D_2_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="1" android:trimPathOffset="0" android:pathData=" M6.25 19.34 C7.48,17.3 9.46,15.58 11.9,14.42 C12.93,13.94 14.03,13.55 15.2,13.27 C16.51,12.96 17.9,12.8 19.34,12.8 C20.77,12.8 22.14,12.96 23.45,13.26 C24.9,13.6 26.26,14.12 27.48,14.78 C29.6,15.92 31.32,17.5 32.43,19.34 "/><path android:name="_R_G_L_0_G_D_3_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:trimPathStart="0" android:trimPathEnd="1" android:trimPathOffset="0" android:pathData=" M9.52 8.7 C10.98,7.91 12.58,7.28 14.28,6.86 C15.89,6.46 17.58,6.25 19.34,6.25 C21.06,6.25 22.72,6.45 24.3,6.83 C26.04,7.25 27.67,7.89 29.16,8.7 "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_3_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="83" android:startOffset="0" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeWidth" android:duration="67" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="strokeWidth" android:duration="233" android:startOffset="67" android:valueFrom="0" android:valueTo="2.5" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeAlpha" android:duration="67" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="strokeAlpha" android:duration="83" android:startOffset="67" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_2_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleY" android:duration="0" android:startOffset="67" android:valueFrom="0" android:valueTo="0.975" android:valueType="floatType"/></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="167" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="167" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="100" android:startOffset="167" android:valueFrom="0" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="100" android:startOffset="167" android:valueFrom="0" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.06 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="67" android:startOffset="267" android:valueFrom="1.1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.147,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="67" android:startOffset="267" android:valueFrom="1.1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.147,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_1_P_0_G_0_T_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="167" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="167" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.096 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="100" android:startOffset="167" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="100" android:startOffset="167" android:valueFrom="0" android:valueTo="1.1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.08,0.096 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="67" android:startOffset="267" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.341,0 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="67" android:startOffset="267" android:valueFrom="1.1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.2,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathStart" android:duration="167" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathStart" android:duration="167" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_2_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathStart" android:duration="167" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_3_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="trimPathStart" android:duration="167" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="350" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_unlock.xml b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_unlock.xml
new file mode 100644
index 0000000..1694429
--- /dev/null
+++ b/packages/SystemUI/res/drawable/fingerprint_dialog_fp_to_unlock.xml
@@ -0,0 +1 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"><aapt:attr name="android:drawable"><vector android:height="80dp" android:width="80dp" android:viewportHeight="80" android:viewportWidth="80"><group android:name="_R_G"><group android:name="_R_G_L_2_G" android:translateX="-0.25" android:translateY="-0.25"><path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#474747" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M40.21 0.25 C18.13,0.25 0.25,18.17 0.25,40.25 C0.25,62.33 18.13,80.25 40.21,80.25 C62.33,80.25 80.25,62.33 80.25,40.25 C80.25,18.17 62.33,0.25 40.21,0.25c "/></group><group android:name="_R_G_L_1_G" android:translateX="20.75" android:translateY="15.75"><path android:name="_R_G_L_1_G_D_0_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M27.52 38.98 C26.49,39.95 25.29,40.73 23.98,41.29 C23.17,41.65 22.31,41.91 21.41,42.07 C20.74,42.19 20.05,42.25 19.34,42.25 C18.44,42.25 17.56,42.15 16.72,41.96 C15.93,41.77 15.16,41.51 14.43,41.18 C13.23,40.63 12.13,39.88 11.16,38.98 "/><path android:name="_R_G_L_1_G_D_1_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M8.64 34.07 C7.89,31.97 7.89,29.85 7.89,29.85 C7.89,24.05 12.81,19.34 19.34,19.34 C25.87,19.34 30.8,24.05 30.8,29.85 C30.8,29.85 30.8,30.16 30.8,30.16 C30.8,32.32 29.04,34.07 26.89,34.07 C25.28,34.07 23.86,33.1 23.27,31.61 C23.27,31.61 21.96,28.34 21.96,28.34 C21.37,26.85 19.93,25.89 18.34,25.89 C16.18,25.89 14.43,27.64 14.43,29.8 C14.43,31.42 14.87,32.99 15.68,34.36 C16.22,35.26 16.93,36.08 17.77,36.75 C17.77,36.75 18.52,37.34 18.52,37.34 "/><path android:name="_R_G_L_1_G_D_2_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M6.25 19.34 C7.48,17.3 9.46,15.58 11.9,14.42 C12.93,13.94 14.03,13.55 15.2,13.27 C16.51,12.96 17.9,12.8 19.34,12.8 C20.77,12.8 22.14,12.96 23.45,13.26 C24.9,13.6 26.26,14.12 27.48,14.78 C29.6,15.92 31.32,17.5 32.43,19.34 "/><path android:name="_R_G_L_1_G_D_3_P_0" android:strokeColor="#d3e3fd" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2" android:strokeAlpha="1" android:pathData=" M9.52 8.7 C10.98,7.91 12.58,7.28 14.28,6.86 C15.89,6.46 17.58,6.25 19.34,6.25 C21.06,6.25 22.72,6.45 24.3,6.83 C26.04,7.25 27.67,7.89 29.16,8.7 "/></group><group android:name="_R_G_L_0_G" android:translateX="37.357" android:translateY="43.25" android:pivotX="2.75" android:pivotY="2.75" android:scaleX="1.41866" android:scaleY="1.41866"><path android:name="_R_G_L_0_G_D_0_P_0" android:fillColor="#d3e3fd" android:fillAlpha="0" android:fillType="nonZero" android:pathData=" M2.75 5.25 C4.13,5.25 5.25,4.13 5.25,2.75 C5.25,1.37 4.13,0.25 2.75,0.25 C1.37,0.25 0.25,1.37 0.25,2.75 C0.25,4.13 1.37,5.25 2.75,5.25c "/></group></group><group android:name="time_group"/></vector></aapt:attr><target android:name="_R_G_L_1_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="107" android:startOffset="0" android:valueFrom="M27.52 38.98 C26.49,39.95 25.29,40.73 23.98,41.29 C23.17,41.65 22.31,41.91 21.41,42.07 C20.74,42.19 20.05,42.25 19.34,42.25 C18.44,42.25 17.56,42.15 16.72,41.96 C15.93,41.77 15.16,41.51 14.43,41.18 C13.23,40.63 12.13,39.88 11.16,38.98 " android:valueTo="M30.81 32.26 C30.56,32.49 30.27,38.76 29.96,38.9 C29.77,39.46 29.13,39.94 28.57,40.26 C28.15,40.51 26.93,40.65 26.4,40.65 C26.18,40.65 11.91,40.62 11.71,40.58 C10.68,40.53 9.06,39.79 8.89,38.88 C8.6,38.74 8.34,32.48 8.1,32.27 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.833,0.767 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="143" android:startOffset="107" android:valueFrom="M30.81 32.26 C30.56,32.49 30.27,38.76 29.96,38.9 C29.77,39.46 29.13,39.94 28.57,40.26 C28.15,40.51 26.93,40.65 26.4,40.65 C26.18,40.65 11.91,40.62 11.71,40.58 C10.68,40.53 9.06,39.79 8.89,38.88 C8.6,38.74 8.34,32.48 8.1,32.27 " android:valueTo="M30.64 30.14 C30.64,30.14 30.64,38.14 30.64,38.14 C30.64,38.77 30.36,39.32 29.91,39.69 C29.57,39.97 29.12,40.14 28.64,40.14 C28.64,40.14 10.14,40.14 10.14,40.14 C9.04,40.14 8.14,39.25 8.14,38.14 C8.14,38.14 8.14,30.14 8.14,30.14 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0.331,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="strokeAlpha" android:duration="140" android:startOffset="0" android:valueFrom="1" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="strokeAlpha" android:duration="50" android:startOffset="140" android:valueFrom="1" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_1_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="107" android:startOffset="0" android:valueFrom="M8.64 34.07 C7.89,31.97 7.89,29.85 7.89,29.85 C7.89,24.05 12.81,19.34 19.34,19.34 C25.87,19.34 30.8,24.05 30.8,29.85 C30.8,29.85 30.8,30.16 30.8,30.16 C30.8,32.32 29.04,34.07 26.89,34.07 C25.28,34.07 23.86,33.1 23.27,31.61 C23.27,31.61 21.96,28.34 21.96,28.34 C21.37,26.85 19.93,25.89 18.34,25.89 C16.18,25.89 14.43,27.64 14.43,29.8 C14.43,31.42 14.87,32.99 15.68,34.36 C16.22,35.26 16.93,36.08 17.77,36.75 C17.77,36.75 18.52,37.34 18.52,37.34 " android:valueTo="M18.93 32.18 C17.11,32.68 16.62,30.26 16.62,30.26 C16.62,28.78 17.81,27.59 19.39,27.59 C20.96,27.59 22.15,28.78 22.15,30.26 C22.15,30.26 22.15,30.34 22.15,30.34 C22.15,30.89 21.11,32.54 19.57,32.19 C19.19,32.1 20.48,31.09 20.34,30.71 C20.34,30.71 20.02,29.88 20.02,29.88 C19.88,29.5 19.53,29.25 19.15,29.25 C18.63,29.25 18,29.67 18,30.22 C18,30.57 18.06,31.08 18.32,31.51 C18.49,31.8 19.02,32.25 19.79,32.04 C20.41,31.7 20.38,31.36 20.38,31.36 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.833,0.767 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="107" android:startOffset="107" android:valueFrom="M18.93 32.18 C17.11,32.68 16.62,30.26 16.62,30.26 C16.62,28.78 17.81,27.59 19.39,27.59 C20.96,27.59 22.15,28.78 22.15,30.26 C22.15,30.26 22.15,30.34 22.15,30.34 C22.15,30.89 21.11,32.54 19.57,32.19 C19.19,32.1 20.48,31.09 20.34,30.71 C20.34,30.71 20.02,29.88 20.02,29.88 C19.88,29.5 19.53,29.25 19.15,29.25 C18.63,29.25 18,29.67 18,30.22 C18,30.57 18.06,31.08 18.32,31.51 C18.49,31.8 19.02,32.25 19.79,32.04 C20.41,31.7 20.38,31.36 20.38,31.36 " android:valueTo="M19.42 31.53 C18.15,31.52 18.11,30.33 18.11,30.33 C18.11,29.59 18.66,28.98 19.4,28.98 C20.13,28.98 20.69,29.59 20.69,30.33 C20.69,30.33 20.69,30.37 20.69,30.37 C20.69,30.64 20.49,30.87 20.25,30.87 C20.07,30.87 19.91,30.74 19.84,30.55 C19.84,30.55 19.69,30.14 19.69,30.14 C19.63,29.94 19.46,29.82 19.28,29.82 C19.04,29.82 18.61,30.02 18.61,30.29 C18.61,30.43 18.6,30.75 18.76,31.03 C18.87,31.21 19.21,31.77 19.96,31.41 C20.69,31.01 20.69,30.34 20.69,30.34 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_2_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="250" android:startOffset="0" android:valueFrom="M6.25 19.34 C7.48,17.3 9.46,15.58 11.9,14.42 C12.93,13.94 14.03,13.55 15.2,13.27 C16.51,12.96 17.9,12.8 19.34,12.8 C20.77,12.8 22.14,12.96 23.45,13.26 C24.9,13.6 26.26,14.12 27.48,14.78 C29.6,15.92 31.32,17.5 32.43,19.34 " android:valueTo="M8.14 30.22 C8.14,30.22 8.14,22.22 8.14,22.22 C8.14,21.71 8.33,21.25 8.64,20.9 C9,20.48 9.54,20.22 10.14,20.22 C10.14,20.22 28.64,20.22 28.64,20.22 C29.75,20.22 30.64,21.11 30.64,22.22 C30.64,22.22 30.64,30.14 30.64,30.14 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.189,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_1_G_D_3_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="pathData" android:duration="95" android:startOffset="0" android:valueFrom="M9.52 8.7 C10.98,7.91 12.58,7.28 14.28,6.86 C15.89,6.46 17.58,6.25 19.34,6.25 C21.06,6.25 22.72,6.45 24.3,6.83 C26.04,7.25 27.67,7.89 29.16,8.7 " android:valueTo="M11.47 14.84 C11.47,14.84 12.21,11.43 13.54,9.84 C14.84,8.28 16.68,7.22 19.35,7.22 C22.01,7.22 23.98,8.4 25.19,10.18 C26.39,11.96 27.25,14.84 27.25,14.84 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.541,0 0.833,0.767 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="24" android:startOffset="95" android:valueFrom="M11.47 14.84 C11.47,14.84 12.21,11.43 13.54,9.84 C14.84,8.28 16.68,7.22 19.35,7.22 C22.01,7.22 23.98,8.4 25.19,10.18 C26.39,11.96 27.25,14.84 27.25,14.84 " android:valueTo="M12.11 16.85 C12.11,16.85 12.82,12.71 13.37,11.5 C14.17,9.24 16.38,7.53 19.35,7.53 C22.32,7.53 24.61,9.32 25.35,11.72 C25.61,12.64 26.62,16.85 26.62,16.85 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0.833,0.767 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="81" android:startOffset="119" android:valueFrom="M12.11 16.85 C12.11,16.85 12.82,12.71 13.37,11.5 C14.17,9.24 16.38,7.53 19.35,7.53 C22.32,7.53 24.61,9.32 25.35,11.72 C25.61,12.64 26.62,16.85 26.62,16.85 " android:valueTo="M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.233 0.261,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="pathData" android:duration="233" android:startOffset="200" android:valueFrom="M13.12 20.04 C13.12,20.04 13.11,14.15 13.11,14.15 C13.11,10.77 15.91,8.04 19.36,8.04 C22.81,8.04 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueTo="M37.91 20.05 C37.91,20.05 37.89,14.16 37.89,14.16 C37.89,10.79 35.15,8.05 31.86,8.03 C28.46,8.01 25.61,10.77 25.61,14.15 C25.61,14.15 25.62,20.04 25.62,20.04 " android:valueType="pathType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.123,0 0.23,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G_D_0_P_0"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="fillAlpha" android:duration="120" android:startOffset="0" android:valueFrom="0" android:valueTo="0" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="fillAlpha" android:duration="20" android:startOffset="120" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="_R_G_L_0_G"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="scaleX" android:duration="120" android:startOffset="0" android:valueFrom="1.4186600000000003" android:valueTo="1.4186600000000003" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="120" android:startOffset="0" android:valueFrom="1.4186600000000003" android:valueTo="1.4186600000000003" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleX" android:duration="130" android:startOffset="120" android:valueFrom="1.4186600000000003" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0"/></aapt:attr></objectAnimator><objectAnimator android:propertyName="scaleY" android:duration="130" android:startOffset="120" android:valueFrom="1.4186600000000003" android:valueTo="1" android:valueType="floatType"><aapt:attr name="android:interpolator"><pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.43,1 1.0,1.0"/></aapt:attr></objectAnimator></set></aapt:attr></target><target android:name="time_group"><aapt:attr name="android:animation"><set android:ordering="together"><objectAnimator android:propertyName="translateX" android:duration="517" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/></set></aapt:attr></target></animated-vector>
\ No newline at end of file
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-land-television/volume_dialog.xml b/packages/SystemUI/res/layout-land-television/volume_dialog.xml
index 6b5629f..0fbc519 100644
--- a/packages/SystemUI/res/layout-land-television/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land-television/volume_dialog.xml
@@ -73,8 +73,7 @@
                 android:layout_height="match_parent"
                 android:tint="@color/caption_tint_color_selector"
                 android:layout_gravity="center"
-                android:soundEffectsEnabled="false"
-                sysui:optedOut="false"/>
+                android:soundEffectsEnabled="false"/>
 
         </FrameLayout>
 
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index f1cda27..3b70dc0 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -136,8 +136,7 @@
                 android:layout_height="match_parent"
                 android:tint="?android:attr/colorAccent"
                 android:layout_gravity="center"
-                android:soundEffectsEnabled="false"
-                sysui:optedOut="false"/>
+                android:soundEffectsEnabled="false" />
         </FrameLayout>
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/auth_biometric_contents.xml b/packages/SystemUI/res/layout/auth_biometric_contents.xml
index 89690e8..58adb91 100644
--- a/packages/SystemUI/res/layout/auth_biometric_contents.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_contents.xml
@@ -49,8 +49,8 @@
 
         <ImageView
             android:id="@+id/biometric_icon"
-            android:layout_width="@dimen/biometric_dialog_biometric_icon_size"
-            android:layout_height="@dimen/biometric_dialog_biometric_icon_size"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_gravity="center"
             android:contentDescription="@null"
             android:scaleType="fitXY" />
diff --git a/packages/SystemUI/res/layout/auth_biometric_face_to_fingerprint_view.xml b/packages/SystemUI/res/layout/auth_biometric_fingerprint_and_face_view.xml
similarity index 83%
rename from packages/SystemUI/res/layout/auth_biometric_face_to_fingerprint_view.xml
rename to packages/SystemUI/res/layout/auth_biometric_fingerprint_and_face_view.xml
index 7cf1789..05ca2a7 100644
--- a/packages/SystemUI/res/layout/auth_biometric_face_to_fingerprint_view.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_fingerprint_and_face_view.xml
@@ -14,12 +14,13 @@
   ~ limitations under the License.
   -->
 
-<com.android.systemui.biometrics.AuthBiometricFaceToFingerprintView
+<com.android.systemui.biometrics.AuthBiometricFingerprintAndFaceView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/contents"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical">
 
     <include layout="@layout/auth_biometric_contents"/>
 
-</com.android.systemui.biometrics.AuthBiometricFaceToFingerprintView>
\ No newline at end of file
+</com.android.systemui.biometrics.AuthBiometricFingerprintAndFaceView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/auth_biometric_udfps_view.xml b/packages/SystemUI/res/layout/auth_biometric_view.xml
similarity index 83%
rename from packages/SystemUI/res/layout/auth_biometric_udfps_view.xml
rename to packages/SystemUI/res/layout/auth_biometric_view.xml
index 238288e..ee4da25 100644
--- a/packages/SystemUI/res/layout/auth_biometric_udfps_view.xml
+++ b/packages/SystemUI/res/layout/auth_biometric_view.xml
@@ -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,7 +14,7 @@
   ~ limitations under the License.
   -->
 
-<com.android.systemui.biometrics.AuthBiometricUdfpsView
+<com.android.systemui.biometrics.AuthBiometricView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/contents"
     android:layout_width="match_parent"
@@ -23,4 +23,4 @@
 
     <include layout="@layout/auth_biometric_contents"/>
 
-</com.android.systemui.biometrics.AuthBiometricUdfpsView>
\ No newline at end of file
+</com.android.systemui.biometrics.AuthBiometricView>
\ No newline at end of file
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/communal_host_view.xml b/packages/SystemUI/res/layout/communal_host_view.xml
deleted file mode 100644
index cd9c260..0000000
--- a/packages/SystemUI/res/layout/communal_host_view.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="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.
-  -->
-
-<!-- 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
diff --git a/packages/SystemUI/res/layout/dream_overlay_complication_preview.xml b/packages/SystemUI/res/layout/dream_overlay_complication_preview.xml
new file mode 100644
index 0000000..ca5c499
--- /dev/null
+++ b/packages/SystemUI/res/layout/dream_overlay_complication_preview.xml
@@ -0,0 +1,28 @@
+<?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.
+  -->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/dream_preview_text"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:textSize="@dimen/dream_overlay_complication_preview_text_size"
+    android:textColor="@android:color/white"
+    android:shadowColor="@color/keyguard_shadow_color"
+    android:shadowRadius="?attr/shadowRadius"
+    android:gravity="center_vertical"
+    android:drawableStart="@drawable/dream_preview_back_arrow"
+    android:drawablePadding="@dimen/dream_overlay_complication_preview_icon_padding"/>
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 813787e..d0f4903 100644
--- a/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_status_bar_view.xml
@@ -29,7 +29,6 @@
         android:layout_width="@dimen/dream_overlay_notification_indicator_size"
         android:layout_height="@dimen/dream_overlay_notification_indicator_size"
         android:visibility="gone"
-        android:contentDescription="@string/dream_overlay_status_bar_notification_indicator"
         app:dotColor="@android:color/white"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
@@ -43,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"
@@ -68,7 +56,7 @@
             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_remove_circle"
+            android:src="@drawable/ic_qs_dnd_on"
             android:tint="@android:color/white"
             android:visibility="gone"
             android:contentDescription="@string/dream_overlay_status_bar_priority_mode" />
diff --git a/packages/SystemUI/res/layout/foreground_service_dungeon.xml b/packages/SystemUI/res/layout/foreground_service_dungeon.xml
deleted file mode 100644
index d4e98e2..0000000
--- a/packages/SystemUI/res/layout/foreground_service_dungeon.xml
+++ /dev/null
@@ -1,61 +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.
-  -->
-
-<com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/foreground_service_dungeon"
-    android:layout_width="@dimen/qs_panel_width"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center_horizontal|bottom"
-    android:visibility="visible"
->
-    <LinearLayout
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:orientation="vertical"
-        android:gravity="bottom"
-        android:visibility="visible"
-        android:background="@drawable/notif_dungeon_bg_gradient"
-    >
-
-        <!-- divider view -->
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="1dp"
-            android:background="@color/GM2_grey_200"
-            android:visibility="visible"
-        />
-
-        <TextView
-            android:id="@+id/dungeon_title"
-            android:layout_height="48dp"
-            android:layout_width="match_parent"
-            android:padding="8dp"
-            android:text="Apps active in background"
-            android:textColor="@color/GM2_grey_200"
-        />
-
-        <!--  List containing the actual foreground service notifications  -->
-        <LinearLayout
-            android:id="@+id/entry_list"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="bottom"
-            android:orientation="vertical" >
-        </LinearLayout>
-
-    </LinearLayout>
-</com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView>
diff --git a/packages/SystemUI/res/layout/foreground_service_dungeon_row.xml b/packages/SystemUI/res/layout/foreground_service_dungeon_row.xml
deleted file mode 100644
index a6f1638..0000000
--- a/packages/SystemUI/res/layout/foreground_service_dungeon_row.xml
+++ /dev/null
@@ -1,43 +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.
-  -->
-
-<com.android.systemui.statusbar.notification.row.DungeonRow
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/foreground_service_dungeon_row"
-    android:layout_width="match_parent"
-    android:layout_height="48dp"
-    android:padding="8dp"
-    android:clickable="true"
-    android:orientation="horizontal" >
-
-    <com.android.systemui.statusbar.StatusBarIconView
-        android:id="@+id/icon"
-        android:layout_width="24dp"
-        android:layout_height="24dp"
-        android:padding="4dp" />
-
-    <TextView
-        android:id="@+id/app_name"
-        android:layout_width="0dp"
-        android:layout_weight="1"
-        android:layout_height="wrap_content"
-        android:paddingStart="4dp"
-        android:gravity="center_vertical"
-        android:layout_gravity="center_vertical"
-        android:textColor="@color/GM2_grey_200"
-    />
-
-</com.android.systemui.statusbar.notification.row.DungeonRow>
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_projection_dialog_title.xml b/packages/SystemUI/res/layout/media_projection_dialog_title.xml
deleted file mode 100644
index b9e39da..0000000
--- a/packages/SystemUI/res/layout/media_projection_dialog_title.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2019, The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:theme="@style/Theme.SystemUI.MediaProjectionAlertDialog"
-        android:paddingStart="?android:attr/dialogPreferredPadding"
-        android:paddingEnd="?android:attr/dialogPreferredPadding"
-        android:orientation="vertical">
-    <ImageView
-        android:id="@+id/dialog_icon"
-        android:src="@drawable/ic_media_projection_permission"
-        android:layout_height="24dp"
-        android:layout_width="24dp"
-        android:layout_marginTop="18dp"
-        android:layout_marginBottom="12dp"
-        android:layout_gravity="center_horizontal" />
-    <TextView
-        android:id="@+id/dialog_title"
-        android:gravity="center"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:textSize="20sp"
-        android:textColor="?android:attr/textColorPrimary"
-        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Title" />
-</LinearLayout>
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 978998d..9ad0152 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -139,7 +139,7 @@
         android:layout_height="wrap_content"
         android:layout_marginEnd="@dimen/qs_media_padding"
         app:layout_constrainedWidth="true"
-        android:layout_marginTop="1dp"
+        android:layout_marginTop="0dp"
         app:layout_constraintTop_toBottomOf="@id/header_title"
         app:layout_constraintStart_toStartOf="@id/header_title"
         app:layout_constraintEnd_toStartOf="@id/actionPlayPause"
diff --git a/packages/SystemUI/res/layout/media_ttt_chip.xml b/packages/SystemUI/res/layout/media_ttt_chip.xml
index a5fdcd9..a502d33 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip.xml
@@ -16,6 +16,7 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:id="@+id/media_ttt_sender_chip"
     android:orientation="horizontal"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
diff --git a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
index 88feacd..5e8b892 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip_receiver.xml
@@ -17,6 +17,7 @@
 <!-- TODO(b/203800646): layout_marginTop doesn't seem to work on some large screens. -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/media_ttt_receiver_chip"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:background="@drawable/media_ttt_chip_background_receiver"
diff --git a/packages/SystemUI/res/layout/notif_half_shelf.xml b/packages/SystemUI/res/layout/notif_half_shelf.xml
index b2ff46e..8ba1ff3 100644
--- a/packages/SystemUI/res/layout/notif_half_shelf.xml
+++ b/packages/SystemUI/res/layout/notif_half_shelf.xml
@@ -27,7 +27,7 @@
 
     <LinearLayout
         android:id="@+id/half_shelf"
-        android:layout_width="@dimen/qs_panel_width"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:gravity="bottom"
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 c7910afc..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"
@@ -94,10 +91,11 @@
         <FrameLayout
             android:id="@+id/qs_frame"
             android:layout="@layout/qs_panel"
-            android:layout_width="@dimen/qs_panel_width"
+            android:layout_width="0dp"
             android:layout_height="0dp"
             android:clipToPadding="false"
             android:clipChildren="false"
+            android:layout_marginHorizontal="@dimen/notification_panel_margin_horizontal"
             systemui:viewType="com.android.systemui.plugins.qs.QS"
             systemui:layout_constraintStart_toStartOf="parent"
             systemui:layout_constraintEnd_toEndOf="parent"
@@ -115,8 +113,9 @@
         <com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
             android:id="@+id/notification_stack_scroller"
             android:layout_marginTop="@dimen/notification_panel_margin_top"
-            android:layout_width="@dimen/notification_panel_width"
+            android:layout_width="0dp"
             android:layout_height="match_parent"
+            android:layout_marginHorizontal="@dimen/notification_panel_margin_horizontal"
             android:layout_marginBottom="@dimen/notification_panel_margin_bottom"
             android:importantForAccessibility="no"
             systemui:layout_constraintStart_toStartOf="parent"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
index 65f55d0..8a2310b 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/plugin_frame"
     android:theme="@style/Theme.SystemUI.QuickSettings"
-    android:layout_width="@dimen/qs_panel_width"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_gravity="center_horizontal"
     android:layout_marginTop="@dimen/notification_side_paddings"
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/user_switcher_fullscreen.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
index 2d883bc..0f2d372 100644
--- a/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
+++ b/packages/SystemUI/res/layout/user_switcher_fullscreen.xml
@@ -21,9 +21,8 @@
     android:id="@+id/user_switcher_root"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_marginBottom="40dp"
-    android:layout_marginEnd="60dp"
-    android:layout_marginStart="60dp">
+    android:layout_marginVertical="40dp"
+    android:layout_marginHorizontal="60dp">
 
   <androidx.constraintlayout.helper.widget.Flow
       android:id="@+id/flow"
@@ -36,7 +35,7 @@
       app:flow_horizontalBias="0.5"
       app:flow_verticalAlign="center"
       app:flow_wrapMode="chain"
-      app:flow_horizontalGap="64dp"
+      app:flow_horizontalGap="@dimen/user_switcher_fullscreen_horizontal_gap"
       app:flow_verticalGap="44dp"
       app:flow_horizontalStyle="packed"/>
 
@@ -56,16 +55,17 @@
 
   <TextView
       android:id="@+id/add"
-      android:visibility="gone"
+      style="@style/Widget.Dialog.Button.BorderButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center"
       android:gravity="center"
-      app:layout_constraintHeight_min="48dp"
-      app:layout_constraintEnd_toEndOf="parent"
-      app:layout_constraintBottom_toBottomOf="parent"
       android:paddingHorizontal="@dimen/user_switcher_fullscreen_button_padding"
-      android:textSize="@dimen/user_switcher_fullscreen_button_text_size"
+      android:text="@string/add"
       android:textColor="?androidprv:attr/colorAccentPrimary"
-      android:text="@string/add" />
+      android:textSize="@dimen/user_switcher_fullscreen_button_text_size"
+      android:visibility="gone"
+      app:layout_constraintBottom_toBottomOf="parent"
+      app:layout_constraintEnd_toEndOf="parent"
+      app:layout_constraintHeight_min="48dp" />
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/user_switcher_fullscreen_item.xml b/packages/SystemUI/res/layout/user_switcher_fullscreen_item.xml
index 3319442..60e840c 100644
--- a/packages/SystemUI/res/layout/user_switcher_fullscreen_item.xml
+++ b/packages/SystemUI/res/layout/user_switcher_fullscreen_item.xml
@@ -13,21 +13,30 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
-<LinearLayout
+<androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:orientation="vertical">
-  <ImageView
-      android:id="@+id/user_switcher_icon"
-      android:layout_gravity="center"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content" />
-  <TextView
-      style="@style/Bouncer.UserSwitcher.Spinner.Item"
-      android:id="@+id/user_switcher_text"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:textColor="@*android:color/text_color_primary_device_default_dark"
-      android:layout_gravity="center" />
-</LinearLayout>
+
+    <ImageView
+        android:id="@+id/user_switcher_icon"
+        android:layout_width="@dimen/bouncer_user_switcher_icon_size_plus_margin"
+        android:layout_height="@dimen/bouncer_user_switcher_icon_size_plus_margin"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <TextView
+        android:id="@+id/user_switcher_text"
+        style="@style/Bouncer.UserSwitcher.Spinner.Item"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:ellipsize="end"
+        android:gravity="center"
+        android:textColor="@*android:color/text_color_primary_device_default_dark"
+        app:layout_constraintEnd_toEndOf="@id/user_switcher_icon"
+        app:layout_constraintStart_toStartOf="@id/user_switcher_icon"
+        app:layout_constraintTop_toBottomOf="@id/user_switcher_icon" />
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 51718d9..6a192d4 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -135,8 +135,7 @@
                 android:layout_height="match_parent"
                 android:tint="?android:attr/colorAccent"
                 android:layout_gravity="center"
-                android:soundEffectsEnabled="false"
-                sysui:optedOut="false"/>
+                android:soundEffectsEnabled="false"/>
         </FrameLayout>
     </LinearLayout>
 
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/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 01eb09b..c386a3e 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -22,7 +22,6 @@
     <dimen name="docked_divider_handle_width">2dp</dimen>
     <dimen name="docked_divider_handle_height">16dp</dimen>
 
-    <dimen name="qs_tile_height">84dp</dimen>
     <dimen name="qs_brightness_margin_top">0dp</dimen>
     <dimen name="qs_brightness_margin_bottom">12dp</dimen>
     <dimen name="qqs_layout_margin_top">8dp</dimen>
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 c37c804..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,12 +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 the keyguard content on
+         NotificationPanelViewController to fully fade (e.g. Clock & Smartspace) -->
+    <dimen name="lockscreen_shade_npvc_keyguard_content_alpha_transition_distance">80dp</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 da2403a..c990605 100644
--- a/packages/SystemUI/res/values-sw600dp-port/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -15,7 +15,9 @@
   ~ limitations under the License.
   -->
 <resources>
-    <!-- Size of the panel of large phones on portrait. This shouldn't fill, but have some padding on the side -->
-    <dimen name="notification_panel_width">504dp</dimen>
-
+    <dimen name="notification_panel_margin_horizontal">60dp</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>
+    <dimen name="bouncer_user_switcher_y_trans">20dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
index e897f75..f267088 100644
--- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw720dp-land/dimens.xml
@@ -22,4 +22,8 @@
     <dimen name="notification_panel_margin_bottom">56dp</dimen>
 
     <dimen name="keyguard_split_shade_top_margin">72dp</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
new file mode 100644
index 0000000..e5f502f
--- /dev/null
+++ b/packages/SystemUI/res/values-sw720dp-port/dimens.xml
@@ -0,0 +1,28 @@
+<?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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     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>
+</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/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index c5e005c..62903d5 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -154,10 +154,6 @@
         <attr name="showAirplaneMode" format="boolean" />
     </declare-styleable>
 
-    <declare-styleable name="CaptionsToggleImageButton">
-        <attr name="optedOut" format="boolean" />
-    </declare-styleable>
-
     <declare-styleable name="IlluminationDrawable">
         <attr name="highlight" format="integer" />
         <attr name="cornerRadius" format="dimension" />
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/config.xml b/packages/SystemUI/res/values/config.xml
index 178f93a..a0a8768 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -74,7 +74,12 @@
 
     <!-- The default tiles to display in QuickSettings -->
     <string name="quick_settings_tiles_default" translatable="false">
-        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle
+        internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,custom(com.android.permissioncontroller/.permission.service.SafetyCenterQsTileService)
+    </string>
+
+    <!-- The component name of the Safety Quick Settings Tile -->
+    <string name="safety_quick_settings_tile" translatable="false">
+        custom(com.android.permissioncontroller/.permission.service.SafetyCenterQsTileService)
     </string>
 
     <!-- The minimum number of tiles to display in QuickSettings -->
@@ -482,6 +487,9 @@
      space -->
     <bool name="config_showBatteryEstimateQSBH">false</bool>
 
+    <!-- Whether to show a severe low battery dialog. -->
+    <bool name="config_severe_battery_dialog">false</bool>
+
     <!-- A path similar to frameworks/base/core/res/res/values/config.xml
       config_mainBuiltInDisplayCutout that describes a path larger than the exact path of a display
       cutout. If present as well as config_enableDisplayCutoutProtection is set to true, then
@@ -690,4 +698,13 @@
 
     <!-- How often in milliseconds to jitter the dream overlay in order to avoid burn-in. -->
     <integer name="config_dreamOverlayBurnInProtectionUpdateIntervalMillis">500</integer>
+
+    <!-- How long in milliseconds before full burn-in protection is achieved. -->
+    <integer name="config_dreamOverlayMillisUntilFullJitter">240000</integer>
+
+    <integer name="complicationFadeOutMs">500</integer>
+
+    <integer name="complicationFadeInMs">500</integer>
+
+    <integer name="complicationRestoreMs">1000</integer>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index fcf60bf..5ca7285 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -388,13 +388,10 @@
 
     <dimen name="split_shade_notifications_scrim_margin_bottom">0dp</dimen>
 
-    <dimen name="notification_panel_width">@dimen/match_parent</dimen>
+    <dimen name="notification_panel_margin_horizontal">0dp</dimen>
 
     <dimen name="brightness_mirror_height">48dp</dimen>
 
-    <!-- The width of the panel that holds the quick settings. -->
-    <dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
-
     <dimen name="volume_dialog_panel_transparent_padding_right">8dp</dimen>
 
     <dimen name="volume_dialog_panel_transparent_padding">20dp</dimen>
@@ -470,7 +467,7 @@
     <dimen name="pull_span_min">25dp</dimen>
 
     <dimen name="qs_corner_radius">28dp</dimen>
-    <dimen name="qs_tile_height">84dp</dimen>
+    <dimen name="qs_tile_height">80dp</dimen>
     <dimen name="qs_tile_margin_horizontal">8dp</dimen>
     <dimen name="qs_tile_margin_vertical">@dimen/qs_tile_margin_horizontal</dimen>
     <dimen name="qs_tile_margin_top_bottom">4dp</dimen>
@@ -879,7 +876,8 @@
     <dimen name="remote_input_history_extra_height">60dp</dimen>
 
     <!-- Biometric Dialog values -->
-    <dimen name="biometric_dialog_biometric_icon_size">64dp</dimen>
+    <dimen name="biometric_dialog_face_icon_size">64dp</dimen>
+    <dimen name="biometric_dialog_fingerprint_icon_size">80dp</dimen>
     <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen>
     <dimen name="biometric_dialog_button_positive_max_width">136dp</dimen>
     <dimen name="biometric_dialog_corner_size">4dp</dimen>
@@ -1124,13 +1122,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 -->
@@ -1347,6 +1372,8 @@
     <dimen name="dream_overlay_complication_clock_time_text_size">72sp</dimen>
     <dimen name="dream_overlay_complication_clock_date_text_size">18sp</dimen>
     <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>
 
     <!-- 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
@@ -1389,4 +1416,6 @@
 
     <!-- The margin applied between complications -->
     <dimen name="dream_overlay_complication_margin">0dp</dimen>
+
+    <dimen name="status_view_margin_horizontal">0dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index df16b0d..9f2f1c1 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -21,7 +21,13 @@
     <string name="app_label">System UI</string>
 
     <!-- When the battery is low, this is displayed to the user in a dialog.  The title of the low battery alert.  [CHAR LIMIT=NONE]-->
-    <string name="battery_low_title">Battery may run out soon</string>
+    <string name="battery_low_title">Turn on Battery Saver?</string>
+
+    <!-- When the battery is low, this is displayed to the user in a dialog.  The description of the low battery alert.  [CHAR LIMIT=NONE]-->
+    <string name="battery_low_description">You have <xliff:g id="percentage" example="20%">%s</xliff:g> battery left. Battery Saver turns on Dark theme, restricts background activity, and delays notifications.</string>
+
+    <!-- When the battery is low at first time, this is displayed to the user in a dialog.  The description of the low battery alert.  [CHAR LIMIT=NONE]-->
+    <string name="battery_low_intro">Battery Saver turns on Dark theme, restricts background activity, and delays notifications.</string>
 
     <!-- A message that appears when the battery level is getting low in a dialog.  This is
         appended to the subtitle of the low battery alert.  "percentage" is the percentage of battery
@@ -60,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] -->
 
@@ -316,6 +325,8 @@
     <string name="biometric_dialog_face_icon_description_confirmed">Confirmed</string>
     <!-- Message shown when a biometric is authenticated, waiting for the user to confirm authentication [CHAR LIMIT=40]-->
     <string name="biometric_dialog_tap_confirm">Tap Confirm to complete</string>
+    <!-- Message shown when a biometric has authenticated with a user's face and is waiting for the user to confirm authentication [CHAR LIMIT=60]-->
+    <string name="biometric_dialog_tap_confirm_with_face">Unlocked by your face. Press to continue.</string>
     <!-- Talkback string when a biometric is authenticated [CHAR LIMIT=NONE] -->
     <string name="biometric_dialog_authenticated">Authenticated</string>
 
@@ -441,8 +452,8 @@
     <string name="accessibility_quick_settings_dnd_none_on">total silence</string>
     <!-- Content description of the do not disturb tile in quick settings when on in alarms only (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_alarms_on">alarms only</string>
-     <!-- Content description of the priority mode tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_quick_settings_dnd" translatable="false">Priority mode.</string>
+     <!-- Content description of the do not disturb tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_dnd">Do Not Disturb.</string>
     <!-- Content description of the bluetooth tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_bluetooth">Bluetooth.</string>
     <!-- Content description of the bluetooth tile in quick settings when on (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -520,8 +531,8 @@
     <string name="ethernet_label">Ethernet</string>
 
     <!-- QuickSettings: Onboarding text that introduces users to long press on an option in order to view the option's menu in Settings [CHAR LIMIT=NONE] -->
-    <!-- QuickSettings: Priority mode [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_dnd_label" translatable="false">Priority mode</string>
+    <!-- QuickSettings: Do not disturb [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_dnd_label">Do Not Disturb</string>
     <!-- QuickSettings: Do not disturb - Priority only [CHAR LIMIT=NONE] -->
     <!-- QuickSettings: Do not disturb - Alarms only [CHAR LIMIT=NONE] -->
     <!-- QuickSettings: Do not disturb - Total silence [CHAR LIMIT=NONE] -->
@@ -909,8 +920,8 @@
     <!-- Content description for accessibility: Tapping this button will dismiss all gentle notifications [CHAR LIMIT=NONE] -->
     <string name="accessibility_notification_section_header_gentle_clear_all">Clear all silent notifications</string>
 
-    <!-- The text to show in the notifications shade when Priority mode is suppressing notifications. [CHAR LIMIT=100] -->
-    <string name="dnd_suppressing_shade_text" translatable="false">Notifications paused by Priority mode</string>
+    <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
+    <string name="dnd_suppressing_shade_text">Notifications paused by Do Not Disturb</string>
 
     <!-- Media projection permission dialog action text. [CHAR LIMIT=60] -->
     <string name="media_projection_action_text">Start now</string>
@@ -1329,8 +1340,8 @@
     <!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
     <string name="notification_channel_summary_priority_baseline">Shows at the top of conversation notifications and as a profile picture on lock screen</string>
     <string name="notification_channel_summary_priority_bubble">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" translatable="false">Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Priority mode</string>
-    <string name="notification_channel_summary_priority_all" translatable="false">Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Priority mode</string>
+    <string name="notification_channel_summary_priority_dnd">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">Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb</string>
 
     <!-- [CHAR LIMIT=150] Notification Importance title: important conversation level -->
     <string name="notification_priority_title">Priority</string>
@@ -1521,8 +1532,8 @@
     <!-- User visible title for the keyboard shortcut that takes the user to the calendar app. -->
     <string name="keyboard_shortcut_group_applications_calendar">Calendar</string>
 
-    <!-- SysUI Tuner: Label for screen about priority mode settings [CHAR LIMIT=60] -->
-    <string name="volume_and_do_not_disturb" translatable="false">Priority mode</string>
+    <!-- SysUI Tuner: Label for screen about do not disturb settings [CHAR LIMIT=60] -->
+    <string name="volume_and_do_not_disturb">Do Not Disturb</string>
 
     <!-- SysUI Tuner: Switch to control whether volume buttons enter/exit do
          not disturb [CHAR LIMIT=60] -->
@@ -1878,17 +1889,17 @@
     <!-- Label for when bluetooth is off in QS detail panel [CHAR LIMIT=NONE] -->
     <string name="bt_is_off">Bluetooth is off</string>
 
-    <!-- Label for when Priority mode is off in QS detail panel [CHAR LIMIT=NONE] -->
-    <string name="dnd_is_off" translatable="false">Priority mode is off</string>
+    <!-- Label for when Do not disturb is off in QS detail panel [CHAR LIMIT=NONE] -->
+    <string name="dnd_is_off">Do Not Disturb is off</string>
 
-    <!-- Prompt for when Priority mode is on from automatic rule in QS [CHAR LIMIT=NONE] -->
-    <string name="qs_dnd_prompt_auto_rule" translatable="false">Priority mode was turned on by an automatic rule (<xliff:g name="rule">%s</xliff:g>).</string>
+    <!-- Prompt for when Do not disturb is on from automatic rule in QS [CHAR LIMIT=NONE] -->
+    <string name="qs_dnd_prompt_auto_rule">Do Not Disturb was turned on by an automatic rule (<xliff:g name="rule">%s</xliff:g>).</string>
 
-    <!-- Prompt for when Priority mode is on from app in QS [CHAR LIMIT=NONE] -->
-    <string name="qs_dnd_prompt_app" translatable="false">Priority mode was turned on by an app (<xliff:g name="app">%s</xliff:g>).</string>
+    <!-- Prompt for when Do not disturb is on from app in QS [CHAR LIMIT=NONE] -->
+    <string name="qs_dnd_prompt_app">Do Not Disturb was turned on by an app (<xliff:g name="app">%s</xliff:g>).</string>
 
-    <!-- Prompt for when Priority mode is on from automatic rule or app in QS [CHAR LIMIT=NONE] -->
-    <string name="qs_dnd_prompt_auto_rule_app" translatable="false">Priority mode was turned on by an automatic rule or app.</string>
+    <!-- Prompt for when Do not disturb is on from automatic rule or app in QS [CHAR LIMIT=NONE] -->
+    <string name="qs_dnd_prompt_auto_rule_app">Do Not Disturb was turned on by an automatic rule or app.</string>
 
     <!-- Title of the "running foreground services" dialog. [CHAR LIMIT=NONE] -->
     <string name="running_foreground_services_title">Apps running in background</string>
@@ -2215,6 +2226,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]-->
@@ -2284,8 +2297,8 @@
     <string name="people_tile_description">See recent messages, missed calls, and status updates</string>
     <!-- Title text displayed for the Conversation widget [CHAR LIMIT=50] -->
     <string name="people_tile_title">Conversation</string>
-    <!-- Text when the Conversation widget when Priority mode is suppressing the notification. [CHAR LIMIT=50] -->
-    <string name="paused_by_dnd" translatable="false">Paused by Priority mode</string>
+    <!-- Text when the Conversation widget when Do Not Disturb is suppressing the notification. [CHAR LIMIT=50] -->
+    <string name="paused_by_dnd">Paused by Do Not Disturb</string>
     <!-- Content description text on the Conversation widget when a person has sent a new text message [CHAR LIMIT=150] -->
     <string name="new_notification_text_content_description"><xliff:g id="name" example="Anna">%1$s</xliff:g> sent a message: <xliff:g id="notification" example="Hey! How is your day going">%2$s</xliff:g></string>
     <!-- Content description text on the Conversation widget when a person has sent a new image message [CHAR LIMIT=150] -->
@@ -2417,10 +2430,11 @@
     <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 camera and mic off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
-    <string name="dream_overlay_status_bar_notification_indicator">There are notifications</string>
+    <!-- Content description for the notifications indicator icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
+    <string name="dream_overlay_status_bar_notification_indicator">{count, plural,
+    =1 {# notification}
+    other {# notifications}
+    }</string>
 </resources>
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/flags/Flag.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
index b611c96..6ad9161 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
@@ -35,6 +35,11 @@
     val resourceId: Int
 }
 
+interface SysPropFlag<T> : Flag<T> {
+    val name: String
+    val default: T
+}
+
 // Consider using the "parcelize" kotlin library.
 
 data class BooleanFlag @JvmOverloads constructor(
@@ -66,6 +71,12 @@
     @BoolRes override val resourceId: Int
 ) : ResourceFlag<Boolean>
 
+data class SysPropBooleanFlag constructor(
+    override val id: Int,
+    override val name: String,
+    override val default: Boolean = false
+) : SysPropFlag<Boolean>
+
 data class StringFlag @JvmOverloads constructor(
     override val id: Int,
     override val default: String = ""
diff --git a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt
index ec619dd..149f6e8 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt
@@ -54,7 +54,7 @@
      * An action called on restart which takes as an argument whether the listeners requested
      * that the restart be suppressed
      */
-    var restartAction: Consumer<Boolean>? = null
+    var onSettingsChangedAction: Consumer<Boolean>? = null
     var clearCacheAction: Consumer<Int>? = null
     private val listeners: MutableSet<PerFlagListener> = mutableSetOf()
     private val settingsObserver: ContentObserver = SettingsObserver()
@@ -154,11 +154,11 @@
             val idStr = parts[parts.size - 1]
             val id = try { idStr.toInt() } catch (e: NumberFormatException) { return }
             clearCacheAction?.accept(id)
-            dispatchListenersAndMaybeRestart(id)
+            dispatchListenersAndMaybeRestart(id, onSettingsChangedAction)
         }
     }
 
-    fun dispatchListenersAndMaybeRestart(id: Int) {
+    fun dispatchListenersAndMaybeRestart(id: Int, restartAction: Consumer<Boolean>?) {
         val filteredListeners: List<FlagListenable.Listener> = synchronized(listeners) {
             listeners.mapNotNull { if (it.id == id) it.listener else null }
         }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index b3983d2..e743c4e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -43,6 +43,7 @@
 
     /**
      * Get the secondary split screen app's rectangle when not minimized.
+     * @deprecated
      */
     Rect getNonMinimizedSplitScreenSecondaryBounds() = 7;
 
@@ -104,6 +105,7 @@
 
     /**
      * Sets the split-screen divider minimized state
+     * @deprecated
      */
     void setSplitScreenMinimized(boolean minimized) = 22;
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AppTrace.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AppTrace.java
deleted file mode 100644
index 0241c59..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AppTrace.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.shared.recents.utilities;
-
-import static android.os.Trace.TRACE_TAG_APP;
-
-/**
- * Helper class for internal trace functions.
- */
-public class AppTrace {
-
-    /**
-     * Begins a new async trace section with the given {@param key} and {@param cookie}.
-     */
-    public static void start(String key, int cookie) {
-        android.os.Trace.asyncTraceBegin(TRACE_TAG_APP, key, cookie);
-    }
-
-    /**
-     * Begins a new async trace section with the given {@param key}.
-     */
-    public static void start(String key) {
-        android.os.Trace.asyncTraceBegin(TRACE_TAG_APP, key, 0);
-    }
-
-    /**
-     * Ends an existing async trace section with the given {@param key}.
-     */
-    public static void end(String key) {
-        android.os.Trace.asyncTraceEnd(TRACE_TAG_APP, key, 0);
-    }
-
-    /**
-     * Ends an existing async trace section with the given {@param key} and {@param cookie}.
-     */
-    public static void end(String key, int cookie) {
-        android.os.Trace.asyncTraceEnd(TRACE_TAG_APP, key, cookie);
-    }
-
-    /**
-     * Begins a new trace section with the given {@param key}. Can be nested.
-     */
-    public static void beginSection(String key) {
-        android.os.Trace.beginSection(key);
-    }
-
-    /**
-     * Ends an existing trace section started in the last {@link #beginSection(String)}.
-     */
-    public static void endSection() {
-        android.os.Trace.endSection();
-    }
-
-    /**
-     * Traces a counter value.
-     */
-    public static void count(String name, int count) {
-        android.os.Trace.traceCounter(TRACE_TAG_APP, name, count);
-    }
-}
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/recents/utilities/RectFEvaluator.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/RectFEvaluator.java
deleted file mode 100644
index 51c1b5a..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/RectFEvaluator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.shared.recents.utilities;
-
-import android.animation.TypeEvaluator;
-import android.graphics.RectF;
-
-/**
- * This evaluator can be used to perform type interpolation between <code>RectF</code> values.
- */
-public class RectFEvaluator implements TypeEvaluator<RectF> {
-
-    private final RectF mRect = new RectF();
-
-    /**
-     * This function returns the result of linearly interpolating the start and
-     * end Rect values, with <code>fraction</code> representing the proportion
-     * between the start and end values. The calculation is a simple parametric
-     * calculation on each of the separate components in the Rect objects
-     * (left, top, right, and bottom).
-     *
-     * <p>The object returned will be the <code>reuseRect</code> passed into the constructor.</p>
-     *
-     * @param fraction   The fraction from the starting to the ending values
-     * @param startValue The start Rect
-     * @param endValue   The end Rect
-     * @return A linear interpolation between the start and end values, given the
-     *         <code>fraction</code> parameter.
-     */
-    @Override
-    public RectF evaluate(float fraction, RectF startValue, RectF endValue) {
-        float left = startValue.left + ((endValue.left - startValue.left) * fraction);
-        float top = startValue.top + ((endValue.top - startValue.top) * fraction);
-        float right = startValue.right + ((endValue.right - startValue.right) * fraction);
-        float bottom = startValue.bottom + ((endValue.bottom - startValue.bottom) * fraction);
-        mRect.set(left, top, right, bottom);
-        return mRect;
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
index 0c7e56e..0f937bd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
@@ -42,31 +42,4 @@
     public void unregisterRemoteAnimations() {
         mWrapped.unregisterRemoteAnimations();
     }
-
-    /**
-     * @see android.view.ViewDebug#dumpv2(View, ByteArrayOutputStream)
-     */
-    public boolean encodeViewHierarchy(ByteArrayOutputStream out) {
-        View view = null;
-        if (mWrapped.getWindow() != null &&
-                mWrapped.getWindow().peekDecorView() != null &&
-                mWrapped.getWindow().peekDecorView().getViewRootImpl() != null) {
-            view = mWrapped.getWindow().peekDecorView().getViewRootImpl().getView();
-        }
-        if (view == null) {
-            return false;
-        }
-
-        final ViewHierarchyEncoder encoder = new ViewHierarchyEncoder(out);
-        int[] location = view.getLocationOnScreen();
-        encoder.addProperty("window:left", location[0]);
-        encoder.addProperty("window:top", location[1]);
-        view.encode(encoder);
-        encoder.endStream();
-        return true;
-    }
-
-    public int getDisplayId() {
-        return mWrapped.getDisplayId();
-    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 48fcbbd..461c2dc 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -262,7 +262,6 @@
      * Starts a task from Recents synchronously.
      */
     public boolean startActivityFromRecents(Task.TaskKey taskKey, ActivityOptions options) {
-        ActivityOptionsCompat.addTaskInfo(options, taskKey);
         return startActivityFromRecents(taskKey.id, options);
     }
 
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 e2ca349..db62f88 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
@@ -104,15 +104,4 @@
         opts.setSourceInfo(ActivityOptions.SourceInfo.TYPE_LAUNCHER, uptimeMillis);
         return opts;
     }
-
-    /**
-     * Sets Task specific information to the activity options
-     */
-    public static void addTaskInfo(ActivityOptions opts, Task.TaskKey taskKey) {
-        if (taskKey.windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
-            // We show non-visible docked tasks in Recents, but we always want to launch
-            // them in the fullscreen stack.
-            opts.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
-        }
-    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ClipDescriptionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ClipDescriptionCompat.java
deleted file mode 100644
index 0b1141e..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ClipDescriptionCompat.java
+++ /dev/null
@@ -1,39 +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.system;
-
-import android.content.ClipDescription;
-import android.content.Intent;
-
-/**
- * Wrapper around ClipDescription.
- */
-public abstract class ClipDescriptionCompat {
-
-    public static String MIMETYPE_APPLICATION_ACTIVITY =
-            ClipDescription.MIMETYPE_APPLICATION_ACTIVITY;
-
-    public static String MIMETYPE_APPLICATION_SHORTCUT =
-            ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
-
-    public static String MIMETYPE_APPLICATION_TASK =
-            ClipDescription.MIMETYPE_APPLICATION_TASK;
-
-    public static String EXTRA_PENDING_INTENT = ClipDescription.EXTRA_PENDING_INTENT;
-
-    public static String EXTRA_TASK_ID = Intent.EXTRA_TASK_ID;
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ConfigurationCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ConfigurationCompat.java
deleted file mode 100644
index d1c77a6..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ConfigurationCompat.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.shared.system;
-
-import android.content.res.Configuration;
-
-/**
- * Wraps the Configuration to access the window configuration.
- */
-public class ConfigurationCompat {
-
-    public static int getWindowConfigurationRotation(Configuration c) {
-        return c.windowConfiguration.getRotation();
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/DockedStackListenerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/DockedStackListenerCompat.java
deleted file mode 100644
index bb319e6..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/DockedStackListenerCompat.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.system;
-
-import android.view.IDockedStackListener;
-
-/**
- * An interface to track docked stack changes.
- */
-public class DockedStackListenerCompat {
-
-    IDockedStackListener.Stub mListener = new IDockedStackListener.Stub() {
-        @Override
-        public void onDividerVisibilityChanged(boolean visible) {}
-
-        @Override
-        public void onDockedStackExistsChanged(boolean exists) {
-            DockedStackListenerCompat.this.onDockedStackExistsChanged(exists);
-        }
-
-        @Override
-        public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
-                boolean isHomeStackResizable) {
-            DockedStackListenerCompat.this.onDockedStackMinimizedChanged(minimized, animDuration,
-                    isHomeStackResizable);
-        }
-
-        @Override
-        public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration) {}
-
-        @Override
-        public void onDockSideChanged(final int newDockSide) {
-            DockedStackListenerCompat.this.onDockSideChanged(newDockSide);
-        }
-    };
-
-    public void onDockedStackExistsChanged(boolean exists) {
-        // To be overridden
-    }
-
-    public void onDockedStackMinimizedChanged(boolean minimized, long animDuration,
-            boolean isHomeStackResizable) {
-        // To be overridden
-    }
-
-    public void onDockSideChanged(final int newDockSide) {
-        // To be overridden
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java
index bf23a49..ba0a6d1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java
@@ -17,7 +17,6 @@
 package com.android.systemui.shared.system;
 
 import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.INPUT_CONSUMER_PIP;
 import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
 
 import android.os.Binder;
@@ -137,14 +136,6 @@
      * Registers the input consumer.
      */
     public void registerInputConsumer() {
-        registerInputConsumer(false);
-    }
-
-    /**
-     * Registers the input consumer.
-     * @param withSfVsync the flag set using sf vsync signal or no
-     */
-    public void registerInputConsumer(boolean withSfVsync) {
         if (mInputEventReceiver == null) {
             final InputChannel inputChannel = new InputChannel();
             try {
@@ -154,7 +145,7 @@
                 Log.e(TAG, "Failed to create input consumer", e);
             }
             mInputEventReceiver = new InputEventReceiver(inputChannel, Looper.myLooper(),
-                    withSfVsync ? Choreographer.getSfInstance() : Choreographer.getInstance());
+                    Choreographer.getInstance());
             if (mRegistrationListener != null) {
                 mRegistrationListener.onRegistrationChanged(true /* isRegistered */);
             }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/LatencyTrackerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LatencyTrackerCompat.java
index a8c19ec..e6ae19e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/LatencyTrackerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LatencyTrackerCompat.java
@@ -24,14 +24,6 @@
  * @see LatencyTracker
  */
 public class LatencyTrackerCompat {
-    /**
-     * @see LatencyTracker
-     * @deprecated Please use {@link LatencyTrackerCompat#logToggleRecents(Context, int)} instead.
-     */
-    @Deprecated
-    public static void logToggleRecents(int duration) {
-        LatencyTracker.logActionDeprecated(LatencyTracker.ACTION_TOGGLE_RECENTS, duration, false);
-    }
 
     /** @see LatencyTracker */
     public static void logToggleRecents(Context context, int duration) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherAppsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherAppsCompat.java
deleted file mode 100644
index d24c779..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherAppsCompat.java
+++ /dev/null
@@ -1,34 +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.system;
-
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.pm.LauncherApps;
-import android.os.Bundle;
-import android.os.UserHandle;
-
-/**
- * Wrapper around LauncherApps.
- */
-public abstract class LauncherAppsCompat {
-
-    public static PendingIntent getMainActivityLaunchIntent(LauncherApps launcherApps,
-            ComponentName component, Bundle startActivityOptions, UserHandle user) {
-        return launcherApps.getMainActivityLaunchIntent(component, startActivityOptions, user);
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherEventUtil.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherEventUtil.java
deleted file mode 100644
index a51d668..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/LauncherEventUtil.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.system;
-
-public class LauncherEventUtil {
-
-    // Constants for the Action
-    public static final int VISIBLE = 0;
-    public static final int DISMISS = 1;
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
deleted file mode 100644
index 952c8ae..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.system;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class MetricsLoggerCompat {
-
-    private final MetricsLogger mMetricsLogger;
-    public static final int OVERVIEW_ACTIVITY = MetricsEvent.OVERVIEW_ACTIVITY;
-
-    public MetricsLoggerCompat() {
-        mMetricsLogger = new MetricsLogger();
-    }
-
-    public void action(int category) {
-        mMetricsLogger.action(category);
-    }
-
-    public void action(int category, int value) {
-        mMetricsLogger.action(category, value);
-    }
-
-    public void visible(int category) {
-        mMetricsLogger.visible(category);
-    }
-
-    public void hidden(int category) {
-        mMetricsLogger.hidden(category);
-    }
-
-    public void visibility(int category, boolean visible) {
-        mMetricsLogger.visibility(category, visible);
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
index ace7938..b61827a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteTransitionCompat.java
@@ -132,12 +132,13 @@
                 // the current going-away task on top of recents, though, so move it to front
                 final ArrayList<WindowContainerToken> pausingTasks = new ArrayList<>();
                 WindowContainerToken pipTask = null;
+                WindowContainerToken recentsTask = null;
                 for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                     final TransitionInfo.Change change = info.getChanges().get(i);
+                    final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                     if (change.getMode() == TRANSIT_CLOSE || change.getMode() == TRANSIT_TO_BACK) {
                         t.setLayer(leashMap.get(change.getLeash()),
                                 info.getChanges().size() * 3 - i);
-                        final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
                         if (taskInfo == null) {
                             continue;
                         }
@@ -147,11 +148,14 @@
                                 && taskInfo.pictureInPictureParams.isAutoEnterEnabled()) {
                             pipTask = taskInfo.token;
                         }
-                    } else if (change.getTaskInfo() != null
-                            && change.getTaskInfo().topActivityType == ACTIVITY_TYPE_RECENTS) {
+                    } else if (taskInfo != null
+                            && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
                         // This task is for recents, keep it on top.
                         t.setLayer(leashMap.get(change.getLeash()),
                                 info.getChanges().size() * 3 - i);
+                        recentsTask = taskInfo.token;
+                    } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+                        recentsTask = taskInfo.token;
                     }
                 }
                 // Also make all the wallpapers opaque since we want the visible from the start
@@ -160,7 +164,7 @@
                 }
                 t.apply();
                 mRecentsSession.setup(controller, info, finishedCallback, pausingTasks, pipTask,
-                        leashMap, mToken);
+                        recentsTask, leashMap, mToken);
                 recents.onAnimationStart(mRecentsSession, apps, wallpapers, new Rect(0, 0, 0, 0),
                         new Rect());
             }
@@ -209,6 +213,7 @@
         private IRemoteTransitionFinishedCallback mFinishCB = null;
         private ArrayList<WindowContainerToken> mPausingTasks = null;
         private WindowContainerToken mPipTask = null;
+        private WindowContainerToken mRecentsTask = null;
         private TransitionInfo mInfo = null;
         private ArrayList<SurfaceControl> mOpeningLeashes = null;
         private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
@@ -218,7 +223,8 @@
         void setup(RecentsAnimationControllerCompat wrapped, TransitionInfo info,
                 IRemoteTransitionFinishedCallback finishCB,
                 ArrayList<WindowContainerToken> pausingTasks, WindowContainerToken pipTask,
-                ArrayMap<SurfaceControl, SurfaceControl> leashMap, IBinder transition) {
+                WindowContainerToken recentsTask, ArrayMap<SurfaceControl, SurfaceControl> leashMap,
+                IBinder transition) {
             if (mInfo != null) {
                 throw new IllegalStateException("Trying to run a new recents animation while"
                         + " recents is already active.");
@@ -228,6 +234,7 @@
             mFinishCB = finishCB;
             mPausingTasks = pausingTasks;
             mPipTask = pipTask;
+            mRecentsTask = recentsTask;
             mLeashMap = leashMap;
             mTransition = transition;
         }
@@ -236,10 +243,15 @@
         boolean merge(TransitionInfo info, SurfaceControl.Transaction t,
                 RecentsAnimationListener recents) {
             ArrayList<TransitionInfo.Change> openingTasks = null;
+            boolean cancelRecents = false;
             for (int i = info.getChanges().size() - 1; i >= 0; --i) {
                 final TransitionInfo.Change change = info.getChanges().get(i);
                 if (change.getMode() == TRANSIT_OPEN || change.getMode() == TRANSIT_TO_FRONT) {
                     if (change.getTaskInfo() != null) {
+                        if (change.getTaskInfo().topActivityType == ACTIVITY_TYPE_HOME) {
+                            // canceling recents animation
+                            cancelRecents = true;
+                        }
                         if (openingTasks == null) {
                             openingTasks = new ArrayList<>();
                         }
@@ -249,9 +261,11 @@
             }
             if (openingTasks == null) return false;
             int pauseMatches = 0;
-            for (int i = 0; i < openingTasks.size(); ++i) {
-                if (mPausingTasks.contains(openingTasks.get(i).getContainer())) {
-                    ++pauseMatches;
+            if (!cancelRecents) {
+                for (int i = 0; i < openingTasks.size(); ++i) {
+                    if (mPausingTasks.contains(openingTasks.get(i).getContainer())) {
+                        ++pauseMatches;
+                    }
                 }
             }
             if (pauseMatches > 0) {
@@ -329,6 +343,9 @@
                     wct.reorder(mPausingTasks.get(i), true /* onTop */);
                     t.show(mInfo.getChange(mPausingTasks.get(i)).getLeash());
                 }
+                if (mRecentsTask != null) {
+                    wct.restoreTransientOrder(mRecentsTask);
+                }
             } else {
                 wct = null;
                 if (mPipTask != null && mPipTransaction != null) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RotationWatcher.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RotationWatcher.java
deleted file mode 100644
index 7c8c23e..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RotationWatcher.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.system;
-
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-import android.view.IRotationWatcher;
-import android.view.WindowManagerGlobal;
-
-public abstract class RotationWatcher {
-
-    private static final String TAG = "RotationWatcher";
-
-    private final Context mContext;
-
-    private final IRotationWatcher mWatcher = new IRotationWatcher.Stub() {
-
-        @Override
-        public void onRotationChanged(int rotation) {
-            RotationWatcher.this.onRotationChanged(rotation);
-
-        }
-    };
-
-    private boolean mIsWatching = false;
-
-    public RotationWatcher(Context context) {
-        mContext = context;
-    }
-
-    protected abstract void onRotationChanged(int rotation);
-
-    public void enable() {
-        if (!mIsWatching) {
-            try {
-                WindowManagerGlobal.getWindowManagerService().watchRotation(mWatcher,
-                        mContext.getDisplayId());
-                mIsWatching = true;
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to set rotation watcher", e);
-            }
-        }
-    }
-
-    public void disable() {
-        if (mIsWatching) {
-            try {
-                WindowManagerGlobal.getWindowManagerService().removeRotationWatcher(mWatcher);
-                mIsWatching = false;
-            }  catch (RemoteException e) {
-                Log.w(TAG, "Failed to remove rotation watcher", e);
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java
deleted file mode 100644
index 35952f5..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.system;
-
-import android.app.ActivityManager;
-import android.graphics.Bitmap;
-
-public class TaskDescriptionCompat {
-
-    private ActivityManager.TaskDescription mTaskDescription;
-
-    public TaskDescriptionCompat(ActivityManager.TaskDescription td) {
-        mTaskDescription = td;
-    }
-
-    public int getPrimaryColor() {
-        return mTaskDescription != null
-                ? mTaskDescription.getPrimaryColor()
-                : 0;
-    }
-
-    public int getBackgroundColor() {
-        return mTaskDescription != null
-                ? mTaskDescription.getBackgroundColor()
-                : 0;
-    }
-
-    public static Bitmap getIcon(ActivityManager.TaskDescription desc, int userId) {
-        if (desc.getInMemoryIcon() != null) {
-            return desc.getInMemoryIcon();
-        }
-        return ActivityManager.TaskDescription.loadTaskDescriptionIcon(
-                desc.getIconFilename(), userId);
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ThreadedRendererCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ThreadedRendererCompat.java
deleted file mode 100644
index ffd8a08..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ThreadedRendererCompat.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.system;
-
-import android.view.ThreadedRenderer;
-
-/**
- * @see ThreadedRenderer
- */
-public class ThreadedRendererCompat {
-
-    public static int EGL_CONTEXT_PRIORITY_REALTIME_NV = 0x3357;
-    public static int EGL_CONTEXT_PRIORITY_HIGH_IMG = 0x3101;
-    public static int EGL_CONTEXT_PRIORITY_MEDIUM_IMG = 0x3102;
-    public static int EGL_CONTEXT_PRIORITY_LOW_IMG = 0x3103;
-
-    public static void setContextPriority(int priority) {
-        ThreadedRenderer.setContextPriority(priority);
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TonalCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TonalCompat.java
deleted file mode 100644
index 4a0f89b..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TonalCompat.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS 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.system;
-
-import android.app.WallpaperColors;
-import android.content.Context;
-
-import com.android.internal.colorextraction.ColorExtractor.GradientColors;
-import com.android.internal.colorextraction.types.Tonal;
-
-public class TonalCompat {
-
-    private final Tonal mTonal;
-
-    public TonalCompat(Context context) {
-        mTonal = new Tonal(context);
-    }
-
-    public ExtractionInfo extractDarkColors(WallpaperColors colors) {
-        GradientColors darkColors = new GradientColors();
-        mTonal.extractInto(colors, new GradientColors(), darkColors, new GradientColors());
-
-        ExtractionInfo result = new ExtractionInfo();
-        result.mainColor = darkColors.getMainColor();
-        result.secondaryColor = darkColors.getSecondaryColor();
-        result.supportsDarkText = darkColors.supportsDarkText();
-        if (colors != null) {
-            result.supportsDarkTheme =
-                    (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
-        }
-        return result;
-    }
-
-    public static class ExtractionInfo {
-        public int mainColor;
-        public int secondaryColor;
-        public boolean supportsDarkText;
-        public boolean supportsDarkTheme;
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ViewRootImplCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ViewRootImplCompat.java
deleted file mode 100644
index 89c60f1..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ViewRootImplCompat.java
+++ /dev/null
@@ -1,67 +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.system;
-
-import android.graphics.HardwareRenderer;
-import android.view.SurfaceControl;
-import android.view.View;
-import android.view.ViewRootImpl;
-
-import java.util.function.LongConsumer;
-
-/**
- * Helper class to expose some ViewRoomImpl methods
- */
-public class ViewRootImplCompat {
-
-    private final ViewRootImpl mViewRoot;
-
-    public ViewRootImplCompat(View view) {
-        mViewRoot = view == null ? null : view.getViewRootImpl();
-    }
-
-    public SurfaceControl getRenderSurfaceControl() {
-        return mViewRoot == null ? null : mViewRoot.getSurfaceControl();
-    }
-
-    public boolean isValid() {
-        return mViewRoot != null;
-    }
-
-    public View getView() {
-        return mViewRoot == null ? null : mViewRoot.getView();
-    }
-
-    public void registerRtFrameCallback(LongConsumer callback) {
-        if (mViewRoot != null) {
-            mViewRoot.registerRtFrameCallback(
-                    new HardwareRenderer.FrameDrawingCallback() {
-                        @Override
-                        public void onFrameDraw(long l) {
-                            callback.accept(l);
-                        }
-                    });
-        }
-    }
-
-    public void mergeWithNextTransaction(SurfaceControl.Transaction t, long frame) {
-        if (mViewRoot != null) {
-            mViewRoot.mergeWithNextTransaction(t, frame);
-        } else {
-            t.apply();
-        }
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java
deleted file mode 100644
index 73dc60d..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperEngineCompat.java
+++ /dev/null
@@ -1,56 +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.system;
-
-import android.graphics.Rect;
-import android.service.wallpaper.IWallpaperEngine;
-import android.util.Log;
-
-/**
- * @see IWallpaperEngine
- */
-public class WallpaperEngineCompat {
-
-    private static final String TAG = "WallpaperEngineCompat";
-
-    /**
-     * Returns true if {@link IWallpaperEngine#scalePreview(Rect)} is available.
-     */
-    public static boolean supportsScalePreview() {
-        try {
-            return IWallpaperEngine.class.getMethod("scalePreview", Rect.class) != null;
-        } catch (NoSuchMethodException | SecurityException e) {
-            return false;
-        }
-    }
-
-    private final IWallpaperEngine mWrappedEngine;
-
-    public WallpaperEngineCompat(IWallpaperEngine wrappedEngine) {
-        mWrappedEngine = wrappedEngine;
-    }
-
-    /**
-     * @see IWallpaperEngine#scalePreview(Rect)
-     */
-    public void scalePreview(Rect scaleToRect) {
-        try {
-            mWrappedEngine.scalePreview(scaleToRect);
-        } catch (Exception e) {
-            Log.i(TAG, "Couldn't call scalePreview method on WallpaperEngine", e);
-        }
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
deleted file mode 100644
index 1f194eca..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WallpaperManagerCompat.java
+++ /dev/null
@@ -1,51 +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.system;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.IBinder;
-
-/**
- * @see WallpaperManager
- */
-public class WallpaperManagerCompat {
-    private final WallpaperManager mWallpaperManager;
-
-    public WallpaperManagerCompat(Context context) {
-        mWallpaperManager = context.getSystemService(WallpaperManager.class);
-    }
-
-    /**
-     * @see WallpaperManager#setWallpaperZoomOut(IBinder, float)
-     */
-    public void setWallpaperZoomOut(IBinder windowToken, float zoom) {
-        mWallpaperManager.setWallpaperZoomOut(windowToken, zoom);
-    }
-
-    /**
-     * @return the max scale for the wallpaper when it's fully zoomed out
-     */
-    public static float getWallpaperZoomOutMaxScale(Context context) {
-        return context.getResources()
-                .getFloat(Resources.getSystem().getIdentifier(
-                        /* name= */ "config_wallpaperMaxScale",
-                        /* defType= */ "dimen",
-                        /* defPackage= */ "android"));
-    }
-}
\ No newline at end of file
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 f6fe1ed..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
@@ -4,20 +4,31 @@
 import android.hardware.SensorEvent
 import android.hardware.SensorEventListener
 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/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
index c4b02f6..ffd1546 100644
--- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java
@@ -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/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 848b8ab..1ede76f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -26,6 +26,7 @@
 import android.media.MediaRouter;
 import android.media.MediaRouter.RouteInfo;
 import android.os.Bundle;
+import android.os.Trace;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Display;
@@ -67,11 +68,14 @@
 
         @Override
         public void onDisplayAdded(int displayId) {
+            Trace.beginSection(
+                    "KeyguardDisplayManager#onDisplayAdded(displayId=" + displayId + ")");
             final Display display = mDisplayService.getDisplay(displayId);
             if (mShowing) {
                 updateNavigationBarVisibility(displayId, false /* navBarVisible */);
                 showPresentation(display);
             }
+            Trace.endSection();
         }
 
         @Override
@@ -81,7 +85,10 @@
 
         @Override
         public void onDisplayRemoved(int displayId) {
+            Trace.beginSection(
+                    "KeyguardDisplayManager#onDisplayRemoved(displayId=" + displayId + ")");
             hidePresentation(displayId);
+            Trace.endSection();
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
index 0529cdbc..28f21af 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java
@@ -183,7 +183,7 @@
     @Override
     void resetState() {
         mPasswordEntry.setTextOperationUser(UserHandle.of(KeyguardUpdateMonitor.getCurrentUser()));
-        mMessageAreaController.setMessage("");
+        mMessageAreaController.setMessage(R.string.keyguard_enter_your_password);
         final boolean wasDisabled = mPasswordEntry.isEnabled();
         mView.setPasswordEntryEnabled(true);
         mView.setPasswordEntryInputEnabled(true);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
index 41f9240..7635f919 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java
@@ -358,7 +358,7 @@
     }
 
     private void displayDefaultSecurityMessage() {
-        mMessageAreaController.setMessage("");
+        mMessageAreaController.setMessage(R.string.keyguard_enter_your_pattern);
     }
 
     private void handleAttemptLockout(long elapsedRealtimeDeadline) {
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..cc7e4f7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java
@@ -132,5 +132,12 @@
     @Override
     void resetState() {
         mView.setPasswordEntryEnabled(true);
+        mMessageAreaController.setMessage(R.string.keyguard_enter_your_pin);
+    }
+
+    @Override
+    protected void startErrorAnimation() {
+        super.startErrorAnimation();
+        mView.startErrorAnimation();
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
index 9f4585f..160d82a 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java
@@ -76,12 +76,6 @@
     }
 
     @Override
-    void resetState() {
-        super.resetState();
-        mMessageAreaController.setMessage("");
-    }
-
-    @Override
     public boolean startDisappearAnimation(Runnable finishRunnable) {
         return mView.startDisappearAnimation(
                 mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 7bc343e..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));
@@ -973,18 +973,22 @@
 
         @Override
         public void updateSecurityViewLocation() {
+            int yTrans = mResources.getDimensionPixelSize(R.dimen.bouncer_user_switcher_y_trans);
+
             if (mResources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                 updateViewGravity(mViewFlipper, Gravity.CENTER_HORIZONTAL);
                 updateViewGravity(mUserSwitcherViewGroup, Gravity.CENTER_HORIZONTAL);
-                mUserSwitcherViewGroup.setTranslationY(0);
+
+                mUserSwitcherViewGroup.setTranslationY(yTrans);
+                mViewFlipper.setTranslationY(-yTrans);
             } else {
                 updateViewGravity(mViewFlipper, Gravity.RIGHT | Gravity.BOTTOM);
                 updateViewGravity(mUserSwitcherViewGroup, Gravity.LEFT | Gravity.CENTER_VERTICAL);
 
                 // Attempt to reposition a bit higher to make up for this frame being a bit lower
                 // on the device
-                int yTrans = mResources.getDimensionPixelSize(R.dimen.status_bar_height);
                 mUserSwitcherViewGroup.setTranslationY(-yTrans);
+                mViewFlipper.setTranslationY(0);
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index a72a050e..31f466f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -16,8 +16,6 @@
 
 package com.android.keyguard;
 
-import android.app.ActivityManager;
-import android.app.IActivityManager;
 import android.content.Context;
 import android.graphics.Color;
 import android.util.AttributeSet;
@@ -27,7 +25,6 @@
 
 import androidx.core.graphics.ColorUtils;
 
-import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 
@@ -44,9 +41,6 @@
     private static final boolean DEBUG = KeyguardConstants.DEBUG;
     private static final String TAG = "KeyguardStatusView";
 
-    private final LockPatternUtils mLockPatternUtils;
-    private final IActivityManager mIActivityManager;
-
     private ViewGroup mStatusViewContainer;
     private KeyguardClockSwitch mClockView;
     private KeyguardSliceView mKeyguardSlice;
@@ -56,14 +50,6 @@
     private int mTextColor;
     private float mChildrenAlphaExcludingSmartSpace = 1f;
 
-    /**
-     * Bottom margin that defines the margin between bottom of smart space and top of notification
-     * icons on AOD.
-     */
-    private int mIconTopMargin;
-    private int mIconTopMarginWithHeader;
-    private boolean mShowingHeader;
-
     public KeyguardStatusView(Context context) {
         this(context, null, 0);
     }
@@ -74,8 +60,6 @@
 
     public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mIActivityManager = ActivityManager.getService();
-        mLockPatternUtils = new LockPatternUtils(getContext());
     }
 
     @Override
@@ -91,25 +75,11 @@
         mKeyguardSlice = findViewById(R.id.keyguard_slice_view);
         mTextColor = mClockView.getCurrentTextColor();
 
-        mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
-        onSliceContentChanged();
-
         mMediaHostContainer = findViewById(R.id.status_view_media_container);
 
         updateDark();
     }
 
-    /**
-     * Moves clock, adjusting margins when slice content changes.
-     */
-    private void onSliceContentChanged() {
-        final boolean hasHeader = mKeyguardSlice.hasHeader();
-        if (mShowingHeader == hasHeader) {
-            return;
-        }
-        mShowingHeader = hasHeader;
-    }
-
     void setDarkAmount(float darkAmount) {
         if (mDarkAmount == darkAmount) {
             return;
@@ -158,10 +128,4 @@
             mKeyguardSlice.dump(fd, pw, args);
         }
     }
-
-    private void loadBottomMargin() {
-        mIconTopMargin = getResources().getDimensionPixelSize(R.dimen.widget_vertical_padding);
-        mIconTopMarginWithHeader = getResources().getDimensionPixelSize(
-                R.dimen.widget_vertical_padding_with_header);
-    }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java
index a5fe0ef..af3da9f 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;
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 37f4564..1ef6dea 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;
@@ -752,15 +753,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 +959,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);
             }
         }
     }
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/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
index 122f3d7..295d77d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
@@ -24,9 +24,9 @@
 
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 
 /**
@@ -176,9 +176,9 @@
     //  achieving complete abstraction away from where the Keyguard View is mounted.
 
     /**
-     * Registers the StatusBar to which this Keyguard View is mounted.
+     * Registers the CentralSurfaces to which this Keyguard View is mounted.
      */
-    void registerStatusBar(StatusBar statusBar,
+    void registerCentralSurfaces(CentralSurfaces centralSurfaces,
             NotificationPanelViewController notificationPanelViewController,
             @Nullable PanelExpansionStateManager panelExpansionStateManager,
             BiometricUnlockController biometricUnlockController,
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 4ad5183..370686a 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -60,7 +60,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.ViewController;
@@ -78,7 +78,7 @@
  * For devices with UDFPS, the lock icon will show at the sensor location. Else, the lock
  * icon will show a set distance from the bottom of the device.
  */
-@StatusBarComponent.StatusBarScope
+@CentralSurfacesComponent.CentralSurfacesScope
 public class LockIconViewController extends ViewController<LockIconView> implements Dumpable {
     private static final String TAG = "LockIconViewController";
     private static final float sDefaultDensity =
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
index e6298a4..f925eaa 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java
@@ -16,17 +16,18 @@
 package com.android.keyguard;
 
 import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
+import android.annotation.Nullable;
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.RippleDrawable;
 import android.view.ContextThemeWrapper;
+import android.widget.TextView;
 
 import androidx.annotation.StyleRes;
 
-import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.util.Utils;
 
@@ -34,45 +35,104 @@
  * Provides background color and radius animations for key pad buttons.
  */
 class NumPadAnimator {
-    private AnimatorSet mAnimator;
     private ValueAnimator mExpandAnimator;
+    private AnimatorSet mExpandAnimatorSet;
     private ValueAnimator mContractAnimator;
+    private AnimatorSet mContractAnimatorSet;
     private GradientDrawable mBackground;
-    private RippleDrawable mRipple;
     private int mNormalColor;
     private int mHighlightColor;
     private int mStyle;
+    private static final int EXPAND_ANIMATION_MS = 100;
+    private static final int EXPAND_COLOR_ANIMATION_MS = 50;
+    private static final int CONTRACT_ANIMATION_DELAY_MS = 33;
+    private static final int CONTRACT_ANIMATION_MS = 417;
 
-    NumPadAnimator(Context context, final RippleDrawable drawable, @StyleRes int style) {
+    NumPadAnimator(Context context, final Drawable drawable, @StyleRes int style) {
+        this(context, drawable, style, null);
+    }
+
+    NumPadAnimator(Context context, final Drawable drawable, @StyleRes int style,
+            @Nullable TextView digitTextView) {
         mStyle = style;
-        mRipple = (RippleDrawable) drawable.mutate();
-        mBackground = (GradientDrawable) mRipple.findDrawableByLayerId(R.id.background);
+        mBackground = (GradientDrawable) drawable;
 
         reloadColors(context);
+        int textColorPrimary = com.android.settingslib.Utils
+                .getColorAttrDefaultColor(context, android.R.attr.textColorPrimary);
+        int textColorPrimaryInverse = com.android.settingslib.Utils
+                .getColorAttrDefaultColor(context, android.R.attr.textColorPrimaryInverse);
 
         // Actual values will be updated later, usually during an onLayout() call
-        mAnimator = new AnimatorSet();
         mExpandAnimator = ValueAnimator.ofFloat(0f, 1f);
-        mExpandAnimator.setDuration(50);
+        mExpandAnimator.setDuration(EXPAND_ANIMATION_MS);
         mExpandAnimator.setInterpolator(Interpolators.LINEAR);
-        mExpandAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                public void onAnimationUpdate(ValueAnimator anim) {
-                    mBackground.setCornerRadius((float) anim.getAnimatedValue());
-                    mRipple.invalidateSelf();
-                }
+        mExpandAnimator.addUpdateListener(
+                anim -> mBackground.setCornerRadius((float) anim.getAnimatedValue()));
+
+        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) {
+                digitTextView.setTextColor((int) valueAnimator.getAnimatedValue());
+            }
         });
 
+        mExpandAnimatorSet = new AnimatorSet();
+        mExpandAnimatorSet.playTogether(mExpandAnimator,
+                expandBackgroundColorAnimator, expandTextColorAnimator);
+
         mContractAnimator = ValueAnimator.ofFloat(1f, 0f);
-        mContractAnimator.setStartDelay(33);
-        mContractAnimator.setDuration(417);
+        mContractAnimator.setStartDelay(CONTRACT_ANIMATION_DELAY_MS);
+        mContractAnimator.setDuration(CONTRACT_ANIMATION_MS);
         mContractAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-        mContractAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                public void onAnimationUpdate(ValueAnimator anim) {
-                    mBackground.setCornerRadius((float) anim.getAnimatedValue());
-                    mRipple.invalidateSelf();
-                }
+        mContractAnimator.addUpdateListener(
+                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(
+                animator -> mBackground.setColor((int) animator.getAnimatedValue()));
+
+        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 -> {
+            if (digitTextView != null) {
+                digitTextView.setTextColor((int) valueAnimator.getAnimatedValue());
+            }
         });
-        mAnimator.playSequentially(mExpandAnimator, mContractAnimator);
+
+        mContractAnimatorSet = new AnimatorSet();
+        mContractAnimatorSet.playTogether(mContractAnimator,
+                contractBackgroundColorAnimator, contractTextColorAnimator);
+    }
+
+    public void expand() {
+        mExpandAnimatorSet.cancel();
+        mContractAnimatorSet.cancel();
+        mExpandAnimatorSet.start();
+    }
+
+    public void contract() {
+        mExpandAnimatorSet.cancel();
+        mContractAnimatorSet.cancel();
+        mContractAnimatorSet.start();
     }
 
     void onLayout(int height) {
@@ -83,11 +143,6 @@
         mContractAnimator.setFloatValues(endRadius, startRadius);
     }
 
-    void start() {
-        mAnimator.cancel();
-        mAnimator.start();
-    }
-
     /**
      * Reload colors from resources.
      **/
@@ -103,7 +158,6 @@
         a.recycle();
 
         mBackground.setColor(mNormalColor);
-        mRipple.setColor(ColorStateList.valueOf(mHighlightColor));
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
index f4ce643..e0d0fc2 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadButton.java
@@ -19,8 +19,6 @@
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.RippleDrawable;
 import android.graphics.drawable.VectorDrawable;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
@@ -39,13 +37,8 @@
     public NumPadButton(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        Drawable background = getBackground();
-        if (background instanceof RippleDrawable) {
-            mAnimator = new NumPadAnimator(context, (RippleDrawable) getBackground(),
-                    attrs.getStyleAttribute());
-        } else {
-            mAnimator = null;
-        }
+        mAnimator = new NumPadAnimator(context, getBackground().mutate(),
+                attrs.getStyleAttribute());
     }
 
     @Override
@@ -79,8 +72,14 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        if (event.getActionMasked() == MotionEvent.ACTION_DOWN && mAnimator != null) {
-            mAnimator.start();
+        switch(event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                if (mAnimator != null) mAnimator.expand();
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                if (mAnimator != null) mAnimator.contract();
+                break;
         }
         return super.onTouchEvent(event);
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index a5a3f80..88a0bce 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -18,8 +18,6 @@
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.RippleDrawable;
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -131,13 +129,8 @@
 
         setContentDescription(mDigitText.getText().toString());
 
-        Drawable background = getBackground();
-        if (background instanceof RippleDrawable) {
-            mAnimator = new NumPadAnimator(context, (RippleDrawable) background,
-                    R.style.NumPadKey);
-        } else {
-            mAnimator = null;
-        }
+        mAnimator = new NumPadAnimator(context, getBackground().mutate(),
+                R.style.NumPadKey, mDigitText);
     }
 
     @Override
@@ -161,11 +154,16 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            doHapticKeyClick();
-            if (mAnimator != null) mAnimator.start();
+        switch(event.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                doHapticKeyClick();
+                if (mAnimator != null) mAnimator.expand();
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                if (mAnimator != null) mAnimator.contract();
+                break;
         }
-
         return super.onTouchEvent(event);
     }
 
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java
index 207ac28..8dbe5e0 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardBouncerScope.java
@@ -24,7 +24,7 @@
 import javax.inject.Scope;
 
 /**
- * Scope annotation for singleton items within the StatusBarComponent.
+ * Scope annotation for singleton items within the CentralSurfacesComponent.
  */
 @Documented
 @Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java
index ba0642f..f498ef3 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java
@@ -24,7 +24,7 @@
 import javax.inject.Scope;
 
 /**
- * Scope annotation for singleton items within the StatusBarComponent.
+ * Scope annotation for singleton items within the CentralSurfacesComponent.
  */
 @Documented
 @Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java
index 880822a..aeae8e3 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewScope.java
@@ -24,7 +24,7 @@
 import javax.inject.Scope;
 
 /**
- * Scope annotation for singleton items within the StatusBarComponent.
+ * Scope annotation for singleton items within the CentralSurfacesComponent.
  */
 @Documented
 @Retention(RUNTIME)
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index cc166c2..5bd620e 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -23,7 +23,7 @@
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.util.Optional;
 
@@ -33,17 +33,17 @@
 
 /**
  * Single common instance of ActivityStarter that can be gotten and referenced from anywhere, but
- * delegates to an actual implementation (StatusBar).
+ * delegates to an actual implementation (CentralSurfaces).
  */
 @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
 @SysUISingleton
 public class ActivityStarterDelegate implements ActivityStarter {
 
-    private Lazy<Optional<StatusBar>> mActualStarterOptionalLazy;
+    private Lazy<Optional<CentralSurfaces>> mActualStarterOptionalLazy;
 
     @Inject
-    public ActivityStarterDelegate(Lazy<Optional<StatusBar>> statusBarOptionalLazy) {
-        mActualStarterOptionalLazy = statusBarOptionalLazy;
+    public ActivityStarterDelegate(Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy) {
+        mActualStarterOptionalLazy = centralSurfacesOptionalLazy;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
index 6bec8aa..56046d9 100644
--- a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+++ b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
@@ -49,7 +49,7 @@
     private val shouldDrawCutout: Boolean = DisplayCutout.getFillBuiltInDisplayCutout(
             context.resources, context.display?.uniqueId)
     private var displayMode: Display.Mode? = null
-    private val location = IntArray(2)
+    protected val location = IntArray(2)
     protected var displayRotation = 0
 
     @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
@@ -65,7 +65,8 @@
     @JvmField val protectionPath: Path = Path()
     private val protectionRectOrig: RectF = RectF()
     private val protectionPathOrig: Path = Path()
-    private var cameraProtectionProgress: Float = HIDDEN_CAMERA_PROTECTION_SCALE
+    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+    var cameraProtectionProgress: Float = HIDDEN_CAMERA_PROTECTION_SCALE
     private var cameraProtectionAnimator: ValueAnimator? = null
 
     constructor(context: Context) : super(context)
@@ -273,4 +274,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
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 ee1d9a3..4b86862 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
@@ -26,11 +26,22 @@
 import android.graphics.PorterDuff
 import android.graphics.PorterDuffColorFilter
 import android.graphics.PorterDuffXfermode
+import android.graphics.Rect
+import android.graphics.Region
 import android.graphics.drawable.Drawable
 import android.hardware.graphics.common.AlphaInterpretation
 import android.hardware.graphics.common.DisplayDecorationSupport
+import android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM
+import android.view.DisplayCutout.BOUNDS_POSITION_LEFT
+import android.view.DisplayCutout.BOUNDS_POSITION_LENGTH
+import android.view.DisplayCutout.BOUNDS_POSITION_TOP
+import android.view.DisplayCutout.BOUNDS_POSITION_RIGHT
 import android.view.RoundedCorner
 import android.view.RoundedCorners
+import android.view.Surface
+import androidx.annotation.VisibleForTesting
+import kotlin.math.ceil
+import kotlin.math.floor
 
 /**
  * When the HWC of the device supports Composition.DISPLAY_DECORATON, we use this layer to draw
@@ -38,13 +49,16 @@
  */
 class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDecorationSupport)
     : DisplayCutoutBaseView(context) {
-    public val colorMode: Int
+    val colorMode: Int
     private val useInvertedAlphaColor: Boolean
     private val color: Int
     private val bgColor: Int
     private val cornerFilter: ColorFilter
     private val cornerBgFilter: ColorFilter
     private val clearPaint: Paint
+    @JvmField val transparentRect: Rect = Rect()
+    private val debugTransparentRegionPaint: Paint?
+    private val tempRect: Rect = Rect()
 
     private var roundedCornerTopSize = 0
     private var roundedCornerBottomSize = 0
@@ -61,6 +75,10 @@
             bgColor = Color.TRANSPARENT
             colorMode = ActivityInfo.COLOR_MODE_DEFAULT
             useInvertedAlphaColor = false
+            debugTransparentRegionPaint = Paint().apply {
+                color = 0x2f00ff00 // semi-transparent green
+                style = Paint.Style.FILL
+            }
         } else {
             colorMode = ActivityInfo.COLOR_MODE_A8
             useInvertedAlphaColor = displayDecorationSupport.alphaInterpretation ==
@@ -72,6 +90,7 @@
                 color = Color.BLACK
                 bgColor = Color.TRANSPARENT
             }
+            debugTransparentRegionPaint = null
         }
         cornerFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)
         cornerBgFilter = PorterDuffColorFilter(bgColor, PorterDuff.Mode.SRC_OUT)
@@ -82,6 +101,9 @@
 
     override fun onAttachedToWindow() {
         super.onAttachedToWindow()
+        if (!DEBUG_COLOR) {
+            parent.requestTransparentRegion(this)
+        }
         viewRootImpl.setDisplayDecoration(true)
 
         if (useInvertedAlphaColor) {
@@ -93,12 +115,172 @@
     }
 
     override fun onDraw(canvas: Canvas) {
+        // If updating onDraw, also update gatherTransparentRegion
         if (useInvertedAlphaColor) {
             canvas.drawColor(bgColor)
         }
         // Cutouts are drawn in DisplayCutoutBaseView.onDraw()
         super.onDraw(canvas)
         drawRoundedCorners(canvas)
+
+        debugTransparentRegionPaint?.let {
+            calculateTransparentRect()
+            canvas.drawRect(transparentRect, it)
+        }
+    }
+
+    override fun gatherTransparentRegion(region: Region?): Boolean {
+        region?.let {
+            calculateTransparentRect()
+            region.op(transparentRect, Region.Op.INTERSECT)
+        }
+        // Always return false - views underneath this should always be visible.
+        return false
+    }
+
+    /**
+     * The transparent rect is calculated by subtracting the regions of cutouts, cutout protect and
+     * rounded corners from the region with fullscreen display size.
+     */
+    @VisibleForTesting
+    fun calculateTransparentRect() {
+        transparentRect.set(0, 0, width, height)
+
+        // Remove cutout region.
+        removeCutoutFromTransparentRegion()
+
+        // Remove cutout protection region.
+        removeCutoutProtectionFromTransparentRegion()
+
+        // Remove rounded corner region.
+        removeRoundedCornersFromTransparentRegion()
+    }
+
+    private fun removeCutoutFromTransparentRegion() {
+        displayInfo.displayCutout?.let {
+                cutout ->
+            if (!cutout.boundingRectLeft.isEmpty) {
+                transparentRect.left =
+                    cutout.boundingRectLeft.right.coerceAtLeast(transparentRect.left)
+            }
+            if (!cutout.boundingRectTop.isEmpty) {
+                transparentRect.top =
+                    cutout.boundingRectTop.bottom.coerceAtLeast(transparentRect.top)
+            }
+            if (!cutout.boundingRectRight.isEmpty) {
+                transparentRect.right =
+                    cutout.boundingRectRight.left.coerceAtMost(transparentRect.right)
+            }
+            if (!cutout.boundingRectBottom.isEmpty) {
+                transparentRect.bottom =
+                    cutout.boundingRectBottom.top.coerceAtMost(transparentRect.bottom)
+            }
+        }
+    }
+
+    private fun removeCutoutProtectionFromTransparentRegion() {
+        if (protectionRect.isEmpty) {
+            return
+        }
+
+        val centerX = protectionRect.centerX()
+        val centerY = protectionRect.centerY()
+        val scaledDistanceX = (centerX - protectionRect.left) * cameraProtectionProgress
+        val scaledDistanceY = (centerY - protectionRect.top) * cameraProtectionProgress
+        tempRect.set(
+            floor(centerX - scaledDistanceX).toInt(),
+            floor(centerY - scaledDistanceY).toInt(),
+            ceil(centerX + scaledDistanceX).toInt(),
+            ceil(centerY + scaledDistanceY).toInt()
+        )
+
+        // Find out which edge the protectionRect belongs and remove that edge from the transparent
+        // region.
+        val leftDistance = tempRect.left
+        val topDistance = tempRect.top
+        val rightDistance = width - tempRect.right
+        val bottomDistance = height - tempRect.bottom
+        val minDistance = minOf(leftDistance, topDistance, rightDistance, bottomDistance)
+        when (minDistance) {
+            leftDistance -> {
+                transparentRect.left = tempRect.right.coerceAtLeast(transparentRect.left)
+            }
+            topDistance -> {
+                transparentRect.top = tempRect.bottom.coerceAtLeast(transparentRect.top)
+            }
+            rightDistance -> {
+                transparentRect.right = tempRect.left.coerceAtMost(transparentRect.right)
+            }
+            bottomDistance -> {
+                transparentRect.bottom = tempRect.top.coerceAtMost(transparentRect.bottom)
+            }
+        }
+    }
+
+    private fun removeRoundedCornersFromTransparentRegion() {
+        var hasTopOrBottomCutouts = false
+        var hasLeftOrRightCutouts = false
+        displayInfo.displayCutout?.let {
+                cutout ->
+            hasTopOrBottomCutouts = !cutout.boundingRectTop.isEmpty ||
+                    !cutout.boundingRectBottom.isEmpty
+            hasLeftOrRightCutouts = !cutout.boundingRectLeft.isEmpty ||
+                    !cutout.boundingRectRight.isEmpty
+        }
+        // The goal is to remove the rounded corner areas as small as possible so that we can have a
+        // larger transparent region. Therefore, we should always remove from the short edge sides
+        // if possible.
+        val isShortEdgeTopBottom = width < height
+        if (isShortEdgeTopBottom) {
+            // Short edges on top & bottom.
+            if (!hasTopOrBottomCutouts && hasLeftOrRightCutouts) {
+                // If there are cutouts only on left or right edges, remove left and right sides
+                // for rounded corners.
+                transparentRect.left = getRoundedCornerSizeByPosition(BOUNDS_POSITION_LEFT)
+                    .coerceAtLeast(transparentRect.left)
+                transparentRect.right =
+                    (width - getRoundedCornerSizeByPosition(BOUNDS_POSITION_RIGHT))
+                        .coerceAtMost(transparentRect.right)
+            } else {
+                // If there are cutouts on top or bottom edges or no cutout at all, remove top
+                // and bottom sides for rounded corners.
+                transparentRect.top = getRoundedCornerSizeByPosition(BOUNDS_POSITION_TOP)
+                    .coerceAtLeast(transparentRect.top)
+                transparentRect.bottom =
+                    (height - getRoundedCornerSizeByPosition(BOUNDS_POSITION_BOTTOM))
+                        .coerceAtMost(transparentRect.bottom)
+            }
+        } else {
+            // Short edges on left & right.
+            if (hasTopOrBottomCutouts && !hasLeftOrRightCutouts) {
+                // If there are cutouts only on top or bottom edges, remove top and bottom sides
+                // for rounded corners.
+                transparentRect.top = getRoundedCornerSizeByPosition(BOUNDS_POSITION_TOP)
+                    .coerceAtLeast(transparentRect.top)
+                transparentRect.bottom =
+                    (height - getRoundedCornerSizeByPosition(BOUNDS_POSITION_BOTTOM))
+                        .coerceAtMost(transparentRect.bottom)
+            } else {
+                // If there are cutouts on left or right edges or no cutout at all, remove left
+                // and right sides for rounded corners.
+                transparentRect.left = getRoundedCornerSizeByPosition(BOUNDS_POSITION_LEFT)
+                    .coerceAtLeast(transparentRect.left)
+                transparentRect.right =
+                    (width - getRoundedCornerSizeByPosition(BOUNDS_POSITION_RIGHT))
+                        .coerceAtMost(transparentRect.right)
+            }
+        }
+    }
+
+    private fun getRoundedCornerSizeByPosition(position: Int): Int {
+        val delta = displayRotation - Surface.ROTATION_0
+        return when ((position + delta) % BOUNDS_POSITION_LENGTH) {
+            BOUNDS_POSITION_LEFT -> roundedCornerTopSize.coerceAtLeast(roundedCornerBottomSize)
+            BOUNDS_POSITION_TOP -> roundedCornerTopSize
+            BOUNDS_POSITION_RIGHT -> roundedCornerTopSize.coerceAtLeast(roundedCornerBottomSize)
+            BOUNDS_POSITION_BOTTOM -> roundedCornerBottomSize
+            else -> throw IllegalArgumentException("Incorrect position: $position")
+        }
     }
 
     private fun drawRoundedCorners(canvas: Canvas) {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 2ec5f4f..ae41cae 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -847,14 +847,20 @@
         pw.println("  mIsRoundedCornerMultipleRadius:" + mIsRoundedCornerMultipleRadius);
         pw.println("  mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
         pw.println("  mPendingRotationChange:" + mPendingRotationChange);
-        pw.println("  mHwcScreenDecorationSupport:");
-        if (mHwcScreenDecorationSupport == null) {
-            pw.println("    null");
-        } else {
-            pw.println("    format: "
+        if (mHwcScreenDecorationSupport != null) {
+            pw.println("  mHwcScreenDecorationSupport:");
+            pw.println("    format="
                     + PixelFormat.formatToString(mHwcScreenDecorationSupport.format));
-            pw.println("    alphaInterpretation: "
+            pw.println("    alphaInterpretation="
                     + alphaInterpretationToString(mHwcScreenDecorationSupport.alphaInterpretation));
+        } else {
+            pw.println("  mHwcScreenDecorationSupport: null");
+        }
+        if (mScreenDecorHwcLayer != null) {
+            pw.println("  mScreenDecorHwcLayer:");
+            pw.println("    transparentRegion=" + mScreenDecorHwcLayer.transparentRect);
+        } else {
+            pw.println("  mScreenDecorHwcLayer: null");
         }
         pw.println("  mRoundedDefault(x,y)=(" + mRoundedDefault.x + "," + mRoundedDefault.y + ")");
         pw.println("  mRoundedDefaultTop(x,y)=(" + mRoundedDefaultTop.x + "," + mRoundedDefaultTop.y
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index ec11065..3a6165c 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -38,13 +38,13 @@
 import android.util.Log;
 import android.util.TimingsTraceLog;
 import android.view.SurfaceControl;
+import android.view.ThreadedRenderer;
 
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.systemui.dagger.ContextComponentHelper;
 import com.android.systemui.dagger.GlobalRootComponent;
 import com.android.systemui.dagger.SysUIComponent;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.shared.system.ThreadedRendererCompat;
 import com.android.systemui.util.NotificationChannels;
 
 import java.lang.reflect.Constructor;
@@ -118,11 +118,11 @@
             // The priority is defaulted at medium.
             int sfPriority = SurfaceControl.getGPUContextPriority();
             Log.i(TAG, "Found SurfaceFlinger's GPU Priority: " + sfPriority);
-            if (sfPriority == ThreadedRendererCompat.EGL_CONTEXT_PRIORITY_REALTIME_NV) {
+            if (sfPriority == ThreadedRenderer.EGL_CONTEXT_PRIORITY_REALTIME_NV) {
                 Log.i(TAG, "Setting SysUI's GPU Context priority to: "
-                        + ThreadedRendererCompat.EGL_CONTEXT_PRIORITY_HIGH_IMG);
-                ThreadedRendererCompat.setContextPriority(
-                        ThreadedRendererCompat.EGL_CONTEXT_PRIORITY_HIGH_IMG);
+                        + ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
+                ThreadedRenderer.setContextPriority(
+                        ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
             }
 
             // Enable binder tracing on system server for calls originating from SysUI
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index 881e6a9..bd8e44c 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -54,7 +54,7 @@
 import com.android.systemui.recents.Recents;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
 import com.android.systemui.util.Assert;
 
@@ -180,7 +180,7 @@
     private final Optional<Recents> mRecentsOptional;
     private Locale mLocale;
     private final AccessibilityManager mA11yManager;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final NotificationShadeWindowController mNotificationShadeController;
     private final StatusBarWindowCallback mNotificationShadeCallback;
     private boolean mDismissNotificationShadeActionRegistered;
@@ -188,7 +188,7 @@
     @Inject
     public SystemActions(Context context,
             NotificationShadeWindowController notificationShadeController,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             Optional<Recents> recentsOptional) {
         super(context);
         mRecentsOptional = recentsOptional;
@@ -201,7 +201,7 @@
         // NotificationShadeWindowController.registerCallback() only keeps weak references.
         mNotificationShadeCallback = (keyguardShowing, keyguardOccluded, bouncerShowing, mDozing) ->
                 registerOrUnregisterDismissNotificationShadeAction();
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
     }
 
     @Override
@@ -311,9 +311,10 @@
 
         // Saving state in instance variable since this callback is called quite often to avoid
         // binder calls
-        final Optional<StatusBar> statusBarOptional = mStatusBarOptionalLazy.get();
-        if (statusBarOptional.map(StatusBar::isPanelExpanded).orElse(false)
-                && !statusBarOptional.get().isKeyguardShowing()) {
+        final Optional<CentralSurfaces> centralSurfacesOptional =
+                mCentralSurfacesOptionalLazy.get();
+        if (centralSurfacesOptional.map(CentralSurfaces::isPanelExpanded).orElse(false)
+                && !centralSurfacesOptional.get().isKeyguardShowing()) {
             if (!mDismissNotificationShadeActionRegistered) {
                 mA11yManager.registerSystemAction(
                         createRemoteAction(
@@ -466,12 +467,12 @@
     }
 
     private void handleNotifications() {
-        mStatusBarOptionalLazy.get().ifPresent(StatusBar::animateExpandNotificationsPanel);
+        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::animateExpandNotificationsPanel);
     }
 
     private void handleQuickSettings() {
-        mStatusBarOptionalLazy.get().ifPresent(
-                statusBar -> statusBar.animateExpandSettingsPanel(null));
+        mCentralSurfacesOptionalLazy.get().ifPresent(
+                centralSurfaces -> centralSurfaces.animateExpandSettingsPanel(null));
     }
 
     private void handlePowerDialog() {
@@ -524,8 +525,8 @@
     }
 
     private void handleAccessibilityDismissNotificationShade() {
-        mStatusBarOptionalLazy.get().ifPresent(
-                statusBar -> statusBar.animateCollapsePanels(
+        mCentralSurfacesOptionalLazy.get().ifPresent(
+                centralSurfaces -> centralSurfaces.animateCollapsePanels(
                         CommandQueue.FLAG_EXCLUDE_NONE, false /* force */));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 885a177..aafbf7e 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -172,6 +172,17 @@
     }
 
     @MainThread
+    void moveWindowMagnifierToPositionInternal(int displayId, float positionX, float positionY,
+            IRemoteMagnificationAnimationCallback callback) {
+        final WindowMagnificationController windowMagnificationController =
+                mMagnificationControllerSupplier.get(displayId);
+        if (windowMagnificationController != null) {
+            windowMagnificationController.moveWindowMagnifierToPosition(positionX, positionY,
+                    callback);
+        }
+    }
+
+    @MainThread
     void disableWindowMagnification(int displayId,
             @Nullable IRemoteMagnificationAnimationCallback callback) {
         final WindowMagnificationController windowMagnificationController =
@@ -210,9 +221,9 @@
     }
 
     @Override
-    public void onDrag(int displayId) {
+    public void onMove(int displayId) {
         if (mWindowMagnificationConnectionImpl != null) {
-            mWindowMagnificationConnectionImpl.onDrag(displayId);
+            mWindowMagnificationConnectionImpl.onMove(displayId);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
index dc1e005..3b4114b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
@@ -156,6 +156,7 @@
         }
         mAnimationCallback = animationCallback;
         setupEnableAnimationSpecs(scale, centerX, centerY);
+
         if (mEndSpec.equals(mStartSpec)) {
             if (mState == STATE_DISABLED) {
                 mController.enableWindowMagnificationInternal(scale, centerX, centerY,
@@ -178,6 +179,24 @@
         }
     }
 
+    void moveWindowMagnifierToPosition(float centerX, float centerY,
+            IRemoteMagnificationAnimationCallback callback) {
+        if (mState == STATE_ENABLED) {
+            // We set the animation duration to shortAnimTime which would be reset at the end.
+            mValueAnimator.setDuration(mContext.getResources()
+                    .getInteger(com.android.internal.R.integer.config_shortAnimTime));
+            enableWindowMagnification(Float.NaN, centerX, centerY,
+                    /* magnificationFrameOffsetRatioX */ Float.NaN,
+                    /* magnificationFrameOffsetRatioY */ Float.NaN, callback);
+        } else if (mState == STATE_ENABLING) {
+            sendAnimationCallback(false);
+            mAnimationCallback = callback;
+            mValueAnimator.setDuration(mContext.getResources()
+                    .getInteger(com.android.internal.R.integer.config_shortAnimTime));
+            setupEnableAnimationSpecs(Float.NaN, centerX, centerY);
+        }
+    }
+
     private void setupEnableAnimationSpecs(float scale, float centerX, float centerY) {
         if (mController == null) {
             return;
@@ -193,9 +212,16 @@
                     R.integer.magnification_default_scale) : scale, centerX, centerY);
         } else {
             mStartSpec.set(currentScale, currentCenterX, currentCenterY);
-            mEndSpec.set(Float.isNaN(scale) ? currentScale : scale,
-                    Float.isNaN(centerX) ? currentCenterX : centerX,
-                    Float.isNaN(centerY) ? currentCenterY : centerY);
+
+            final float endScale = (mState == STATE_ENABLING ? mEndSpec.mScale : currentScale);
+            final float endCenterX =
+                    (mState == STATE_ENABLING ? mEndSpec.mCenterX : currentCenterX);
+            final float endCenterY =
+                    (mState == STATE_ENABLING ? mEndSpec.mCenterY : currentCenterY);
+
+            mEndSpec.set(Float.isNaN(scale) ? endScale : scale,
+                    Float.isNaN(centerX) ? endCenterX : centerX,
+                    Float.isNaN(centerY) ? endCenterY : centerY);
         }
         if (DEBUG) {
             Log.d(TAG, "SetupEnableAnimationSpecs : mStartSpec = " + mStartSpec + ", endSpec = "
@@ -269,6 +295,9 @@
             setState(STATE_ENABLED);
         }
         sendAnimationCallback(true);
+        // We reset the duration to config_longAnimTime
+        mValueAnimator.setDuration(mContext.getResources()
+                .getInteger(com.android.internal.R.integer.config_longAnimTime));
     }
 
     @Override
@@ -313,10 +342,10 @@
                 mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
     }
 
-    private static ValueAnimator newValueAnimator(Resources resources) {
+    private static ValueAnimator newValueAnimator(Resources resource) {
         final ValueAnimator valueAnimator = new ValueAnimator();
         valueAnimator.setDuration(
-                resources.getInteger(com.android.internal.R.integer.config_longAnimTime));
+                resource.getInteger(com.android.internal.R.integer.config_longAnimTime));
         valueAnimator.setInterpolator(new AccelerateInterpolator(2.5f));
         valueAnimator.setFloatValues(0.0f, 1.0f);
         return valueAnimator;
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
index 1d22633..aa684fa 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationConnectionImpl.java
@@ -77,6 +77,13 @@
     }
 
     @Override
+    public void moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
+            IRemoteMagnificationAnimationCallback callback) {
+        mHandler.post(() -> mWindowMagnification.moveWindowMagnifierToPositionInternal(
+                displayId, positionX, positionY, callback));
+    }
+
+    @Override
     public void showMagnificationButton(int displayId, int magnificationMode) {
         mHandler.post(
                 () -> mModeSwitchesController.showButton(displayId, magnificationMode));
@@ -143,10 +150,10 @@
         }
     }
 
-    void onDrag(int displayId) {
+    void onMove(int displayId) {
         if (mConnectionCallback != null) {
             try {
-                mConnectionCallback.onDrag(displayId);
+                mConnectionCallback.onMove(displayId);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to inform taking control by a user", e);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index de03993..7e1a026 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -852,6 +852,7 @@
     @Override
     public void move(int xOffset, int yOffset) {
         moveWindowMagnifier(xOffset, yOffset);
+        mWindowMagnifierCallback.onMove(mDisplayId);
     }
 
     /**
@@ -985,6 +986,14 @@
         }
     }
 
+    void moveWindowMagnifierToPosition(float positionX, float positionY,
+            IRemoteMagnificationAnimationCallback callback) {
+        if (mMirrorSurfaceView == null) {
+            return;
+        }
+        mAnimationController.moveWindowMagnifierToPosition(positionX, positionY, callback);
+    }
+
     /**
      * Gets the scale.
      *
@@ -1037,8 +1046,7 @@
 
     @Override
     public boolean onDrag(float offsetX, float offsetY) {
-        moveWindowMagnifier(offsetX, offsetY);
-        mWindowMagnifierCallback.onDrag(mDisplayId);
+        move((int) offsetX, (int) offsetY);
         return true;
     }
 
@@ -1064,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/accessibility/WindowMagnifierCallback.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
index bdded10..c334ca6 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnifierCallback.java
@@ -17,7 +17,6 @@
 package com.android.systemui.accessibility;
 
 import android.graphics.Rect;
-import android.view.ViewConfiguration;
 
 /**
  * A callback to inform {@link com.android.server.accessibility.AccessibilityManagerService} about
@@ -56,11 +55,9 @@
     void onAccessibilityActionPerformed(int displayId);
 
     /**
-     * Called when the user is performing dragging gesture. It is started after the offset
-     * between the down location and the move event location exceed
-     * {@link ViewConfiguration#getScaledTouchSlop()}.
+     * Called when the user is performing a move action.
      *
      * @param displayId The logical display id.
      */
-    void onDrag(int displayId);
+    void onMove(int displayId);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
index aedaf96..dfff00b 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
@@ -36,7 +36,7 @@
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -69,7 +69,7 @@
     };
 
     private final Context mContext;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final StatusBarStateController mStatusBarStateController;
 
     private boolean mLauncherShowing;
@@ -77,10 +77,11 @@
 
     @Inject
     PhoneStateMonitor(Context context, BroadcastDispatcher broadcastDispatcher,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy, BootCompleteCache bootCompleteCache,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
+            BootCompleteCache bootCompleteCache,
             StatusBarStateController statusBarStateController) {
         mContext = context;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mStatusBarStateController = statusBarStateController;
 
         mDefaultHome = getCurrentDefaultHome();
@@ -180,7 +181,8 @@
     }
 
     private boolean isBouncerShowing() {
-        return mStatusBarOptionalLazy.get().map(StatusBar::isBouncerShowing).orElse(false);
+        return mCentralSurfacesOptionalLazy.get()
+                .map(CentralSurfaces::isBouncerShowing).orElse(false);
     }
 
     private boolean isKeyguardLocked() {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
new file mode 100644
index 0000000..55611f7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
@@ -0,0 +1,123 @@
+/*
+ * 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.biometrics
+
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.util.Log
+import android.widget.ImageView
+import com.android.systemui.R
+import com.android.systemui.biometrics.AuthBiometricView.BiometricState
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATED
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATING
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATING_ANIMATING_IN
+import com.android.systemui.biometrics.AuthBiometricView.STATE_ERROR
+import com.android.systemui.biometrics.AuthBiometricView.STATE_HELP
+import com.android.systemui.biometrics.AuthBiometricView.STATE_IDLE
+import com.android.systemui.biometrics.AuthBiometricView.STATE_PENDING_CONFIRMATION
+
+private const val TAG = "AuthBiometricFaceIconController"
+
+/** Face only icon animator for BiometricPrompt. */
+class AuthBiometricFaceIconController(
+    context: Context,
+    iconView: ImageView
+) : AuthIconController(context, iconView) {
+
+    // false = dark to light, true = light to dark
+    private var lastPulseLightToDark = false
+
+    @BiometricState
+    private var state = 0
+
+    init {
+        val size = context.resources.getDimensionPixelSize(R.dimen.biometric_dialog_face_icon_size)
+        iconView.layoutParams.width = size
+        iconView.layoutParams.height = size
+        showStaticDrawable(R.drawable.face_dialog_pulse_dark_to_light)
+    }
+
+    private fun startPulsing() {
+        lastPulseLightToDark = false
+        animateIcon(R.drawable.face_dialog_pulse_dark_to_light, true)
+    }
+
+    private fun pulseInNextDirection() {
+        val iconRes = if (lastPulseLightToDark) {
+            R.drawable.face_dialog_pulse_dark_to_light
+        } else {
+            R.drawable.face_dialog_pulse_light_to_dark
+        }
+        animateIcon(iconRes, true /* repeat */)
+        lastPulseLightToDark = !lastPulseLightToDark
+    }
+
+    override fun handleAnimationEnd(drawable: Drawable) {
+        if (state == STATE_AUTHENTICATING || state == STATE_HELP) {
+            pulseInNextDirection()
+        }
+    }
+
+    override fun updateIcon(@BiometricState oldState: Int, @BiometricState newState: Int) {
+        val lastStateIsErrorIcon = (oldState == STATE_ERROR || oldState == STATE_HELP)
+        if (newState == STATE_AUTHENTICATING_ANIMATING_IN) {
+            showStaticDrawable(R.drawable.face_dialog_pulse_dark_to_light)
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_authenticating
+            )
+        } else if (newState == STATE_AUTHENTICATING) {
+            startPulsing()
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_authenticating
+            )
+        } else if (oldState == STATE_PENDING_CONFIRMATION && newState == STATE_AUTHENTICATED) {
+            animateIconOnce(R.drawable.face_dialog_dark_to_checkmark)
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_confirmed
+            )
+        } else if (lastStateIsErrorIcon && newState == STATE_IDLE) {
+            animateIconOnce(R.drawable.face_dialog_error_to_idle)
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_idle
+            )
+        } else if (lastStateIsErrorIcon && newState == STATE_AUTHENTICATED) {
+            animateIconOnce(R.drawable.face_dialog_dark_to_checkmark)
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_authenticated
+            )
+        } else if (newState == STATE_ERROR && oldState != STATE_ERROR) {
+            animateIconOnce(R.drawable.face_dialog_dark_to_error)
+        } else if (oldState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
+            animateIconOnce(R.drawable.face_dialog_dark_to_checkmark)
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_authenticated
+            )
+        } else if (newState == STATE_PENDING_CONFIRMATION) {
+            animateIconOnce(R.drawable.face_dialog_wink_from_dark)
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_authenticated
+            )
+        } else if (newState == STATE_IDLE) {
+            showStaticDrawable(R.drawable.face_dialog_idle_static)
+            iconView.contentDescription = context.getString(
+                R.string.biometric_dialog_face_icon_description_idle
+            )
+        } else {
+            Log.w(TAG, "Unhandled state: $newState")
+        }
+        state = newState
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java
deleted file mode 100644
index ae3e94b..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintView.java
+++ /dev/null
@@ -1,245 +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.biometrics;
-
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-
-import android.content.Context;
-import android.hardware.biometrics.BiometricAuthenticator.Modality;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-
-/**
- * Manages the layout of an auth dialog for devices with both a face sensor and a fingerprint
- * sensor. Face authentication is attempted first, followed by fingerprint if the initial attempt is
- * unsuccessful.
- */
-public class AuthBiometricFaceToFingerprintView extends AuthBiometricFaceView {
-    private static final String TAG = "BiometricPrompt/AuthBiometricFaceToFingerprintView";
-
-    protected static class UdfpsIconController extends IconController {
-        @BiometricState private int mIconState = STATE_IDLE;
-
-        protected UdfpsIconController(
-                @NonNull Context context, @NonNull ImageView iconView, @NonNull TextView textView) {
-            super(context, iconView, textView);
-        }
-
-        void updateState(@BiometricState int newState) {
-            updateState(mIconState, newState);
-        }
-
-        @Override
-        protected void updateState(int lastState, int newState) {
-            final boolean lastStateIsErrorIcon =
-                    lastState == STATE_ERROR || lastState == STATE_HELP;
-
-            switch (newState) {
-                case STATE_IDLE:
-                case STATE_AUTHENTICATING_ANIMATING_IN:
-                case STATE_AUTHENTICATING:
-                case STATE_PENDING_CONFIRMATION:
-                case STATE_AUTHENTICATED:
-                    if (lastStateIsErrorIcon) {
-                        animateOnce(R.drawable.fingerprint_dialog_error_to_fp);
-                    } else {
-                        showStaticDrawable(R.drawable.fingerprint_dialog_fp_to_error);
-                    }
-                    mIconView.setContentDescription(mContext.getString(
-                            R.string.accessibility_fingerprint_dialog_fingerprint_icon));
-                    break;
-
-                case STATE_ERROR:
-                case STATE_HELP:
-                    if (!lastStateIsErrorIcon) {
-                        animateOnce(R.drawable.fingerprint_dialog_fp_to_error);
-                    } else {
-                        showStaticDrawable(R.drawable.fingerprint_dialog_error_to_fp);
-                    }
-                    mIconView.setContentDescription(mContext.getString(
-                            R.string.biometric_dialog_try_again));
-                    break;
-
-                default:
-                    Log.e(TAG, "Unknown biometric dialog state: " + newState);
-                    break;
-            }
-
-            mState = newState;
-            mIconState = newState;
-        }
-    }
-
-    @Modality private int mActiveSensorType = TYPE_FACE;
-    @Nullable private ModalityListener mModalityListener;
-    @Nullable private FingerprintSensorPropertiesInternal mFingerprintSensorProps;
-    @Nullable private UdfpsDialogMeasureAdapter mUdfpsMeasureAdapter;
-    @Nullable @VisibleForTesting UdfpsIconController mUdfpsIconController;
-
-
-    public AuthBiometricFaceToFingerprintView(Context context) {
-        super(context);
-    }
-
-    public AuthBiometricFaceToFingerprintView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @VisibleForTesting
-    AuthBiometricFaceToFingerprintView(Context context, AttributeSet attrs, Injector injector) {
-        super(context, attrs, injector);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mUdfpsIconController = new UdfpsIconController(mContext, mIconView, mIndicatorView);
-    }
-
-    @Modality
-    int getActiveSensorType() {
-        return mActiveSensorType;
-    }
-
-    boolean isFingerprintUdfps() {
-        return mFingerprintSensorProps.isAnyUdfpsType();
-    }
-
-    void setModalityListener(@NonNull ModalityListener listener) {
-        mModalityListener = listener;
-    }
-
-    void setFingerprintSensorProps(@NonNull FingerprintSensorPropertiesInternal sensorProps) {
-        mFingerprintSensorProps = sensorProps;
-    }
-
-    @Override
-    protected int getDelayAfterAuthenticatedDurationMs() {
-        return mActiveSensorType == TYPE_FINGERPRINT ? 0
-                : super.getDelayAfterAuthenticatedDurationMs();
-    }
-
-    @Override
-    protected boolean supportsManualRetry() {
-        return false;
-    }
-
-    @Override
-    public void onAuthenticationFailed(
-            @Modality int modality, @Nullable String failureReason) {
-        super.onAuthenticationFailed(modality, checkErrorForFallback(failureReason));
-    }
-
-    @Override
-    public void onError(int modality, String error) {
-        super.onError(modality, checkErrorForFallback(error));
-    }
-
-    private String checkErrorForFallback(String message) {
-        if (mActiveSensorType == TYPE_FACE) {
-            Log.d(TAG, "Falling back to fingerprint: " + message);
-
-            // switching from face -> fingerprint mode, suppress root error messages
-            mCallback.onAction(Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR);
-            return mContext.getString(R.string.fingerprint_dialog_use_fingerprint_instead);
-        }
-        return message;
-    }
-
-    @Override
-    @BiometricState
-    protected int getStateForAfterError() {
-        if (mActiveSensorType == TYPE_FACE) {
-            return STATE_AUTHENTICATING;
-        }
-
-        return super.getStateForAfterError();
-    }
-
-    @Override
-    public void updateState(@BiometricState int newState) {
-        if (mActiveSensorType == TYPE_FACE) {
-            if (newState == STATE_HELP || newState == STATE_ERROR) {
-                mActiveSensorType = TYPE_FINGERPRINT;
-
-                setRequireConfirmation(false);
-                mConfirmButton.setEnabled(false);
-                mConfirmButton.setVisibility(View.GONE);
-
-                if (mModalityListener != null) {
-                    mModalityListener.onModalitySwitched(TYPE_FACE, mActiveSensorType);
-                }
-
-                // Deactivate the face icon controller so it stops drawing to the view
-                mFaceIconController.deactivate();
-                // Then, activate this icon controller. We need to start in the "idle" state
-                mUdfpsIconController.updateState(STATE_IDLE);
-            }
-        } else { // Fingerprint
-            mUdfpsIconController.updateState(newState);
-        }
-
-        super.updateState(newState);
-    }
-
-    @Override
-    @NonNull
-    AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
-        final AuthDialog.LayoutParams layoutParams = super.onMeasureInternal(width, height);
-        return isFingerprintUdfps()
-                ? getUdfpsMeasureAdapter().onMeasureInternal(width, height, layoutParams)
-                : layoutParams;
-    }
-
-    @NonNull
-    private UdfpsDialogMeasureAdapter getUdfpsMeasureAdapter() {
-        if (mUdfpsMeasureAdapter == null
-                || mUdfpsMeasureAdapter.getSensorProps() != mFingerprintSensorProps) {
-            mUdfpsMeasureAdapter = new UdfpsDialogMeasureAdapter(this, mFingerprintSensorProps);
-        }
-        return mUdfpsMeasureAdapter;
-    }
-
-    @Override
-    public void onSaveState(@NonNull Bundle outState) {
-        super.onSaveState(outState);
-        outState.putInt(AuthDialog.KEY_BIOMETRIC_SENSOR_TYPE, mActiveSensorType);
-        outState.putParcelable(AuthDialog.KEY_BIOMETRIC_SENSOR_PROPS, mFingerprintSensorProps);
-    }
-
-    @Override
-    public void restoreState(@Nullable Bundle savedState) {
-        super.restoreState(savedState);
-        if (savedState != null) {
-            mActiveSensorType = savedState.getInt(AuthDialog.KEY_BIOMETRIC_SENSOR_TYPE, TYPE_FACE);
-            mFingerprintSensorProps =
-                    savedState.getParcelable(AuthDialog.KEY_BIOMETRIC_SENSOR_PROPS);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
deleted file mode 100644
index 48f6431..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import android.content.Context;
-import android.graphics.drawable.Animatable2;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
-import android.hardware.biometrics.BiometricAuthenticator.Modality;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-
-public class AuthBiometricFaceView extends AuthBiometricView {
-
-    private static final String TAG = "BiometricPrompt/AuthBiometricFaceView";
-
-    // Delay before dismissing after being authenticated/confirmed.
-    private static final int HIDE_DELAY_MS = 500;
-
-    protected static class IconController extends Animatable2.AnimationCallback {
-        protected Context mContext;
-        protected ImageView mIconView;
-        protected TextView mTextView;
-        protected Handler mHandler;
-        protected boolean mLastPulseLightToDark; // false = dark to light, true = light to dark
-        protected @BiometricState int mState;
-        protected boolean mDeactivated;
-
-        protected IconController(Context context, ImageView iconView, TextView textView) {
-            mContext = context;
-            mIconView = iconView;
-            mTextView = textView;
-            mHandler = new Handler(Looper.getMainLooper());
-            showStaticDrawable(R.drawable.face_dialog_pulse_dark_to_light);
-        }
-
-        protected void animateOnce(int iconRes) {
-            animateIcon(iconRes, false);
-        }
-
-        protected void showStaticDrawable(int iconRes) {
-            mIconView.setImageDrawable(mContext.getDrawable(iconRes));
-        }
-
-        protected void animateIcon(int iconRes, boolean repeat) {
-            Log.d(TAG, "animateIcon, state: " + mState + ", deactivated: " + mDeactivated);
-            if (mDeactivated) {
-                return;
-            }
-
-            final AnimatedVectorDrawable icon =
-                    (AnimatedVectorDrawable) mContext.getDrawable(iconRes);
-            mIconView.setImageDrawable(icon);
-            icon.forceAnimationOnUI();
-            if (repeat) {
-                icon.registerAnimationCallback(this);
-            }
-            icon.start();
-        }
-
-        protected void startPulsing() {
-            mLastPulseLightToDark = false;
-            animateIcon(R.drawable.face_dialog_pulse_dark_to_light, true);
-        }
-
-        protected void pulseInNextDirection() {
-            int iconRes = mLastPulseLightToDark ? R.drawable.face_dialog_pulse_dark_to_light
-                    : R.drawable.face_dialog_pulse_light_to_dark;
-            animateIcon(iconRes, true /* repeat */);
-            mLastPulseLightToDark = !mLastPulseLightToDark;
-        }
-
-        @Override
-        public void onAnimationEnd(Drawable drawable) {
-            super.onAnimationEnd(drawable);
-            Log.d(TAG, "onAnimationEnd, mState: " + mState + ", deactivated: " + mDeactivated);
-            if (mDeactivated) {
-                return;
-            }
-
-            if (mState == STATE_AUTHENTICATING || mState == STATE_HELP) {
-                pulseInNextDirection();
-            }
-        }
-
-        protected void deactivate() {
-            mDeactivated = true;
-        }
-
-        protected void updateState(int lastState, int newState) {
-            if (mDeactivated) {
-                Log.w(TAG, "Ignoring updateState when deactivated: " + newState);
-                return;
-            }
-
-            final boolean lastStateIsErrorIcon =
-                    lastState == STATE_ERROR || lastState == STATE_HELP;
-
-            if (newState == STATE_AUTHENTICATING_ANIMATING_IN) {
-                showStaticDrawable(R.drawable.face_dialog_pulse_dark_to_light);
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_authenticating));
-            } else if (newState == STATE_AUTHENTICATING) {
-                startPulsing();
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_authenticating));
-            } else if (lastState == STATE_PENDING_CONFIRMATION && newState == STATE_AUTHENTICATED) {
-                animateOnce(R.drawable.face_dialog_dark_to_checkmark);
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_confirmed));
-            } else if (lastStateIsErrorIcon && newState == STATE_IDLE) {
-                animateOnce(R.drawable.face_dialog_error_to_idle);
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_idle));
-            } else if (lastStateIsErrorIcon && newState == STATE_AUTHENTICATED) {
-                animateOnce(R.drawable.face_dialog_dark_to_checkmark);
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_authenticated));
-            } else if (newState == STATE_ERROR && lastState != STATE_ERROR) {
-                animateOnce(R.drawable.face_dialog_dark_to_error);
-            } else if (lastState == STATE_AUTHENTICATING && newState == STATE_AUTHENTICATED) {
-                animateOnce(R.drawable.face_dialog_dark_to_checkmark);
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_authenticated));
-            } else if (newState == STATE_PENDING_CONFIRMATION) {
-                animateOnce(R.drawable.face_dialog_wink_from_dark);
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_authenticated));
-            } else if (newState == STATE_IDLE) {
-                showStaticDrawable(R.drawable.face_dialog_idle_static);
-                mIconView.setContentDescription(mContext.getString(
-                        R.string.biometric_dialog_face_icon_description_idle));
-            } else {
-                Log.w(TAG, "Unhandled state: " + newState);
-            }
-            mState = newState;
-        }
-    }
-
-    @Nullable @VisibleForTesting IconController mFaceIconController;
-    @NonNull private final OnAttachStateChangeListener mOnAttachStateChangeListener =
-            new OnAttachStateChangeListener() {
-        @Override
-        public void onViewAttachedToWindow(View v) {
-
-        }
-
-        @Override
-        public void onViewDetachedFromWindow(View v) {
-            mFaceIconController.deactivate();
-        }
-    };
-
-    public AuthBiometricFaceView(Context context) {
-        this(context, null);
-    }
-
-    public AuthBiometricFaceView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @VisibleForTesting
-    AuthBiometricFaceView(Context context, AttributeSet attrs, Injector injector) {
-        super(context, attrs, injector);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mFaceIconController = new IconController(mContext, mIconView, mIndicatorView);
-
-        addOnAttachStateChangeListener(mOnAttachStateChangeListener);
-    }
-
-    @Override
-    protected int getDelayAfterAuthenticatedDurationMs() {
-        return HIDE_DELAY_MS;
-    }
-
-    @Override
-    protected int getStateForAfterError() {
-        return STATE_IDLE;
-    }
-
-    @Override
-    protected void handleResetAfterError() {
-        resetErrorView();
-    }
-
-    @Override
-    protected void handleResetAfterHelp() {
-        resetErrorView();
-    }
-
-    @Override
-    protected boolean supportsSmallDialog() {
-        return true;
-    }
-
-    @Override
-    protected boolean supportsManualRetry() {
-        return true;
-    }
-
-    @Override
-    public void updateState(@BiometricState int newState) {
-        mFaceIconController.updateState(mState, newState);
-
-        if (newState == STATE_AUTHENTICATING_ANIMATING_IN ||
-                (newState == STATE_AUTHENTICATING && getSize() == AuthDialog.SIZE_MEDIUM)) {
-            resetErrorView();
-        }
-
-        // Do this last since the state variable gets updated.
-        super.updateState(newState);
-    }
-
-    @Override
-    public void onAuthenticationFailed(@Modality int modality, @Nullable String failureReason) {
-        if (getSize() == AuthDialog.SIZE_MEDIUM) {
-            if (supportsManualRetry()) {
-                mTryAgainButton.setVisibility(View.VISIBLE);
-                mConfirmButton.setVisibility(View.GONE);
-            }
-        }
-
-        // Do this last since we want to know if the button is being animated (in the case of
-        // small -> medium dialog)
-        super.onAuthenticationFailed(modality, failureReason);
-    }
-
-    private void resetErrorView() {
-        mIndicatorView.setTextColor(mTextColorHint);
-        mIndicatorView.setVisibility(View.INVISIBLE);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.kt
new file mode 100644
index 0000000..be89d10
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.biometrics
+
+import android.content.Context
+import android.hardware.biometrics.BiometricAuthenticator.Modality
+import android.util.AttributeSet
+
+/** Face only view for BiometricPrompt. */
+class AuthBiometricFaceView(
+    context: Context,
+    attrs: AttributeSet? = null
+) : AuthBiometricView(context, attrs) {
+
+    override fun getDelayAfterAuthenticatedDurationMs() = HIDE_DELAY_MS
+
+    override fun getStateForAfterError() = STATE_IDLE
+
+    override fun handleResetAfterError() = resetErrorView()
+
+    override fun handleResetAfterHelp() = resetErrorView()
+
+    override fun supportsSmallDialog() = true
+
+    override fun supportsManualRetry() = true
+
+    override fun supportsRequireConfirmation() = true
+
+    override fun createIconController(): AuthIconController =
+        AuthBiometricFaceIconController(mContext, mIconView)
+
+    override fun updateState(@BiometricState newState: Int) {
+        if (newState == STATE_AUTHENTICATING_ANIMATING_IN ||
+            newState == STATE_AUTHENTICATING && size == AuthDialog.SIZE_MEDIUM) {
+            resetErrorView()
+        }
+
+        // Do this last since the state variable gets updated.
+        super.updateState(newState)
+    }
+
+    override fun onAuthenticationFailed(
+        @Modality modality: Int,
+        failureReason: String?
+    ) {
+        if (size == AuthDialog.SIZE_MEDIUM) {
+            if (supportsManualRetry()) {
+                mTryAgainButton.visibility = VISIBLE
+                mConfirmButton.visibility = GONE
+            }
+        }
+
+        // Do this last since we want to know if the button is being animated (in the case of
+        // small -> medium dialog)
+        super.onAuthenticationFailed(modality, failureReason)
+    }
+
+    private fun resetErrorView() {
+        mIndicatorView.setTextColor(mTextColorHint)
+        mIndicatorView.visibility = INVISIBLE
+    }
+
+    companion object {
+        /** Delay before dismissing after being authenticated/confirmed. */
+        const val HIDE_DELAY_MS = 500
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
new file mode 100644
index 0000000..3e4e573
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.biometrics
+
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.widget.ImageView
+import com.android.systemui.R
+import com.android.systemui.biometrics.AuthBiometricView.BiometricState
+import com.android.systemui.biometrics.AuthBiometricView.STATE_PENDING_CONFIRMATION
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATED
+import com.android.systemui.biometrics.AuthBiometricView.STATE_ERROR
+import com.android.systemui.biometrics.AuthBiometricView.STATE_HELP
+
+/** Face/Fingerprint combined icon animator for BiometricPrompt. */
+class AuthBiometricFingerprintAndFaceIconController(
+    context: Context,
+    iconView: ImageView
+) : AuthBiometricFingerprintIconController(context, iconView) {
+
+    override val actsAsConfirmButton: Boolean = true
+
+    override fun shouldAnimateForTransition(
+        @BiometricState oldState: Int,
+        @BiometricState newState: Int
+    ): Boolean = when (newState) {
+        STATE_PENDING_CONFIRMATION -> true
+        STATE_AUTHENTICATED -> false
+        else -> super.shouldAnimateForTransition(oldState, newState)
+    }
+
+    override fun getAnimationForTransition(
+        @BiometricState oldState: Int,
+        @BiometricState newState: Int
+    ): Drawable? = when (newState) {
+        STATE_PENDING_CONFIRMATION -> {
+            if (oldState == STATE_ERROR || oldState == STATE_HELP) {
+                context.getDrawable(R.drawable.fingerprint_dialog_error_to_unlock)
+            } else {
+                context.getDrawable(R.drawable.fingerprint_dialog_fp_to_unlock)
+            }
+        }
+        STATE_AUTHENTICATED -> null
+        else -> super.getAnimationForTransition(oldState, newState)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
new file mode 100644
index 0000000..7371442
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
@@ -0,0 +1,43 @@
+/*
+ * 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.biometrics
+
+import android.content.Context
+import android.hardware.biometrics.BiometricAuthenticator.Modality
+import android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE
+import android.util.AttributeSet
+import com.android.systemui.R
+
+/** Face/Fingerprint combined view for BiometricPrompt. */
+class AuthBiometricFingerprintAndFaceView(
+    context: Context,
+    attrs: AttributeSet?
+) : AuthBiometricFingerprintView(context, attrs) {
+
+    constructor (context: Context) : this(context, null)
+
+    override fun getConfirmationPrompt() = R.string.biometric_dialog_tap_confirm_with_face
+
+    override fun forceRequireConfirmation(@Modality modality: Int) = modality == TYPE_FACE
+
+    override fun ignoreUnsuccessfulEventsFrom(@Modality modality: Int) = modality == TYPE_FACE
+
+    override fun onPointerDown(failedModalities: Set<Int>) = failedModalities.contains(TYPE_FACE)
+
+    override fun createIconController(): AuthIconController =
+        AuthBiometricFingerprintAndFaceIconController(mContext, mIconView)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
new file mode 100644
index 0000000..cd16379
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -0,0 +1,112 @@
+/*
+ * 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.biometrics
+
+import android.content.Context
+import android.graphics.drawable.AnimatedVectorDrawable
+import android.graphics.drawable.Drawable
+import android.widget.ImageView
+import com.android.systemui.R
+import com.android.systemui.biometrics.AuthBiometricView.BiometricState
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATED
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATING
+import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATING_ANIMATING_IN
+import com.android.systemui.biometrics.AuthBiometricView.STATE_ERROR
+import com.android.systemui.biometrics.AuthBiometricView.STATE_HELP
+import com.android.systemui.biometrics.AuthBiometricView.STATE_IDLE
+import com.android.systemui.biometrics.AuthBiometricView.STATE_PENDING_CONFIRMATION
+
+/** Fingerprint only icon animator for BiometricPrompt.  */
+open class AuthBiometricFingerprintIconController(
+    context: Context,
+    iconView: ImageView
+) : AuthIconController(context, iconView) {
+
+    init {
+        val size = context.resources.getDimensionPixelSize(
+            R.dimen.biometric_dialog_fingerprint_icon_size
+        )
+        iconView.layoutParams.width = size
+        iconView.layoutParams.height = size
+    }
+
+    override fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int) {
+        val icon = getAnimationForTransition(lastState, newState) ?: return
+
+        iconView.setImageDrawable(icon)
+
+        val iconContentDescription = getIconContentDescription(newState)
+        if (iconContentDescription != null) {
+            iconView.contentDescription = iconContentDescription
+        }
+
+        (icon as? AnimatedVectorDrawable)?.apply {
+            reset()
+            if (shouldAnimateForTransition(lastState, newState)) {
+                forceAnimationOnUI()
+                start()
+            }
+        }
+    }
+
+    private fun getIconContentDescription(@BiometricState newState: Int): CharSequence? {
+        val id = when (newState) {
+            STATE_IDLE,
+            STATE_AUTHENTICATING_ANIMATING_IN,
+            STATE_AUTHENTICATING,
+            STATE_PENDING_CONFIRMATION,
+            STATE_AUTHENTICATED -> R.string.accessibility_fingerprint_dialog_fingerprint_icon
+            STATE_ERROR,
+            STATE_HELP -> R.string.biometric_dialog_try_again
+            else -> null
+        }
+        return if (id != null) context.getString(id) else null
+    }
+
+    protected open fun shouldAnimateForTransition(
+        @BiometricState oldState: Int,
+        @BiometricState newState: Int
+    ) = when (newState) {
+        STATE_HELP,
+        STATE_ERROR -> true
+        STATE_AUTHENTICATING_ANIMATING_IN,
+        STATE_AUTHENTICATING -> oldState == STATE_ERROR || oldState == STATE_HELP
+        STATE_AUTHENTICATED -> false
+        else -> false
+    }
+
+    protected open fun getAnimationForTransition(
+        @BiometricState oldState: Int,
+        @BiometricState newState: Int
+    ): Drawable? {
+        val id = when (newState) {
+            STATE_HELP,
+            STATE_ERROR -> R.drawable.fingerprint_dialog_fp_to_error
+            STATE_AUTHENTICATING_ANIMATING_IN,
+            STATE_AUTHENTICATING -> {
+                if (oldState == STATE_ERROR || oldState == STATE_HELP) {
+                    R.drawable.fingerprint_dialog_error_to_fp
+                } else {
+                    R.drawable.fingerprint_dialog_fp_to_error
+                }
+            }
+            STATE_AUTHENTICATED -> R.drawable.fingerprint_dialog_fp_to_error
+            else -> return null
+        }
+        return if (id != null) context.getDrawable(id) else null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java
deleted file mode 100644
index ee602bc..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-
-import android.content.Context;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-
-import com.android.systemui.R;
-
-public class AuthBiometricFingerprintView extends AuthBiometricView {
-
-    private static final String TAG = "BiometricPrompt/AuthBiometricFingerprintView";
-
-    public AuthBiometricFingerprintView(Context context) {
-        this(context, null);
-    }
-
-    public AuthBiometricFingerprintView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected int getDelayAfterAuthenticatedDurationMs() {
-        return 0;
-    }
-
-    @Override
-    protected int getStateForAfterError() {
-        return STATE_AUTHENTICATING;
-    }
-
-    @Override
-    protected void handleResetAfterError() {
-        showTouchSensorString();
-    }
-
-    @Override
-    protected void handleResetAfterHelp() {
-        showTouchSensorString();
-    }
-
-    @Override
-    protected boolean supportsSmallDialog() {
-        return false;
-    }
-
-    @Override
-    public void updateState(@BiometricState int newState) {
-        updateIcon(mState, newState);
-
-        // Do this last since the state variable gets updated.
-        super.updateState(newState);
-    }
-
-    @Override
-    void onAttachedToWindowInternal() {
-        super.onAttachedToWindowInternal();
-        showTouchSensorString();
-    }
-
-    private void showTouchSensorString() {
-        mIndicatorView.setText(R.string.fingerprint_dialog_touch_sensor);
-        mIndicatorView.setTextColor(mTextColorHint);
-    }
-
-    private void updateIcon(int lastState, int newState) {
-        final Drawable icon = getAnimationForTransition(lastState, newState);
-        if (icon == null) {
-            Log.e(TAG, "Animation not found, " + lastState + " -> " + newState);
-            return;
-        }
-
-        final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
-                ? (AnimatedVectorDrawable) icon
-                : null;
-
-        mIconView.setImageDrawable(icon);
-
-        final CharSequence iconContentDescription = getIconContentDescription(newState);
-        if (iconContentDescription != null) {
-            mIconView.setContentDescription(iconContentDescription);
-        }
-
-        if (animation != null && shouldAnimateForTransition(lastState, newState)) {
-            animation.forceAnimationOnUI();
-            animation.start();
-        }
-    }
-
-    @Nullable
-    private CharSequence getIconContentDescription(int newState) {
-        switch (newState) {
-            case STATE_IDLE:
-            case STATE_AUTHENTICATING_ANIMATING_IN:
-            case STATE_AUTHENTICATING:
-            case STATE_PENDING_CONFIRMATION:
-            case STATE_AUTHENTICATED:
-                return mContext.getString(
-                        R.string.accessibility_fingerprint_dialog_fingerprint_icon);
-
-            case STATE_ERROR:
-            case STATE_HELP:
-                return mContext.getString(R.string.biometric_dialog_try_again);
-
-            default:
-                return null;
-        }
-    }
-
-    private boolean shouldAnimateForTransition(int oldState, int newState) {
-        switch (newState) {
-            case STATE_HELP:
-            case STATE_ERROR:
-                return true;
-            case STATE_AUTHENTICATING_ANIMATING_IN:
-            case STATE_AUTHENTICATING:
-                if (oldState == STATE_ERROR || oldState == STATE_HELP) {
-                    return true;
-                } else {
-                    return false;
-                }
-            case STATE_AUTHENTICATED:
-                return false;
-            default:
-                return false;
-        }
-    }
-
-    private Drawable getAnimationForTransition(int oldState, int newState) {
-        int iconRes;
-
-        switch (newState) {
-            case STATE_HELP:
-            case STATE_ERROR:
-                iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-                break;
-            case STATE_AUTHENTICATING_ANIMATING_IN:
-            case STATE_AUTHENTICATING:
-                if (oldState == STATE_ERROR || oldState == STATE_HELP) {
-                    iconRes = R.drawable.fingerprint_dialog_error_to_fp;
-                } else {
-                    iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-                }
-                break;
-            case STATE_AUTHENTICATED:
-                iconRes = R.drawable.fingerprint_dialog_fp_to_error;
-                break;
-            default:
-                return null;
-        }
-
-        return mContext.getDrawable(iconRes);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
new file mode 100644
index 0000000..368bc3a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.biometrics
+
+import android.content.Context
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.util.AttributeSet
+import android.util.Log
+import android.widget.FrameLayout
+import android.widget.TextView
+import com.android.systemui.R
+
+private const val TAG = "AuthBiometricFingerprintView"
+
+/** Fingerprint only view for BiometricPrompt.  */
+open class AuthBiometricFingerprintView(
+    context: Context,
+    attrs: AttributeSet? = null
+) : AuthBiometricView(context, attrs) {
+    /** If this view is for a UDFPS sensor.  */
+    var isUdfps = false
+        private set
+
+    private var udfpsAdapter: UdfpsDialogMeasureAdapter? = null
+
+    /** Set the [sensorProps] of this sensor so the view can be customized prior to layout. */
+    fun setSensorProperties(sensorProps: FingerprintSensorPropertiesInternal) {
+        isUdfps = sensorProps.isAnyUdfpsType
+        udfpsAdapter = if (isUdfps) UdfpsDialogMeasureAdapter(this, sensorProps) else null
+    }
+
+    override fun onMeasureInternal(width: Int, height: Int): AuthDialog.LayoutParams {
+        val layoutParams = super.onMeasureInternal(width, height)
+        return udfpsAdapter?.onMeasureInternal(width, height, layoutParams) ?: layoutParams
+    }
+
+    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
+        super.onLayout(changed, left, top, right, bottom)
+
+        val adapter = udfpsAdapter
+        if (adapter != null) {
+            // Move the UDFPS icon and indicator text if necessary. This probably only needs to happen
+            // for devices where the UDFPS sensor is too low.
+            // TODO(b/201510778): Update this logic to support cases where the sensor or text overlap
+            //  the button bar area.
+            val bottomSpacerHeight = adapter.bottomSpacerHeight
+            Log.w(TAG, "bottomSpacerHeight: $bottomSpacerHeight")
+            if (bottomSpacerHeight < 0) {
+                val iconFrame = findViewById<FrameLayout>(R.id.biometric_icon_frame)!!
+                iconFrame.translationY = -bottomSpacerHeight.toFloat()
+                val indicator = findViewById<TextView>(R.id.indicator)!!
+                indicator.translationY = -bottomSpacerHeight.toFloat()
+            }
+        }
+    }
+
+    override fun getDelayAfterAuthenticatedDurationMs() = 0
+
+    override fun getStateForAfterError() = STATE_AUTHENTICATING
+
+    override fun handleResetAfterError() = showTouchSensorString()
+
+    override fun handleResetAfterHelp() = showTouchSensorString()
+
+    override fun supportsSmallDialog() = false
+
+    override fun createIconController(): AuthIconController =
+        AuthBiometricFingerprintIconController(mContext, mIconView)
+
+    override fun onAttachedToWindow() {
+        super.onAttachedToWindow()
+        showTouchSensorString()
+    }
+
+    private fun showTouchSensorString() {
+        mIndicatorView.setText(R.string.fingerprint_dialog_touch_sensor)
+        mIndicatorView.setTextColor(mTextColorHint)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
new file mode 100644
index 0000000..ce5e600
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
@@ -0,0 +1,94 @@
+/*
+ * 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.biometrics
+
+import android.annotation.DrawableRes
+import android.content.Context
+import android.graphics.drawable.Animatable2
+import android.graphics.drawable.AnimatedVectorDrawable
+import android.graphics.drawable.Drawable
+import android.util.Log
+import android.widget.ImageView
+import com.android.systemui.biometrics.AuthBiometricView.BiometricState
+
+private const val TAG = "AuthIconController"
+
+/** Controller for animating the BiometricPrompt icon/affordance. */
+abstract class AuthIconController(
+    protected val context: Context,
+    protected val iconView: ImageView
+) : Animatable2.AnimationCallback() {
+
+    /** If this controller should ignore events and pause. */
+    var deactivated: Boolean = false
+
+    /** If the icon view should be treated as an alternate "confirm" button. */
+    open val actsAsConfirmButton: Boolean = false
+
+    final override fun onAnimationStart(drawable: Drawable) {
+        super.onAnimationStart(drawable)
+    }
+
+    final override fun onAnimationEnd(drawable: Drawable) {
+        super.onAnimationEnd(drawable)
+
+        if (!deactivated) {
+            handleAnimationEnd(drawable)
+        }
+    }
+
+    /** Set the icon to a static image. */
+    protected fun showStaticDrawable(@DrawableRes iconRes: Int) {
+        iconView.setImageDrawable(context.getDrawable(iconRes))
+    }
+
+    /** Animate a resource. */
+    protected fun animateIconOnce(@DrawableRes iconRes: Int) {
+        animateIcon(iconRes, false)
+    }
+
+    /** Animate a resource. */
+    protected fun animateIcon(@DrawableRes iconRes: Int, repeat: Boolean) {
+        if (!deactivated) {
+            val icon = context.getDrawable(iconRes) as AnimatedVectorDrawable
+            iconView.setImageDrawable(icon)
+            icon.forceAnimationOnUI()
+            if (repeat) {
+                icon.registerAnimationCallback(this)
+            }
+            icon.start()
+        }
+    }
+
+    /** Update the icon to reflect the [newState]. */
+    fun updateState(@BiometricState lastState: Int, @BiometricState newState: Int) {
+        if (deactivated) {
+            Log.w(TAG, "Ignoring updateState when deactivated: $newState")
+        } else {
+            updateIcon(lastState, newState)
+        }
+    }
+
+    /** If the icon should act as a "retry" button in the [currentState]. */
+    fun iconTapSendsRetryWhen(@BiometricState currentState: Int): Boolean = false
+
+    /** Call during [updateState] if the controller is not [deactivated]. */
+    abstract fun updateIcon(@BiometricState lastState: Int, @BiometricState newState: Int)
+
+    /** Called during [onAnimationEnd] if the controller is not [deactivated]. */
+    open fun handleAnimationEnd(drawable: Drawable) {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
deleted file mode 100644
index d80d9cc..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricUdfpsView.java
+++ /dev/null
@@ -1,80 +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.biometrics;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-
-/**
- * Manages the layout for under-display fingerprint sensors (UDFPS). Ensures that UI elements
- * do not overlap with
- */
-public class AuthBiometricUdfpsView extends AuthBiometricFingerprintView {
-    private static final String TAG = "AuthBiometricUdfpsView";
-
-    @Nullable private UdfpsDialogMeasureAdapter mMeasureAdapter;
-
-    public AuthBiometricUdfpsView(Context context) {
-        this(context, null /* attrs */);
-    }
-
-    public AuthBiometricUdfpsView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    void setSensorProps(@NonNull FingerprintSensorPropertiesInternal sensorProps) {
-        if (mMeasureAdapter == null || mMeasureAdapter.getSensorProps() != sensorProps) {
-            mMeasureAdapter = new UdfpsDialogMeasureAdapter(this, sensorProps);
-        }
-    }
-
-    @Override
-    @NonNull
-    AuthDialog.LayoutParams onMeasureInternal(int width, int height) {
-        final AuthDialog.LayoutParams layoutParams = super.onMeasureInternal(width, height);
-        return mMeasureAdapter != null
-                ? mMeasureAdapter.onMeasureInternal(width, height, layoutParams)
-                : layoutParams;
-    }
-
-    @Override
-    void onLayoutInternal() {
-        super.onLayoutInternal();
-
-        // Move the UDFPS icon and indicator text if necessary. This probably only needs to happen
-        // for devices where the UDFPS sensor is too low.
-        // TODO(b/201510778): Update this logic to support cases where the sensor or text overlap
-        //  the button bar area.
-        final int bottomSpacerHeight = mMeasureAdapter.getBottomSpacerHeight();
-        Log.w(TAG, "bottomSpacerHeight: " + bottomSpacerHeight);
-        if (bottomSpacerHeight < 0) {
-            FrameLayout iconFrame = findViewById(R.id.biometric_icon_frame);
-            iconFrame.setTranslationY(-bottomSpacerHeight);
-
-            TextView indicator = findViewById(R.id.indicator);
-            indicator.setTranslationY(-bottomSpacerHeight);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index 1496f17..76d4aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -25,6 +25,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator.Modality;
 import android.hardware.biometrics.BiometricPrompt;
@@ -44,19 +45,21 @@
 import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.R;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 /**
- * Contains the Biometric views (title, subtitle, icon, buttons, etc) and its controllers.
+ * Contains the Biometric views (title, subtitle, icon, buttons, etc.) and its controllers.
  */
-public abstract class AuthBiometricView extends LinearLayout {
+public class AuthBiometricView extends LinearLayout {
 
-    private static final String TAG = "BiometricPrompt/AuthBiometricView";
+    private static final String TAG = "AuthBiometricView";
 
     /**
      * Authentication hardware idle.
@@ -102,13 +105,6 @@
         int ACTION_BUTTON_TRY_AGAIN = 4;
         int ACTION_ERROR = 5;
         int ACTION_USE_DEVICE_CREDENTIAL = 6;
-        /**
-         * Notify the receiver to start the fingerprint sensor.
-         *
-         * This is only applicable to multi-sensor devices that need to delay fingerprint auth
-         * (i.e face -> fingerprint).
-         */
-        int ACTION_START_DELAYED_FINGERPRINT_SENSOR = 7;
 
         /**
          * When an action has occurred. The caller will only invoke this when the callback should
@@ -118,66 +114,9 @@
         void onAction(int action);
     }
 
-    @VisibleForTesting
-    static class Injector {
-        AuthBiometricView mBiometricView;
-
-        public Button getNegativeButton() {
-            return mBiometricView.findViewById(R.id.button_negative);
-        }
-
-        public Button getCancelButton() {
-            return mBiometricView.findViewById(R.id.button_cancel);
-        }
-
-        public Button getUseCredentialButton() {
-            return mBiometricView.findViewById(R.id.button_use_credential);
-        }
-
-        public Button getConfirmButton() {
-            return mBiometricView.findViewById(R.id.button_confirm);
-        }
-
-        public Button getTryAgainButton() {
-            return mBiometricView.findViewById(R.id.button_try_again);
-        }
-
-        public TextView getTitleView() {
-            return mBiometricView.findViewById(R.id.title);
-        }
-
-        public TextView getSubtitleView() {
-            return mBiometricView.findViewById(R.id.subtitle);
-        }
-
-        public TextView getDescriptionView() {
-            return mBiometricView.findViewById(R.id.description);
-        }
-
-        public TextView getIndicatorView() {
-            return mBiometricView.findViewById(R.id.indicator);
-        }
-
-        public ImageView getIconView() {
-            return mBiometricView.findViewById(R.id.biometric_icon);
-        }
-
-        public View getIconHolderView() {
-            return mBiometricView.findViewById(R.id.biometric_icon_frame);
-        }
-
-        public int getDelayAfterError() {
-            return BiometricPrompt.HIDE_DIALOG_DELAY;
-        }
-
-        public int getMediumToLargeAnimationDurationMs() {
-            return AuthDialog.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS;
-        }
-    }
-
-    private final Injector mInjector;
     protected final Handler mHandler;
     private final AccessibilityManager mAccessibilityManager;
+    private final LockPatternUtils mLockPatternUtils;
     protected final int mTextColorError;
     protected final int mTextColorHint;
 
@@ -195,6 +134,11 @@
     protected ImageView mIconView;
     protected TextView mIndicatorView;
 
+    @VisibleForTesting @NonNull AuthIconController mIconController;
+    @VisibleForTesting int mAnimationDurationShort = AuthDialog.ANIMATE_SMALL_TO_MEDIUM_DURATION_MS;
+    @VisibleForTesting int mAnimationDurationLong = AuthDialog.ANIMATE_MEDIUM_TO_LARGE_DURATION_MS;
+    @VisibleForTesting int mAnimationDurationHideDialog = BiometricPrompt.HIDE_DIALOG_DELAY;
+
     // Negative button position, exclusively for the app-specified behavior
     @VisibleForTesting Button mNegativeButton;
     // Negative button position, exclusively for cancelling auth after passive auth success
@@ -217,30 +161,7 @@
     protected boolean mDialogSizeAnimating;
     protected Bundle mSavedState;
 
-    /**
-     * Delay after authentication is confirmed, before the dialog should be animated away.
-     */
-    protected abstract int getDelayAfterAuthenticatedDurationMs();
-    /**
-     * State that the dialog/icon should be in after showing a help message.
-     */
-    protected abstract int getStateForAfterError();
-    /**
-     * Invoked when the error message is being cleared.
-     */
-    protected abstract void handleResetAfterError();
-    /**
-     * Invoked when the help message is being cleared.
-     */
-    protected abstract void handleResetAfterHelp();
-
-    /**
-     * @return true if the dialog supports {@link AuthDialog.DialogSize#SIZE_SMALL}
-     */
-    protected abstract boolean supportsSmallDialog();
-
     private final Runnable mResetErrorRunnable;
-
     private final Runnable mResetHelpRunnable;
 
     private final OnClickListener mBackgroundClickListener = (view) -> {
@@ -262,11 +183,6 @@
     }
 
     public AuthBiometricView(Context context, AttributeSet attrs) {
-        this(context, attrs, new Injector());
-    }
-
-    @VisibleForTesting
-    AuthBiometricView(Context context, AttributeSet attrs, Injector injector) {
         super(context, attrs);
         mHandler = new Handler(Looper.getMainLooper());
         mTextColorError = getResources().getColor(
@@ -274,10 +190,8 @@
         mTextColorHint = getResources().getColor(
                 R.color.biometric_dialog_gray, context.getTheme());
 
-        mInjector = injector;
-        mInjector.mBiometricView = this;
-
         mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+        mLockPatternUtils = new LockPatternUtils(context);
 
         mResetErrorRunnable = () -> {
             updateState(getStateForAfterError());
@@ -292,36 +206,91 @@
         };
     }
 
-    public void setPanelController(AuthPanelController panelController) {
+    /** Delay after authentication is confirmed, before the dialog should be animated away. */
+    protected int getDelayAfterAuthenticatedDurationMs() {
+        return 0;
+    }
+
+    /** State that the dialog/icon should be in after showing a help message. */
+    protected int getStateForAfterError() {
+        return STATE_IDLE;
+    }
+
+    /** Invoked when the error message is being cleared. */
+    protected void handleResetAfterError() {}
+
+    /** Invoked when the help message is being cleared. */
+    protected void handleResetAfterHelp() {}
+
+    /** True if the dialog supports {@link AuthDialog.DialogSize#SIZE_SMALL}. */
+    protected boolean supportsSmallDialog() {
+        return false;
+    }
+
+    /** The string to show when the user must tap to confirm via the button or icon. */
+    @StringRes
+    protected int getConfirmationPrompt() {
+        return R.string.biometric_dialog_tap_confirm;
+    }
+
+    /** True if require confirmation will be honored when set via the API. */
+    protected boolean supportsRequireConfirmation() {
+        return false;
+    }
+
+    /** True if confirmation will be required even if it was not supported/requested. */
+    protected boolean forceRequireConfirmation(@Modality int modality) {
+        return false;
+    }
+
+    /** Ignore all events from this (secondary) modality except successful authentication. */
+    protected boolean ignoreUnsuccessfulEventsFrom(@Modality int modality) {
+        return false;
+    }
+
+    /**
+     * Create the controller for managing the icons transitions during the prompt.
+     *
+     * Subclass should override.
+     */
+    @NonNull
+    protected AuthIconController createIconController() {
+        return new AuthIconController(mContext, mIconView) {
+            @Override
+            public void updateIcon(int lastState, int newState) {}
+        };
+    }
+
+    void setPanelController(AuthPanelController panelController) {
         mPanelController = panelController;
     }
 
-    public void setPromptInfo(PromptInfo promptInfo) {
+    void setPromptInfo(PromptInfo promptInfo) {
         mPromptInfo = promptInfo;
     }
 
-    public void setCallback(Callback callback) {
+    void setCallback(Callback callback) {
         mCallback = callback;
     }
 
-    public void setBackgroundView(View backgroundView) {
+    void setBackgroundView(View backgroundView) {
         backgroundView.setOnClickListener(mBackgroundClickListener);
     }
 
-    public void setUserId(int userId) {
+    void setUserId(int userId) {
         mUserId = userId;
     }
 
-    public void setEffectiveUserId(int effectiveUserId) {
+    void setEffectiveUserId(int effectiveUserId) {
         mEffectiveUserId = effectiveUserId;
     }
 
-    public void setRequireConfirmation(boolean requireConfirmation) {
-        mRequireConfirmation = requireConfirmation;
+    void setRequireConfirmation(boolean requireConfirmation) {
+        mRequireConfirmation = requireConfirmation && supportsRequireConfirmation();
     }
 
     @VisibleForTesting
-    void updateSize(@AuthDialog.DialogSize int newSize) {
+    final void updateSize(@AuthDialog.DialogSize int newSize) {
         Log.v(TAG, "Current size: " + mSize + " New size: " + newSize);
         if (newSize == AuthDialog.SIZE_SMALL) {
             mTitleView.setVisibility(View.GONE);
@@ -376,7 +345,7 @@
 
             // Choreograph together
             final AnimatorSet as = new AnimatorSet();
-            as.setDuration(AuthDialog.ANIMATE_SMALL_TO_MEDIUM_DURATION_MS);
+            as.setDuration(mAnimationDurationShort);
             as.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationStart(Animator animation) {
@@ -429,7 +398,7 @@
             // Translate at full duration
             final ValueAnimator translationAnimator = ValueAnimator.ofFloat(
                     biometricView.getY(), biometricView.getY() - translationY);
-            translationAnimator.setDuration(mInjector.getMediumToLargeAnimationDurationMs());
+            translationAnimator.setDuration(mAnimationDurationLong);
             translationAnimator.addUpdateListener((animation) -> {
                 final float translation = (float) animation.getAnimatedValue();
                 biometricView.setTranslationY(translation);
@@ -438,7 +407,7 @@
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     super.onAnimationEnd(animation);
-                    if (biometricView.getParent() != null) {
+                    if (biometricView.getParent() instanceof ViewGroup) {
                         ((ViewGroup) biometricView.getParent()).removeView(biometricView);
                     }
                     mSize = newSize;
@@ -447,7 +416,7 @@
 
             // Opacity to 0 in half duration
             final ValueAnimator opacityAnimator = ValueAnimator.ofFloat(1, 0);
-            opacityAnimator.setDuration(mInjector.getMediumToLargeAnimationDurationMs() / 2);
+            opacityAnimator.setDuration(mAnimationDurationLong / 2);
             opacityAnimator.addUpdateListener((animation) -> {
                 final float opacity = (float) animation.getAnimatedValue();
                 biometricView.setAlpha(opacity);
@@ -457,7 +426,7 @@
             mPanelController.updateForContentDimensions(
                     mPanelController.getContainerWidth(),
                     mPanelController.getContainerHeight(),
-                    mInjector.getMediumToLargeAnimationDurationMs());
+                    mAnimationDurationLong);
 
             // Start the animations together
             AnimatorSet as = new AnimatorSet();
@@ -466,7 +435,7 @@
             animators.add(opacityAnimator);
 
             as.playTogether(animators);
-            as.setDuration(mInjector.getMediumToLargeAnimationDurationMs() * 2 / 3);
+            as.setDuration(mAnimationDurationLong * 2 / 3);
             as.start();
         } else {
             Log.e(TAG, "Unknown transition from: " + mSize + " to: " + newSize);
@@ -481,6 +450,8 @@
     public void updateState(@BiometricState int newState) {
         Log.v(TAG, "newState: " + newState);
 
+        mIconController.updateState(mState, newState);
+
         switch (newState) {
             case STATE_AUTHENTICATING_ANIMATING_IN:
             case STATE_AUTHENTICATING:
@@ -510,10 +481,11 @@
                 mNegativeButton.setVisibility(View.GONE);
                 mCancelButton.setVisibility(View.VISIBLE);
                 mUseCredentialButton.setVisibility(View.GONE);
-                mConfirmButton.setEnabled(true);
-                mConfirmButton.setVisibility(View.VISIBLE);
+                // forced confirmations (multi-sensor) use the icon view as the confirm button
+                mConfirmButton.setEnabled(mRequireConfirmation);
+                mConfirmButton.setVisibility(mRequireConfirmation ? View.VISIBLE : View.GONE);
                 mIndicatorView.setTextColor(mTextColorHint);
-                mIndicatorView.setText(R.string.biometric_dialog_tap_confirm);
+                mIndicatorView.setText(getConfirmationPrompt());
                 mIndicatorView.setVisibility(View.VISIBLE);
                 break;
 
@@ -536,9 +508,9 @@
         updateState(STATE_AUTHENTICATING);
     }
 
-    public void onAuthenticationSucceeded() {
+    public void onAuthenticationSucceeded(@Modality int modality) {
         removePendingAnimations();
-        if (mRequireConfirmation) {
+        if (mRequireConfirmation || forceRequireConfirmation(modality)) {
             updateState(STATE_PENDING_CONFIRMATION);
         } else {
             updateState(STATE_AUTHENTICATED);
@@ -553,6 +525,10 @@
      */
     public void onAuthenticationFailed(
             @Modality int modality, @Nullable String failureReason) {
+        if (ignoreUnsuccessfulEventsFrom(modality)) {
+            return;
+        }
+
         showTemporaryMessage(failureReason, mResetErrorRunnable);
         updateState(STATE_ERROR);
     }
@@ -564,12 +540,27 @@
      * @param error message
      */
     public void onError(@Modality int modality, String error) {
+        if (ignoreUnsuccessfulEventsFrom(modality)) {
+            return;
+        }
+
         showTemporaryMessage(error, mResetErrorRunnable);
         updateState(STATE_ERROR);
 
-        mHandler.postDelayed(() -> {
-            mCallback.onAction(Callback.ACTION_ERROR);
-        }, mInjector.getDelayAfterError());
+        mHandler.postDelayed(() -> mCallback.onAction(Callback.ACTION_ERROR),
+                mAnimationDurationHideDialog);
+    }
+
+    /**
+     * Fingerprint pointer down event. This does nothing by default and will not be called if the
+     * device does not have an appropriate sensor (UDFPS), but it may be used as an alternative
+     * to the "retry" button when fingerprint is used with other modalities.
+     *
+     * @param failedModalities the set of modalities that have failed
+     * @return true if a retry was initiated as a result of this event
+     */
+    public boolean onPointerDown(Set<Integer> failedModalities) {
+        return false;
     }
 
     /**
@@ -579,6 +570,9 @@
      * @param help message
      */
     public void onHelp(@Modality int modality, String help) {
+        if (ignoreUnsuccessfulEventsFrom(modality)) {
+            return;
+        }
         if (mSize != AuthDialog.SIZE_MEDIUM) {
             Log.w(TAG, "Help received in size: " + mSize);
             return;
@@ -639,7 +633,7 @@
         // select to enable marquee unless a screen reader is enabled
         mIndicatorView.setSelected(!mAccessibilityManager.isEnabled()
                 || !mAccessibilityManager.isTouchExplorationEnabled());
-        mHandler.postDelayed(resetMessageRunnable, mInjector.getDelayAfterError());
+        mHandler.postDelayed(resetMessageRunnable, mAnimationDurationHideDialog);
 
         Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
     }
@@ -647,29 +641,22 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        onFinishInflateInternal();
-    }
 
-    /**
-     * After inflation, but before things like restoreState, onAttachedToWindow, etc.
-     */
-    @VisibleForTesting
-    void onFinishInflateInternal() {
-        mTitleView = mInjector.getTitleView();
-        mSubtitleView = mInjector.getSubtitleView();
-        mDescriptionView = mInjector.getDescriptionView();
-        mIconView = mInjector.getIconView();
-        mIconHolderView = mInjector.getIconHolderView();
-        mIndicatorView = mInjector.getIndicatorView();
+        mTitleView = findViewById(R.id.title);
+        mSubtitleView = findViewById(R.id.subtitle);
+        mDescriptionView = findViewById(R.id.description);
+        mIconView = findViewById(R.id.biometric_icon);
+        mIconHolderView = findViewById(R.id.biometric_icon_frame);
+        mIndicatorView = findViewById(R.id.indicator);
 
         // Negative-side (left) buttons
-        mNegativeButton = mInjector.getNegativeButton();
-        mCancelButton = mInjector.getCancelButton();
-        mUseCredentialButton = mInjector.getUseCredentialButton();
+        mNegativeButton = findViewById(R.id.button_negative);
+        mCancelButton = findViewById(R.id.button_cancel);
+        mUseCredentialButton = findViewById(R.id.button_use_credential);
 
         // Positive-side (right) buttons
-        mConfirmButton = mInjector.getConfirmButton();
-        mTryAgainButton = mInjector.getTryAgainButton();
+        mConfirmButton = findViewById(R.id.button_confirm);
+        mTryAgainButton = findViewById(R.id.button_try_again);
 
         mNegativeButton.setOnClickListener((view) -> {
             mCallback.onAction(Callback.ACTION_BUTTON_NEGATIVE);
@@ -693,6 +680,15 @@
             mTryAgainButton.setVisibility(View.GONE);
             Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
         });
+
+        mIconController = createIconController();
+        if (mIconController.getActsAsConfirmButton()) {
+            mIconView.setOnClickListener((view) -> {
+                if (mState == STATE_PENDING_CONFIRMATION) {
+                    updateState(STATE_AUTHENTICATED);
+                }
+            });
+        }
     }
 
     /**
@@ -706,21 +702,13 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        onAttachedToWindowInternal();
-    }
 
-    /**
-     * Contains all the testable logic that should be invoked when {@link #onAttachedToWindow()} is
-     * invoked.
-     */
-    @VisibleForTesting
-    void onAttachedToWindowInternal() {
         mTitleView.setText(mPromptInfo.getTitle());
 
         if (isDeviceCredentialAllowed()) {
             final CharSequence credentialButtonText;
-            final @Utils.CredentialType int credentialType =
-                    Utils.getCredentialType(mContext, mEffectiveUserId);
+            @Utils.CredentialType final int credentialType =
+                    Utils.getCredentialType(mLockPatternUtils, mEffectiveUserId);
             switch (credentialType) {
                 case Utils.CREDENTIAL_PIN:
                     credentialButtonText =
@@ -731,9 +719,6 @@
                             getResources().getString(R.string.biometric_dialog_use_pattern);
                     break;
                 case Utils.CREDENTIAL_PASSWORD:
-                    credentialButtonText =
-                            getResources().getString(R.string.biometric_dialog_use_password);
-                    break;
                 default:
                     credentialButtonText =
                             getResources().getString(R.string.biometric_dialog_use_password);
@@ -749,7 +734,6 @@
         }
 
         setTextOrHide(mSubtitleView, mPromptInfo.getSubtitle());
-
         setTextOrHide(mDescriptionView, mPromptInfo.getDescription());
 
         if (mSavedState == null) {
@@ -774,6 +758,8 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
+        mIconController.setDeactivated(true);
+
         // Empty the handler, otherwise things like ACTION_AUTHENTICATED may be duplicated once
         // the new dialog is restored.
         mHandler.removeCallbacksAndMessages(null /* all */);
@@ -856,15 +842,7 @@
     @Override
     public void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-        onLayoutInternal();
-    }
 
-    /**
-     * Contains all the testable logic that should be invoked when
-     * {@link #onLayout(boolean, int, int, int, int)}, is invoked.
-     */
-    @VisibleForTesting
-    void onLayoutInternal() {
         // Start with initial size only once. Subsequent layout changes don't matter since we
         // only care about the initial icon position.
         if (mIconOriginalY == 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 21edb24..6b6af4c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -16,9 +16,10 @@
 
 package com.android.systemui.biometrics;
 
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
 import static android.hardware.biometrics.BiometricManager.BiometricMultiSensorMode;
 
+import android.annotation.DurationMillisLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -52,13 +53,16 @@
 import android.widget.ScrollView;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Top level container/controller for the BiometricPrompt UI.
@@ -66,54 +70,52 @@
 public class AuthContainerView extends LinearLayout
         implements AuthDialog, WakefulnessLifecycle.Observer {
 
-    private static final String TAG = "BiometricPrompt/AuthContainerView";
-    private static final int ANIMATION_DURATION_SHOW_MS = 250;
-    private static final int ANIMATION_DURATION_AWAY_MS = 350; // ms
+    private static final String TAG = "AuthContainerView";
 
-    static final int STATE_UNKNOWN = 0;
-    static final int STATE_ANIMATING_IN = 1;
-    static final int STATE_PENDING_DISMISS = 2;
-    static final int STATE_SHOWING = 3;
-    static final int STATE_ANIMATING_OUT = 4;
-    static final int STATE_GONE = 5;
+    private static final int ANIMATION_DURATION_SHOW_MS = 250;
+    private static final int ANIMATION_DURATION_AWAY_MS = 350;
+
+    private static final int STATE_UNKNOWN = 0;
+    private static final int STATE_ANIMATING_IN = 1;
+    private static final int STATE_PENDING_DISMISS = 2;
+    private static final int STATE_SHOWING = 3;
+    private static final int STATE_ANIMATING_OUT = 4;
+    private static final int STATE_GONE = 5;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({STATE_UNKNOWN, STATE_ANIMATING_IN, STATE_PENDING_DISMISS, STATE_SHOWING,
             STATE_ANIMATING_OUT, STATE_GONE})
-    @interface ContainerState {}
+    private @interface ContainerState {}
 
-    final Config mConfig;
-    final int mEffectiveUserId;
-    @Nullable private final List<FingerprintSensorPropertiesInternal> mFpProps;
-    @Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
+    private final Config mConfig;
+    private final int mEffectiveUserId;
     private final Handler mHandler;
-    private final Injector mInjector;
     private final IBinder mWindowToken = new Binder();
     private final WindowManager mWindowManager;
-    private final AuthPanelController mPanelController;
     private final Interpolator mLinearOutSlowIn;
-    @VisibleForTesting final BiometricCallback mBiometricCallback;
     private final CredentialCallback mCredentialCallback;
-
-    @VisibleForTesting final FrameLayout mFrameLayout;
-    @VisibleForTesting @Nullable AuthBiometricView mBiometricView;
-    @VisibleForTesting @Nullable AuthCredentialView mCredentialView;
-
-    @VisibleForTesting final ImageView mBackgroundView;
-    @VisibleForTesting final ScrollView mBiometricScrollView;
-    private final View mPanelView;
-
-    private final float mTranslationY;
-
+    private final LockPatternUtils mLockPatternUtils;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
 
-    @VisibleForTesting @ContainerState int mContainerState = STATE_UNKNOWN;
+    @VisibleForTesting final BiometricCallback mBiometricCallback;
+
+    @Nullable private AuthBiometricView mBiometricView;
+    @Nullable private AuthCredentialView mCredentialView;
+    private final AuthPanelController mPanelController;
+    private final FrameLayout mFrameLayout;
+    private final ImageView mBackgroundView;
+    private final ScrollView mBiometricScrollView;
+    private final View mPanelView;
+    private final float mTranslationY;
+    @ContainerState private int mContainerState = STATE_UNKNOWN;
+    private final Set<Integer> mFailedModalities = new HashSet<Integer>();
 
     // Non-null only if the dialog is in the act of dismissing and has not sent the reason yet.
-    @Nullable @AuthDialogCallback.DismissedReason Integer mPendingCallbackReason;
+    @Nullable @AuthDialogCallback.DismissedReason private Integer mPendingCallbackReason;
     // HAT received from LockSettingsService when credential is verified.
-    @Nullable byte[] mCredentialAttestation;
+    @Nullable private byte[] mCredentialAttestation;
 
+    @VisibleForTesting
     static class Config {
         Context mContext;
         AuthDialogCallback mCallback;
@@ -122,11 +124,11 @@
         int mUserId;
         String mOpPackageName;
         int[] mSensorIds;
-        boolean mCredentialAllowed;
         boolean mSkipIntro;
         long mOperationId;
         long mRequestId;
-        @BiometricMultiSensorMode int mMultiSensorConfig;
+        boolean mSkipAnimation = false;
+        @BiometricMultiSensorMode int mMultiSensorConfig = BIOMETRIC_MULTI_SENSOR_DEFAULT;
     }
 
     public static class Builder {
@@ -167,7 +169,7 @@
             return this;
         }
 
-        public Builder setOperationId(long operationId) {
+        public Builder setOperationId(@DurationMillisLong long operationId) {
             mConfig.mOperationId = operationId;
             return this;
         }
@@ -178,55 +180,27 @@
             return this;
         }
 
+        @VisibleForTesting
+        public Builder setSkipAnimationDuration(boolean skip) {
+            mConfig.mSkipAnimation = skip;
+            return this;
+        }
+
         /** The multi-sensor mode. */
         public Builder setMultiSensorConfig(@BiometricMultiSensorMode int multiSensorConfig) {
             mConfig.mMultiSensorConfig = multiSensorConfig;
             return this;
         }
 
-        public AuthContainerView build(int[] sensorIds, boolean credentialAllowed,
+        public AuthContainerView build(int[] sensorIds,
                 @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
                 @Nullable List<FaceSensorPropertiesInternal> faceProps,
-                WakefulnessLifecycle wakefulnessLifecycle) {
+                @NonNull WakefulnessLifecycle wakefulnessLifecycle,
+                @NonNull UserManager userManager,
+                @NonNull LockPatternUtils lockPatternUtils) {
             mConfig.mSensorIds = sensorIds;
-            mConfig.mCredentialAllowed = credentialAllowed;
-            return new AuthContainerView(
-                    mConfig, new Injector(), fpProps, faceProps, wakefulnessLifecycle);
-        }
-    }
-
-    public static class Injector {
-        ScrollView getBiometricScrollView(FrameLayout parent) {
-            return parent.findViewById(R.id.biometric_scrollview);
-        }
-
-        FrameLayout inflateContainerView(LayoutInflater factory, ViewGroup root) {
-            return (FrameLayout) factory.inflate(
-                    R.layout.auth_container_view, root, false /* attachToRoot */);
-        }
-
-        AuthPanelController getPanelController(Context context, View panelView) {
-            return new AuthPanelController(context, panelView);
-        }
-
-        ImageView getBackgroundView(FrameLayout parent) {
-            return parent.findViewById(R.id.background);
-        }
-
-        View getPanelView(FrameLayout parent) {
-            return parent.findViewById(R.id.panel);
-        }
-
-        int getAnimateCredentialStartDelayMs() {
-            return AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS;
-        }
-
-        UserManager getUserManager(Context context) {
-            return UserManager.get(context);
-        }
-
-        int getCredentialType(Context context, int effectiveUserId) {
-            return Utils.getCredentialType(context, effectiveUserId);
+            return new AuthContainerView(mConfig, fpProps, faceProps, wakefulnessLifecycle,
+                    userManager, lockPatternUtils, new Handler(Looper.getMainLooper()));
         }
     }
 
@@ -246,6 +220,7 @@
                     animateAway(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE);
                     break;
                 case AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN:
+                    mFailedModalities.clear();
                     mConfig.mCallback.onTryAgainPressed();
                     break;
                 case AuthBiometricView.Callback.ACTION_ERROR:
@@ -255,10 +230,7 @@
                     mConfig.mCallback.onDeviceCredentialPressed();
                     mHandler.postDelayed(() -> {
                         addCredentialView(false /* animatePanel */, true /* animateContents */);
-                    }, mInjector.getAnimateCredentialStartDelayMs());
-                    break;
-                case AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR:
-                    mConfig.mCallback.onStartFingerprintNow();
+                    }, mConfig.mSkipAnimation ? 0 : AuthDialog.ANIMATE_CREDENTIAL_START_DELAY_MS);
                     break;
                 default:
                     Log.e(TAG, "Unhandled action: " + action);
@@ -275,21 +247,19 @@
     }
 
     @VisibleForTesting
-    AuthContainerView(Config config, Injector injector,
+    AuthContainerView(Config config,
             @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
             @Nullable List<FaceSensorPropertiesInternal> faceProps,
-            WakefulnessLifecycle wakefulnessLifecycle) {
+            @NonNull WakefulnessLifecycle wakefulnessLifecycle,
+            @NonNull UserManager userManager,
+            @NonNull LockPatternUtils lockPatternUtils,
+            @NonNull Handler mainHandler) {
         super(config.mContext);
 
         mConfig = config;
-        mInjector = injector;
-        mFpProps = fpProps;
-        mFaceProps = faceProps;
-
-        mEffectiveUserId = mInjector.getUserManager(mContext)
-                .getCredentialOwnerProfile(mConfig.mUserId);
-
-        mHandler = new Handler(Looper.getMainLooper());
+        mLockPatternUtils = lockPatternUtils;
+        mEffectiveUserId = userManager.getCredentialOwnerProfile(mConfig.mUserId);
+        mHandler = mainHandler;
         mWindowManager = mContext.getSystemService(WindowManager.class);
         mWakefulnessLifecycle = wakefulnessLifecycle;
 
@@ -299,100 +269,42 @@
         mBiometricCallback = new BiometricCallback();
         mCredentialCallback = new CredentialCallback();
 
-        final LayoutInflater factory = LayoutInflater.from(mContext);
-        mFrameLayout = mInjector.inflateContainerView(factory, this);
-
-        mPanelView = mInjector.getPanelView(mFrameLayout);
-        mPanelController = mInjector.getPanelController(mContext, mPanelView);
+        final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+        mFrameLayout = (FrameLayout) layoutInflater.inflate(
+                R.layout.auth_container_view, this, false /* attachToRoot */);
+        addView(mFrameLayout);
+        mBiometricScrollView = mFrameLayout.findViewById(R.id.biometric_scrollview);
+        mBackgroundView = mFrameLayout.findViewById(R.id.background);
+        mPanelView = mFrameLayout.findViewById(R.id.panel);
+        mPanelController = new AuthPanelController(mContext, mPanelView);
 
         // Inflate biometric view only if necessary.
-        final int sensorCount = config.mSensorIds.length;
         if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) {
-            if (sensorCount == 1) {
-                final int singleSensorAuthId = config.mSensorIds[0];
-                if (Utils.containsSensorId(mFpProps, singleSensorAuthId)) {
-                    FingerprintSensorPropertiesInternal sensorProps = null;
-                    for (FingerprintSensorPropertiesInternal prop : mFpProps) {
-                        if (prop.sensorId == singleSensorAuthId) {
-                            sensorProps = prop;
-                            break;
-                        }
-                    }
+            final FingerprintSensorPropertiesInternal fpProperties =
+                    Utils.findFirstSensorProperties(fpProps, mConfig.mSensorIds);
+            final FaceSensorPropertiesInternal faceProperties =
+                    Utils.findFirstSensorProperties(faceProps, mConfig.mSensorIds);
 
-                    if (sensorProps.isAnyUdfpsType()) {
-                        AuthBiometricUdfpsView udfpsView = (AuthBiometricUdfpsView) factory
-                                .inflate(R.layout.auth_biometric_udfps_view, null, false);
-                        udfpsView.setSensorProps(sensorProps);
-                        mBiometricView = udfpsView;
-                    } else {
-                        mBiometricView = (AuthBiometricFingerprintView) factory
-                                .inflate(R.layout.auth_biometric_fingerprint_view, null, false);
-                    }
-                } else if (Utils.containsSensorId(mFaceProps, singleSensorAuthId)) {
-                    mBiometricView = (AuthBiometricFaceView)
-                            factory.inflate(R.layout.auth_biometric_face_view, null, false);
-                } else {
-                    // Unknown sensorId
-                    Log.e(TAG, "Unknown sensorId: " + singleSensorAuthId);
-                    mBiometricView = null;
-                    mBackgroundView = null;
-                    mBiometricScrollView = null;
-                    return;
-                }
-            } else if (sensorCount == 2) {
-                final int[] allSensors = findFaceAndFingerprintSensors();
-                final int faceSensorId = allSensors[0];
-                final int fingerprintSensorId = allSensors[1];
-
-                if (fingerprintSensorId == -1 || faceSensorId == -1) {
-                    Log.e(TAG, "Missing fingerprint or face for dual-sensor config");
-                    mBiometricView = null;
-                    mBackgroundView = null;
-                    mBiometricScrollView = null;
-                    return;
-                }
-
-                FingerprintSensorPropertiesInternal fingerprintSensorProps = null;
-                for (FingerprintSensorPropertiesInternal prop : mFpProps) {
-                    if (prop.sensorId == fingerprintSensorId) {
-                        fingerprintSensorProps = prop;
-                        break;
-                    }
-                }
-
-                if (fingerprintSensorProps != null) {
-                    final AuthBiometricFaceToFingerprintView faceToFingerprintView =
-                            (AuthBiometricFaceToFingerprintView) factory.inflate(
-                                    R.layout.auth_biometric_face_to_fingerprint_view, null, false);
-                    faceToFingerprintView.setFingerprintSensorProps(fingerprintSensorProps);
-                    faceToFingerprintView.setModalityListener(new ModalityListener() {
-                        @Override
-                        public void onModalitySwitched(int oldModality, int newModality) {
-                            maybeUpdatePositionForUdfps(true /* invalidate */);
-                        }
-                    });
-                    mBiometricView = faceToFingerprintView;
-                } else {
-                    Log.e(TAG, "Fingerprint props not found for sensor ID: " + fingerprintSensorId);
-                    mBiometricView = null;
-                    mBackgroundView = null;
-                    mBiometricScrollView = null;
-                    return;
-                }
+            if (fpProperties != null && faceProperties != null) {
+                final AuthBiometricFingerprintAndFaceView fingerprintAndFaceView =
+                        (AuthBiometricFingerprintAndFaceView) layoutInflater.inflate(
+                                R.layout.auth_biometric_fingerprint_and_face_view, null, false);
+                fingerprintAndFaceView.setSensorProperties(fpProperties);
+                mBiometricView = fingerprintAndFaceView;
+            } else if (fpProperties != null) {
+                final AuthBiometricFingerprintView fpView =
+                        (AuthBiometricFingerprintView) layoutInflater.inflate(
+                                R.layout.auth_biometric_fingerprint_view, null, false);
+                fpView.setSensorProperties(fpProperties);
+                mBiometricView = fpView;
+            } else if (faceProperties != null) {
+                mBiometricView = (AuthBiometricFaceView) layoutInflater.inflate(
+                        R.layout.auth_biometric_face_view, null, false);
             } else {
-                Log.e(TAG, "Unsupported sensor array, length: " + sensorCount);
-                mBiometricView = null;
-                mBackgroundView = null;
-                mBiometricScrollView = null;
-                return;
+                Log.e(TAG, "No sensors found!");
             }
         }
 
-        mBiometricScrollView = mInjector.getBiometricScrollView(mFrameLayout);
-        mBackgroundView = mInjector.getBackgroundView(mFrameLayout);
-
-        addView(mFrameLayout);
-
         // init view before showing
         if (mBiometricView != null) {
             mBiometricView.setRequireConfirmation(mConfig.mRequireConfirmation);
@@ -431,10 +343,6 @@
         return Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo);
     }
 
-    private void addBiometricView() {
-        mBiometricScrollView.addView(mBiometricView);
-    }
-
     /**
      * Adds the credential view. When going from biometric to credential view, the biometric
      * view starts the panel expansion animation. If the credential view is being shown first,
@@ -444,8 +352,8 @@
     private void addCredentialView(boolean animatePanel, boolean animateContents) {
         final LayoutInflater factory = LayoutInflater.from(mContext);
 
-        final @Utils.CredentialType int credentialType = mInjector.getCredentialType(
-                mContext, mEffectiveUserId);
+        @Utils.CredentialType final int credentialType = Utils.getCredentialType(
+                mLockPatternUtils, mEffectiveUserId);
 
         switch (credentialType) {
             case Utils.CREDENTIAL_PATTERN:
@@ -493,15 +401,11 @@
     @Override
     public void onAttachedToWindow() {
         super.onAttachedToWindow();
-        onAttachedToWindowInternal();
-    }
 
-    @VisibleForTesting
-    void onAttachedToWindowInternal() {
         mWakefulnessLifecycle.addObserver(this);
 
         if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) {
-            addBiometricView();
+            mBiometricScrollView.addView(mBiometricView);
         } else if (Utils.isDeviceCredentialAllowed(mConfig.mPromptInfo)) {
             addCredentialView(true /* animatePanel */, false /* animateContents */);
         } else {
@@ -521,17 +425,18 @@
             mBiometricScrollView.setY(mTranslationY);
 
             setAlpha(0f);
+            final long animateDuration = mConfig.mSkipAnimation ? 0 : ANIMATION_DURATION_SHOW_MS;
             postOnAnimation(() -> {
                 mPanelView.animate()
                         .translationY(0)
-                        .setDuration(ANIMATION_DURATION_SHOW_MS)
+                        .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
                         .withLayer()
                         .withEndAction(this::onDialogAnimatedIn)
                         .start();
                 mBiometricScrollView.animate()
                         .translationY(0)
-                        .setDuration(ANIMATION_DURATION_SHOW_MS)
+                        .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
                         .withLayer()
                         .start();
@@ -539,14 +444,14 @@
                     mCredentialView.setY(mTranslationY);
                     mCredentialView.animate()
                             .translationY(0)
-                            .setDuration(ANIMATION_DURATION_SHOW_MS)
+                            .setDuration(animateDuration)
                             .setInterpolator(mLinearOutSlowIn)
                             .withLayer()
                             .start();
                 }
                 animate()
                         .alpha(1f)
-                        .setDuration(ANIMATION_DURATION_SHOW_MS)
+                        .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
                         .withLayer()
                         .start();
@@ -555,15 +460,8 @@
     }
 
     private static boolean shouldUpdatePositionForUdfps(@NonNull View view) {
-        if (view instanceof AuthBiometricUdfpsView) {
-            return true;
-        }
-
-        if (view instanceof AuthBiometricFaceToFingerprintView) {
-            AuthBiometricFaceToFingerprintView faceToFingerprintView =
-                    (AuthBiometricFaceToFingerprintView) view;
-            return faceToFingerprintView.getActiveSensorType() == TYPE_FINGERPRINT
-                    && faceToFingerprintView.isFingerprintUdfps();
+        if (view instanceof AuthBiometricFingerprintView) {
+            return ((AuthBiometricFingerprintView) view).isUdfps();
         }
 
         return false;
@@ -652,12 +550,13 @@
     }
 
     @Override
-    public void onAuthenticationSucceeded() {
-        mBiometricView.onAuthenticationSucceeded();
+    public void onAuthenticationSucceeded(@Modality int modality) {
+        mBiometricView.onAuthenticationSucceeded(modality);
     }
 
     @Override
     public void onAuthenticationFailed(@Modality int modality, String failureReason) {
+        mFailedModalities.add(modality);
         mBiometricView.onAuthenticationFailed(modality, failureReason);
     }
 
@@ -672,8 +571,17 @@
     }
 
     @Override
+    public void onPointerDown() {
+        if (mBiometricView.onPointerDown(mFailedModalities)) {
+            Log.d(TAG, "retrying failed modalities (pointer down)");
+            mBiometricCallback.onAction(AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN);
+        }
+    }
+
+    @Override
     public void onSaveState(@NonNull Bundle outState) {
-        outState.putInt(AuthDialog.KEY_CONTAINER_STATE, mContainerState);
+        outState.putBoolean(AuthDialog.KEY_CONTAINER_GOING_AWAY,
+                mContainerState == STATE_ANIMATING_OUT);
         // In the case where biometric and credential are both allowed, we can assume that
         // biometric isn't showing if credential is showing since biometric is shown first.
         outState.putBoolean(AuthDialog.KEY_BIOMETRIC_SHOWING,
@@ -695,8 +603,7 @@
         mBiometricView.startTransitionToCredentialUI();
     }
 
-    @VisibleForTesting
-    void animateAway(int reason) {
+    void animateAway(@AuthDialogCallback.DismissedReason int reason) {
         animateAway(true /* sendReason */, reason);
     }
 
@@ -724,31 +631,32 @@
             removeWindowIfAttached();
         };
 
+        final long animateDuration = mConfig.mSkipAnimation ? 0 : ANIMATION_DURATION_AWAY_MS;
         postOnAnimation(() -> {
             mPanelView.animate()
                     .translationY(mTranslationY)
-                    .setDuration(ANIMATION_DURATION_AWAY_MS)
+                    .setDuration(animateDuration)
                     .setInterpolator(mLinearOutSlowIn)
                     .withLayer()
                     .withEndAction(endActionRunnable)
                     .start();
             mBiometricScrollView.animate()
                     .translationY(mTranslationY)
-                    .setDuration(ANIMATION_DURATION_AWAY_MS)
+                    .setDuration(animateDuration)
                     .setInterpolator(mLinearOutSlowIn)
                     .withLayer()
                     .start();
             if (mCredentialView != null && mCredentialView.isAttachedToWindow()) {
                 mCredentialView.animate()
                         .translationY(mTranslationY)
-                        .setDuration(ANIMATION_DURATION_AWAY_MS)
+                        .setDuration(animateDuration)
                         .setInterpolator(mLinearOutSlowIn)
                         .withLayer()
                         .start();
             }
             animate()
                     .alpha(0f)
-                    .setDuration(ANIMATION_DURATION_AWAY_MS)
+                    .setDuration(animateDuration)
                     .setInterpolator(mLinearOutSlowIn)
                     .withLayer()
                     .start();
@@ -773,8 +681,7 @@
         mWindowManager.removeView(this);
     }
 
-    @VisibleForTesting
-    void onDialogAnimatedIn() {
+    private void onDialogAnimatedIn() {
         if (mContainerState == STATE_PENDING_DISMISS) {
             Log.d(TAG, "onDialogAnimatedIn(): mPendingDismissDialog=true, dismissing now");
             animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
@@ -788,8 +695,7 @@
     }
 
     @VisibleForTesting
-    static WindowManager.LayoutParams getLayoutParams(IBinder windowToken,
-            CharSequence title) {
+    static WindowManager.LayoutParams getLayoutParams(IBinder windowToken, CharSequence title) {
         final int windowFlags = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
                 | WindowManager.LayoutParams.FLAG_SECURE;
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -805,24 +711,4 @@
         lp.token = windowToken;
         return lp;
     }
-
-    // returns [face, fingerprint] sensor ids (id is -1 if not present)
-    private int[] findFaceAndFingerprintSensors() {
-        int faceSensorId = -1;
-        int fingerprintSensorId = -1;
-
-        for (final int sensorId : mConfig.mSensorIds) {
-            if (Utils.containsSensorId(mFpProps, sensorId)) {
-                fingerprintSensorId = sensorId;
-            } else if (Utils.containsSensorId(mFaceProps, sensorId)) {
-                faceSensorId = sensorId;
-            }
-
-            if (fingerprintSensorId != -1 && faceSensorId != -1) {
-                break;
-            }
-        }
-
-        return new int[] {faceSensorId, fingerprintSensorId};
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index dfb8c18..64c2d2e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -51,6 +51,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.os.UserManager;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.view.MotionEvent;
@@ -59,6 +60,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.assist.ui.DisplayUtils;
 import com.android.systemui.dagger.SysUISingleton;
@@ -123,8 +125,6 @@
     @Nullable private SidefpsController mSidefpsController;
     @Nullable private IBiometricContextListener mBiometricContextListener;
     @VisibleForTesting
-    TaskStackListener mTaskStackListener;
-    @VisibleForTesting
     IBiometricSysuiReceiver mReceiver;
     @VisibleForTesting
     @NonNull final BiometricDisplayListener mOrientationListener;
@@ -137,13 +137,16 @@
     @NonNull private final SensorPrivacyManager mSensorPrivacyManager;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
     private boolean mAllAuthenticatorsRegistered;
+    @NonNull private final UserManager mUserManager;
+    @NonNull private final LockPatternUtils mLockPatternUtils;
 
-    private class BiometricTaskStackListener extends TaskStackListener {
+    @VisibleForTesting
+    final TaskStackListener mTaskStackListener = new TaskStackListener() {
         @Override
         public void onTaskStackChanged() {
             mHandler.post(AuthController.this::handleTaskStackChanged);
         }
-    }
+    };
 
     private final IFingerprintAuthenticatorsRegisteredCallback
             mFingerprintAuthenticatorsRegisteredCallback =
@@ -256,6 +259,17 @@
         mUdfpsProps = !udfpsProps.isEmpty() ? udfpsProps : null;
         if (mUdfpsProps != null) {
             mUdfpsController = mUdfpsControllerFactory.get();
+            mUdfpsController.addCallback(new UdfpsController.Callback() {
+                @Override
+                public void onFingerUp() {}
+
+                @Override
+                public void onFingerDown() {
+                    if (mCurrentDialog != null) {
+                        mCurrentDialog.onPointerDown();
+                    }
+                }
+            });
         }
         mSidefpsProps = !sidefpsProps.isEmpty() ? sidefpsProps : null;
         if (mSidefpsProps != null) {
@@ -360,20 +374,6 @@
     }
 
     @Override
-    public void onStartFingerprintNow() {
-        if (mReceiver == null) {
-            Log.e(TAG, "onStartUdfpsNow: Receiver is null");
-            return;
-        }
-
-        try {
-            mReceiver.onStartFingerprintNow();
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException when sending onDialogAnimatedIn", e);
-        }
-    }
-
-    @Override
     public void onDismissed(@DismissedReason int reason, @Nullable byte[] credentialAttestation) {
         switch (reason) {
             case AuthDialogCallback.DISMISSED_USER_CANCELED:
@@ -503,12 +503,16 @@
             Provider<UdfpsController> udfpsControllerFactory,
             Provider<SidefpsController> sidefpsControllerFactory,
             @NonNull DisplayManager displayManager,
-            WakefulnessLifecycle wakefulnessLifecycle,
+            @NonNull WakefulnessLifecycle wakefulnessLifecycle,
+            @NonNull UserManager userManager,
+            @NonNull LockPatternUtils lockPatternUtils,
             @NonNull StatusBarStateController statusBarStateController,
             @Main Handler handler) {
         super(context);
         mExecution = execution;
         mWakefulnessLifecycle = wakefulnessLifecycle;
+        mUserManager = userManager;
+        mLockPatternUtils = lockPatternUtils;
         mHandler = handler;
         mCommandQueue = commandQueue;
         mActivityTaskManager = activityTaskManager;
@@ -583,7 +587,6 @@
                     mFingerprintAuthenticatorsRegisteredCallback);
         }
 
-        mTaskStackListener = new BiometricTaskStackListener();
         mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
     }
 
@@ -668,11 +671,11 @@
      * example, KeyguardUpdateMonitor has its own {@link FingerprintManager.AuthenticationCallback}.
      */
     @Override
-    public void onBiometricAuthenticated() {
+    public void onBiometricAuthenticated(@Modality int modality) {
         if (DEBUG) Log.d(TAG, "onBiometricAuthenticated: ");
 
         if (mCurrentDialog != null) {
-            mCurrentDialog.onAuthenticationSucceeded();
+            mCurrentDialog.onAuthenticationSucceeded(modality);
         } else {
             Log.w(TAG, "onBiometricAuthenticated callback but dialog gone");
         }
@@ -827,7 +830,7 @@
         final String opPackageName = (String) args.arg6;
         final long operationId = args.argl1;
         final long requestId = args.argl2;
-        final @BiometricMultiSensorMode int multiSensorConfig = args.argi2;
+        @BiometricMultiSensorMode final int multiSensorConfig = args.argi2;
 
         // Create a new dialog but do not replace the current one yet.
         final AuthDialog newDialog = buildDialog(
@@ -835,13 +838,14 @@
                 requireConfirmation,
                 userId,
                 sensorIds,
-                credentialAllowed,
                 opPackageName,
                 skipAnimation,
                 operationId,
                 requestId,
                 multiSensorConfig,
-                mWakefulnessLifecycle);
+                mWakefulnessLifecycle,
+                mUserManager,
+                mLockPatternUtils);
 
         if (newDialog == null) {
             Log.e(TAG, "Unsupported type configuration");
@@ -902,8 +906,7 @@
 
             // Only show the dialog if necessary. If it was animating out, the dialog is supposed
             // to send its pending callback immediately.
-            if (savedState.getInt(AuthDialog.KEY_CONTAINER_STATE)
-                    != AuthContainerView.STATE_ANIMATING_OUT) {
+            if (!savedState.getBoolean(AuthDialog.KEY_CONTAINER_GOING_AWAY, false)) {
                 final boolean credentialShowing =
                         savedState.getBoolean(AuthDialog.KEY_CREDENTIAL_SHOWING);
                 if (credentialShowing) {
@@ -927,10 +930,12 @@
     }
 
     protected AuthDialog buildDialog(PromptInfo promptInfo, boolean requireConfirmation,
-            int userId, int[] sensorIds, boolean credentialAllowed, String opPackageName,
+            int userId, int[] sensorIds, String opPackageName,
             boolean skipIntro, long operationId, long requestId,
             @BiometricMultiSensorMode int multiSensorConfig,
-            WakefulnessLifecycle wakefulnessLifecycle) {
+            @NonNull WakefulnessLifecycle wakefulnessLifecycle,
+            @NonNull UserManager userManager,
+            @NonNull LockPatternUtils lockPatternUtils) {
         return new AuthContainerView.Builder(mContext)
                 .setCallback(this)
                 .setPromptInfo(promptInfo)
@@ -941,7 +946,8 @@
                 .setOperationId(operationId)
                 .setRequestId(requestId)
                 .setMultiSensorConfig(multiSensorConfig)
-                .build(sensorIds, credentialAllowed, mFpProps, mFaceProps, wakefulnessLifecycle);
+                .build(sensorIds, mFpProps, mFaceProps, wakefulnessLifecycle, userManager,
+                        lockPatternUtils);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index fa5213e..59ed156 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -31,7 +31,7 @@
  */
 public interface AuthDialog {
 
-    String KEY_CONTAINER_STATE = "container_state";
+    String KEY_CONTAINER_GOING_AWAY = "container_going_away";
     String KEY_BIOMETRIC_SHOWING = "biometric_showing";
     String KEY_CREDENTIAL_SHOWING = "credential_showing";
 
@@ -64,7 +64,7 @@
     @interface DialogSize {}
 
     /**
-     * Parameters used when laying out {@link AuthBiometricView}, its sublclasses, and
+     * Parameters used when laying out {@link AuthBiometricView}, its subclasses, and
      * {@link AuthPanelController}.
      */
     class LayoutParams {
@@ -113,7 +113,7 @@
     /**
      * Biometric authenticated. May be pending user confirmation, or completed.
      */
-    void onAuthenticationSucceeded();
+    void onAuthenticationSucceeded(@Modality int modality);
 
     /**
      * Authentication failed (reject, timeout). Dialog stays showing.
@@ -136,6 +136,9 @@
      */
     void onError(@Modality int modality, String error);
 
+    /** UDFPS pointer down event. */
+    void onPointerDown();
+
     /**
      * Save the current state.
      * @param outState
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
index 9f40ca7..a7d2901 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialogCallback.java
@@ -70,9 +70,4 @@
      * Notifies when the dialog has finished animating.
      */
     void onDialogAnimatedIn();
-
-    /**
-     * Notifies that the fingerprint sensor should be started now.
-     */
-    void onStartFingerprintNow();
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index f82ea79..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,9 +40,9 @@
 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.CentralSurfaces
 import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.phone.StatusBar
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.ViewController
@@ -54,9 +55,9 @@
  * Controls the ripple effect that shows when authentication is successful.
  * The ripple uses the accent color of the current theme.
  */
-@StatusBarScope
+@CentralSurfacesScope
 class AuthRippleController @Inject constructor(
-    private val statusBar: StatusBar,
+    private val centralSurfaces: CentralSurfaces,
     private val sysuiContext: Context,
     private val authController: AuthController,
     private val configurationController: ConfigurationController,
@@ -137,7 +138,7 @@
 
     private fun showUnlockedRipple() {
         notificationShadeWindowController.setForcePluginOpen(true, this)
-        val lightRevealScrim = statusBar.lightRevealScrim
+        val lightRevealScrim = centralSurfaces.lightRevealScrim
         if (statusBarStateController.isDozing || biometricUnlockController.isWakeAndUnlock) {
             circleReveal?.let {
                 lightRevealScrim?.revealEffect = it
@@ -155,7 +156,7 @@
 
     override fun onKeyguardFadingAwayChanged() {
         if (keyguardStateController.isKeyguardFadingAway) {
-            val lightRevealScrim = statusBar.lightRevealScrim
+            val lightRevealScrim = centralSurfaces.lightRevealScrim
             if (startLightRevealScrimOnKeyguardFadingAway && lightRevealScrim != null) {
                 ValueAnimator.ofFloat(.1f, 1f).apply {
                     interpolator = Interpolators.LINEAR_OUT_SLOW_IN
@@ -170,7 +171,7 @@
                     }
                     addListener(object : AnimatorListenerAdapter() {
                         override fun onAnimationEnd(animation: Animator?) {
-                            // Reset light reveal scrim to the default, so the StatusBar
+                            // Reset light reveal scrim to the default, so the CentralSurfaces
                             // can handle any subsequent light reveal changes
                             // (ie: from dozing changes)
                             if (lightRevealScrim.revealEffect == circleReveal) {
@@ -199,8 +200,8 @@
                 it.y,
                 0f,
                 Math.max(
-                    Math.max(it.x, statusBar.displayWidth - it.x),
-                    Math.max(it.y, statusBar.displayHeight - it.y)
+                    Math.max(it.x, centralSurfaces.displayWidth - it.x),
+                    Math.max(it.y, centralSurfaces.displayHeight - it.y)
                 )
             )
         }
@@ -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/UdfpsAnimationView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
index 7fdb5ea..9281eb8 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationView.java
@@ -34,8 +34,10 @@
  * - optionally can override dozeTimeTick to adjust views for burn-in mitigation
  */
 public abstract class UdfpsAnimationView extends FrameLayout {
-    // mAlpha takes into consideration the status bar expansion amount to fade out icon when
-    // the status bar is expanded
+    private float mDialogSuggestedAlpha = 1f;
+    private float mNotificationShadeExpansion = 0f;
+
+    // mAlpha takes into consideration the status bar expansion amount and dialog suggested alpha
     private int mAlpha;
     boolean mPauseAuth;
 
@@ -92,6 +94,10 @@
     }
 
     int calculateAlpha() {
+        int alpha = expansionToAlpha(mNotificationShadeExpansion);
+        alpha *= mDialogSuggestedAlpha;
+        mAlpha = alpha;
+
         return mPauseAuth ? mAlpha : 255;
     }
 
@@ -111,8 +117,26 @@
         return (int) ((1 - percent) * 255);
     }
 
+    /**
+     * Set the suggested alpha based on whether a dialog was recently shown or hidden.
+     * @param dialogSuggestedAlpha value from 0f to 1f.
+     */
+    public void setDialogSuggestedAlpha(float dialogSuggestedAlpha) {
+        mDialogSuggestedAlpha = dialogSuggestedAlpha;
+        updateAlpha();
+    }
+
+    public float getDialogSuggestedAlpha() {
+        return mDialogSuggestedAlpha;
+    }
+
+    /**
+     * Sets the amount the notification shade is expanded. This will influence the opacity of the
+     * this visual affordance.
+     * @param expansion amount the shade has expanded from 0f to 1f.
+     */
     public void onExpansionChanged(float expansion) {
-        mAlpha = expansionToAlpha(expansion);
+        mNotificationShadeExpansion = expansion;
         updateAlpha();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
index c33cd8d..27b0592 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
@@ -15,10 +15,12 @@
  */
 package com.android.systemui.biometrics
 
+import android.animation.ValueAnimator
 import android.graphics.PointF
 import android.graphics.RectF
 import com.android.systemui.Dumpable
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.animation.Interpolators
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.phone.SystemUIDialogManager
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener
@@ -50,7 +52,8 @@
     private val view: T
         get() = mView!!
 
-    private val dialogListener = SystemUIDialogManager.Listener { updatePauseAuth() }
+    private var dialogAlphaAnimator: ValueAnimator? = null
+    private val dialogListener = SystemUIDialogManager.Listener { runDialogAlphaAnimator() }
 
     private val panelExpansionListener =
         PanelExpansionListener { fraction, expanded, tracking ->
@@ -83,6 +86,29 @@
      */
     open val paddingY: Int = 0
 
+    open fun updateAlpha() {
+        view.updateAlpha()
+    }
+
+    fun runDialogAlphaAnimator() {
+        val hideAffordance = dialogManager.shouldHideAffordance()
+        dialogAlphaAnimator?.cancel()
+        dialogAlphaAnimator = ValueAnimator.ofFloat(
+                view.calculateAlpha() / 255f,
+                if (hideAffordance) 0f else 1f)
+                .apply {
+            duration = if (hideAffordance) 83L else 200L
+            interpolator = if (hideAffordance) Interpolators.LINEAR else Interpolators.ALPHA_IN
+
+            addUpdateListener { animatedValue ->
+                view.setDialogSuggestedAlpha(animatedValue.animatedValue as Float)
+                updateAlpha()
+                updatePauseAuth()
+            }
+            start()
+        }
+    }
+
     override fun onViewAttached() {
         panelExpansionStateManager.addExpansionListener(panelExpansionListener)
         dialogManager.registerListener(dialogListener)
@@ -106,6 +132,7 @@
         pw.println("mNotificationShadeVisible=$notificationShadeVisible")
         pw.println("shouldPauseAuth()=" + shouldPauseAuth())
         pw.println("isPauseAuth=" + view.isPauseAuth)
+        pw.println("dialogSuggestedAlpha=" + view.dialogSuggestedAlpha)
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt
index 6607915..242601d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt
@@ -23,7 +23,7 @@
  *
  * Currently doesn't draw anything.
  *
- * Note that [AuthBiometricUdfpsView] also shows UDFPS animations. At some point we should
+ * Note that [AuthBiometricFingerprintViewController] also shows UDFPS animations. At some point we should
  * de-dupe this if necessary.
  */
 class UdfpsBpView(context: Context, attrs: AttributeSet?) : UdfpsAnimationView(context, attrs) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 8052c20..bf42db5 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.
@@ -799,7 +810,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/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 590963b..086894d 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -300,7 +300,10 @@
         when (context.display!!.rotation) {
             Surface.ROTATION_90 -> {
                 if (!shouldRotate(animation)) {
-                    Log.v(TAG, "skip rotating udfps location ROTATION_90")
+                    Log.v(TAG, "skip rotating udfps location ROTATION_90" +
+                            " animation=$animation" +
+                            " isGoingToSleep=${keyguardUpdateMonitor.isGoingToSleep}" +
+                            " isOccluded=${keyguardStateController.isOccluded}")
                 } else {
                     Log.v(TAG, "rotate udfps location ROTATION_90")
                     x = (location.sensorLocationY - location.sensorRadius - paddingX)
@@ -309,7 +312,10 @@
             }
             Surface.ROTATION_270 -> {
                 if (!shouldRotate(animation)) {
-                    Log.v(TAG, "skip rotating udfps location ROTATION_270")
+                    Log.v(TAG, "skip rotating udfps location ROTATION_270" +
+                            " animation=$animation" +
+                            " isGoingToSleep=${keyguardUpdateMonitor.isGoingToSleep}" +
+                            " isOccluded=${keyguardStateController.isOccluded}")
                 } else {
                     Log.v(TAG, "rotate udfps location ROTATION_270")
                     x = (p.x - location.sensorLocationY - location.sensorRadius - paddingX)
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
index 7204a15..7efdd1a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardView.java
@@ -38,7 +38,6 @@
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
-import com.android.systemui.statusbar.StatusBarState;
 
 import com.airbnb.lottie.LottieAnimationView;
 import com.airbnb.lottie.LottieProperty;
@@ -68,6 +67,7 @@
     private float mBurnInOffsetY;
     private float mBurnInProgress;
     private float mInterpolatedDarkAmount;
+    private boolean mAnimatingBetweenAodAndLockscreen; // As opposed to Unlocked => AOD
     private boolean mFullyInflated;
 
     public UdfpsKeyguardView(Context context, @Nullable AttributeSet attrs) {
@@ -114,23 +114,32 @@
             return;
         }
 
+        final float darkAmountForAnimation = mAnimatingBetweenAodAndLockscreen
+                ? mInterpolatedDarkAmount : 1f /* animating from unlocked to AOD */;
         mBurnInOffsetX = MathUtils.lerp(0f,
             getBurnInOffset(mMaxBurnInOffsetX * 2, true /* xAxis */)
-                - mMaxBurnInOffsetX, mInterpolatedDarkAmount);
+                - mMaxBurnInOffsetX, darkAmountForAnimation);
         mBurnInOffsetY = MathUtils.lerp(0f,
             getBurnInOffset(mMaxBurnInOffsetY * 2, false /* xAxis */)
-                - mMaxBurnInOffsetY, mInterpolatedDarkAmount);
-        mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), mInterpolatedDarkAmount);
+                - mMaxBurnInOffsetY, darkAmountForAnimation);
+        mBurnInProgress = MathUtils.lerp(0f, getBurnInProgressOffset(), darkAmountForAnimation);
+
+        if (mAnimatingBetweenAodAndLockscreen) {
+            mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
+
+            mLockScreenFp.setTranslationX(mBurnInOffsetX);
+            mLockScreenFp.setTranslationY(mBurnInOffsetY);
+            mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
+            mLockScreenFp.setAlpha(1f - mInterpolatedDarkAmount);
+        } else {
+            mBgProtection.setAlpha(0f);
+            mLockScreenFp.setAlpha(0f);
+        }
 
         mAodFp.setTranslationX(mBurnInOffsetX);
         mAodFp.setTranslationY(mBurnInOffsetY);
         mAodFp.setProgress(mBurnInProgress);
-        mAodFp.setAlpha(255 * mInterpolatedDarkAmount);
-
-        mLockScreenFp.setTranslationX(mBurnInOffsetX);
-        mLockScreenFp.setTranslationY(mBurnInOffsetY);
-        mLockScreenFp.setProgress(1f - mInterpolatedDarkAmount);
-        mLockScreenFp.setAlpha((1f - mInterpolatedDarkAmount) * 255);
+        mAodFp.setAlpha(mInterpolatedDarkAmount);
     }
 
     void requestUdfps(boolean request, int color) {
@@ -171,15 +180,14 @@
     protected int updateAlpha() {
         int alpha = super.updateAlpha();
         if (mFullyInflated) {
-            mLockScreenFp.setAlpha(alpha / 255f);
-            if (mInterpolatedDarkAmount != 0f) {
-                mBgProtection.setAlpha(1f - mInterpolatedDarkAmount);
-            } else {
+            if (mInterpolatedDarkAmount == 0f) {
+                mLockScreenFp.setAlpha(alpha / 255f);
                 mBgProtection.setAlpha(alpha / 255f);
+            } else {
+                updateBurnInOffsets();
             }
         }
 
-
         return alpha;
     }
 
@@ -191,8 +199,10 @@
         return mAlpha;
     }
 
-    void onDozeAmountChanged(float linear, float eased) {
+    void onDozeAmountChanged(float linear, float eased, boolean animatingBetweenAodAndLockscreen) {
+        mAnimatingBetweenAodAndLockscreen = animatingBetweenAodAndLockscreen;
         mInterpolatedDarkAmount = eased;
+
         updateAlpha();
         updateBurnInOffsets();
     }
@@ -225,10 +235,6 @@
         mBackgroundInAnimator.start();
     }
 
-    private boolean isShadeLocked() {
-        return mStatusBarState == StatusBarState.SHADE_LOCKED;
-    }
-
     private final AsyncLayoutInflater.OnInflateFinishedListener mLayoutInflaterFinishListener =
             new AsyncLayoutInflater.OnInflateFinishedListener() {
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
index 3ece3cc..b8334a0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsKeyguardViewController.java
@@ -18,18 +18,22 @@
 
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 
+import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.content.res.Configuration;
+import android.util.Log;
 import android.util.MathUtils;
 import android.view.MotionEvent;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.R;
 import com.android.systemui.animation.ActivityLaunchAnimator;
+import com.android.systemui.animation.Interpolators;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.SystemUIDialogManager;
@@ -47,6 +51,7 @@
  * Class that coordinates non-HBM animations during keyguard authentication.
  */
 public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<UdfpsKeyguardView> {
+    public static final String TAG = "UdfpsKeyguardViewCtrl";
     @NonNull private final StatusBarKeyguardViewManager mKeyguardViewManager;
     @NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @NonNull private final LockscreenShadeTransitionController mLockScreenShadeTransitionController;
@@ -57,6 +62,7 @@
     @NonNull private final UnlockedScreenOffAnimationController
             mUnlockedScreenOffAnimationController;
     @NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator;
+    private final ValueAnimator mUnlockedScreenOffDozeAnimator = ValueAnimator.ofFloat(0f, 1f);
 
     private boolean mShowingUdfpsBouncer;
     private boolean mUdfpsRequested;
@@ -105,6 +111,19 @@
         mUdfpsController = udfpsController;
         mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
         mActivityLaunchAnimator = activityLaunchAnimator;
+
+        mUnlockedScreenOffDozeAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+        mUnlockedScreenOffDozeAnimator.setInterpolator(Interpolators.ALPHA_IN);
+        mUnlockedScreenOffDozeAnimator.addUpdateListener(
+                new ValueAnimator.AnimatorUpdateListener() {
+                    @Override
+                    public void onAnimationUpdate(ValueAnimator animation) {
+                        mView.onDozeAmountChanged(
+                                animation.getAnimatedFraction(),
+                                (float) animation.getAnimatedValue(),
+                                /* animatingBetweenAodAndLockScreen */ false);
+                    }
+                });
     }
 
     @Override
@@ -141,7 +160,6 @@
 
         mKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
         mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(this);
-        mUnlockedScreenOffAnimationController.addCallback(mUnlockedScreenOffCallback);
         mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
     }
 
@@ -159,7 +177,6 @@
         if (mLockScreenShadeTransitionController.getUdfpsKeyguardViewController() == this) {
             mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null);
         }
-        mUnlockedScreenOffAnimationController.removeCallback(mUnlockedScreenOffCallback);
         mActivityLaunchAnimator.removeListener(mActivityLaunchAnimatorListener);
     }
 
@@ -177,6 +194,7 @@
         pw.println("mUdfpsRequested=" + mUdfpsRequested);
         pw.println("mView.mUdfpsRequested=" + mView.mUdfpsRequested);
         pw.println("mLaunchTransitionFadingAway=" + mLaunchTransitionFadingAway);
+        pw.println("mLastDozeAmount=" + mLastDozeAmount);
     }
 
     /**
@@ -229,7 +247,7 @@
             return false;
         }
 
-        if (getDialogManager().shouldHideAffordance()) {
+        if (mView.getDialogSuggestedAlpha() == 0f) {
             return true;
         }
 
@@ -237,7 +255,11 @@
             return true;
         }
 
-        if (mStatusBarState != KEYGUARD) {
+        // Only pause auth if we're not on the keyguard AND we're not transitioning to doze
+        // (ie: dozeAmount = 0f). For the UnlockedScreenOffAnimation, the statusBarState is
+        // delayed. However, we still animate in the UDFPS affordance with the 
+        // mUnlockedScreenOffDozeAnimator.
+        if (mStatusBarState != KEYGUARD && mLastDozeAmount == 0f) {
             return true;
         }
 
@@ -246,7 +268,12 @@
         }
 
         if (mInputBouncerHiddenAmount < .5f || mIsBouncerVisible) {
-            return true;
+            if (!getStatusBarStateController().isDozing()) {
+                return true;
+            } else {
+                Log.e(TAG, "Bouncer state claims visible on doze hiddenAmount="
+                        + mInputBouncerHiddenAmount + " bouncerVisible=" + mIsBouncerVisible);
+            }
         }
 
         return false;
@@ -292,7 +319,12 @@
         updateAlpha();
     }
 
-    private void updateAlpha() {
+    /**
+     * Update alpha for the UDFPS lock screen affordance. The AoD UDFPS visual affordance's
+     * alpha is based on the doze amount.
+     */
+    @Override
+    public void updateAlpha() {
         // fade icon on transitions to showing the status bar, but if mUdfpsRequested, then
         // the keyguard is occluded by some application - so instead use the input bouncer
         // hidden amount to determine the fade
@@ -309,6 +341,10 @@
             if (mIsLaunchingActivity && !mUdfpsRequested) {
                 alpha *= (1.0f - mActivityLaunchProgress);
             }
+
+            // Fade out alpha when a dialog is shown
+            // Fade in alpha when a dialog is hidden
+            alpha *= mView.getDialogSuggestedAlpha();
         }
         mView.setUnpausedAlpha(alpha);
     }
@@ -320,7 +356,18 @@
             if (mLastDozeAmount < linear) {
                 showUdfpsBouncer(false);
             }
-            mView.onDozeAmountChanged(linear, eased);
+            mUnlockedScreenOffDozeAnimator.cancel();
+            final boolean animatingFromUnlockedScreenOff =
+                    mUnlockedScreenOffAnimationController.isAnimationPlaying();
+            if (animatingFromUnlockedScreenOff && linear != 0f) {
+                // we manually animate the fade in of the UDFPS icon since the unlocked
+                // screen off animation prevents the doze amounts to be incrementally eased in
+                mUnlockedScreenOffDozeAnimator.start();
+            } else {
+                mView.onDozeAmountChanged(linear, eased,
+                    /* animatingBetweenAodAndLockScreen */ true);
+            }
+
             mLastDozeAmount = linear;
             updatePauseAuth();
         }
@@ -329,6 +376,7 @@
         public void onStateChanged(int statusBarState) {
             mStatusBarState = statusBarState;
             mView.setStatusBarState(statusBarState);
+            updateAlpha();
             updatePauseAuth();
         }
     };
@@ -439,9 +487,6 @@
                 }
             };
 
-    private final UnlockedScreenOffAnimationController.Callback mUnlockedScreenOffCallback =
-            (linear, eased) -> mStateListener.onDozeAmountChanged(linear, eased);
-
     private final ActivityLaunchAnimator.Listener mActivityLaunchAnimatorListener =
             new ActivityLaunchAnimator.Listener() {
                 @Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
deleted file mode 100644
index 6989547..0000000
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
-import static android.hardware.biometrics.BiometricManager.Authenticators;
-import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.biometrics.PromptInfo;
-import android.hardware.biometrics.SensorPropertiesInternal;
-import android.os.UserManager;
-import android.util.DisplayMetrics;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-
-import com.android.internal.widget.LockPatternUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
-public class Utils {
-
-    public static final int CREDENTIAL_PIN = 1;
-    public static final int CREDENTIAL_PATTERN = 2;
-    public static final int CREDENTIAL_PASSWORD = 3;
-
-    /** Base set of layout flags for fingerprint overlay widgets. */
-    public static final int FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS =
-            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD})
-    @interface CredentialType {}
-
-    static float dpToPixels(Context context, float dp) {
-        return dp * ((float) context.getResources().getDisplayMetrics().densityDpi
-                / DisplayMetrics.DENSITY_DEFAULT);
-    }
-
-    static void notifyAccessibilityContentChanged(AccessibilityManager am, ViewGroup view) {
-        if (!am.isEnabled()) {
-            return;
-        }
-        AccessibilityEvent event = AccessibilityEvent.obtain();
-        event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
-        event.setContentChangeTypes(CONTENT_CHANGE_TYPE_SUBTREE);
-        view.sendAccessibilityEventUnchecked(event);
-        view.notifySubtreeAccessibilityStateChanged(view, view, CONTENT_CHANGE_TYPE_SUBTREE);
-    }
-
-    static boolean isDeviceCredentialAllowed(PromptInfo promptInfo) {
-        @Authenticators.Types final int authenticators = promptInfo.getAuthenticators();
-        return (authenticators & Authenticators.DEVICE_CREDENTIAL) != 0;
-    }
-
-    static boolean isBiometricAllowed(PromptInfo promptInfo) {
-        @Authenticators.Types final int authenticators = promptInfo.getAuthenticators();
-        return (authenticators & Authenticators.BIOMETRIC_WEAK) != 0;
-    }
-
-    static @CredentialType int getCredentialType(Context context, int userId) {
-        final LockPatternUtils lpu = new LockPatternUtils(context);
-        switch (lpu.getKeyguardStoredPasswordQuality(userId)) {
-            case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
-                return CREDENTIAL_PATTERN;
-            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
-            case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
-                return CREDENTIAL_PIN;
-            case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
-            case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
-            case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
-            case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
-                return CREDENTIAL_PASSWORD;
-            default:
-                return CREDENTIAL_PASSWORD;
-        }
-    }
-
-    static boolean isManagedProfile(Context context, int userId) {
-        final UserManager userManager = context.getSystemService(UserManager.class);
-        return userManager.isManagedProfile(userId);
-    }
-
-    static boolean containsSensorId(@Nullable List<? extends SensorPropertiesInternal> properties,
-            int sensorId) {
-        if (properties == null) {
-            return false;
-        }
-
-        for (SensorPropertiesInternal prop : properties) {
-            if (prop.sensorId == sensorId) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    static boolean isSystem(@NonNull Context context, @Nullable String clientPackage) {
-        final boolean hasPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
-                == PackageManager.PERMISSION_GRANTED;
-        return hasPermission && "android".equals(clientPackage);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
new file mode 100644
index 0000000..d0d6f4c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.biometrics
+
+import android.Manifest
+import android.annotation.IntDef
+import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC
+import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
+import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
+import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED
+import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
+import android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+import android.content.Context
+import android.content.pm.PackageManager
+import android.hardware.biometrics.BiometricManager.Authenticators
+import android.hardware.biometrics.PromptInfo
+import android.hardware.biometrics.SensorPropertiesInternal
+import android.os.UserManager
+import android.util.DisplayMetrics
+import android.view.ViewGroup
+import android.view.WindowManager
+import android.view.accessibility.AccessibilityEvent
+import android.view.accessibility.AccessibilityManager
+import com.android.internal.widget.LockPatternUtils
+import java.lang.annotation.Retention
+import java.lang.annotation.RetentionPolicy
+
+object Utils {
+    const val CREDENTIAL_PIN = 1
+    const val CREDENTIAL_PATTERN = 2
+    const val CREDENTIAL_PASSWORD = 3
+
+    /** Base set of layout flags for fingerprint overlay widgets.  */
+    const val FINGERPRINT_OVERLAY_LAYOUT_PARAM_FLAGS =
+        (WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+            or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+            or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+            or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
+
+    @JvmStatic
+    fun dpToPixels(context: Context, dp: Float): Float {
+        val density = context.resources.displayMetrics.densityDpi.toFloat()
+        return dp * (density / DisplayMetrics.DENSITY_DEFAULT)
+    }
+
+    @JvmStatic
+    fun notifyAccessibilityContentChanged(am: AccessibilityManager, view: ViewGroup) {
+        if (!am.isEnabled) {
+            return
+        }
+        val event = AccessibilityEvent.obtain()
+        event.eventType = AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+        event.contentChangeTypes =
+            AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE
+        view.sendAccessibilityEventUnchecked(event)
+        view.notifySubtreeAccessibilityStateChanged(
+            view,
+            view,
+            AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE
+        )
+    }
+
+    @JvmStatic
+    fun isDeviceCredentialAllowed(promptInfo: PromptInfo): Boolean =
+        (promptInfo.authenticators and Authenticators.DEVICE_CREDENTIAL) != 0
+
+    @JvmStatic
+    fun isBiometricAllowed(promptInfo: PromptInfo): Boolean =
+        (promptInfo.authenticators and Authenticators.BIOMETRIC_WEAK) != 0
+
+    @JvmStatic
+    @CredentialType
+    fun getCredentialType(utils: LockPatternUtils, userId: Int): Int =
+        when (utils.getKeyguardStoredPasswordQuality(userId)) {
+            PASSWORD_QUALITY_SOMETHING -> CREDENTIAL_PATTERN
+            PASSWORD_QUALITY_NUMERIC,
+            PASSWORD_QUALITY_NUMERIC_COMPLEX -> CREDENTIAL_PIN
+            PASSWORD_QUALITY_ALPHABETIC,
+            PASSWORD_QUALITY_ALPHANUMERIC,
+            PASSWORD_QUALITY_COMPLEX,
+            PASSWORD_QUALITY_MANAGED -> CREDENTIAL_PASSWORD
+            else -> CREDENTIAL_PASSWORD
+        }
+
+    @JvmStatic
+    fun isManagedProfile(context: Context, userId: Int): Boolean =
+        context.getSystemService(UserManager::class.java)?.isManagedProfile(userId) ?: false
+
+    @JvmStatic
+    fun <T : SensorPropertiesInternal> findFirstSensorProperties(
+        properties: List<T>?,
+        sensorIds: IntArray
+    ): T? = properties?.firstOrNull { sensorIds.contains(it.sensorId) }
+
+    @JvmStatic
+    fun isSystem(context: Context, clientPackage: String?): Boolean {
+        val hasPermission =
+            (context.checkCallingOrSelfPermission(Manifest.permission.USE_BIOMETRIC_INTERNAL)
+                == PackageManager.PERMISSION_GRANTED)
+        return hasPermission && "android" == clientPackage
+    }
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD)
+    internal annotation class CredentialType
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java b/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java
deleted file mode 100644
index 28a3808..0000000
--- a/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.chooser;
-
-import android.app.Activity;
-import android.os.Bundle;
-
-/**
- * Activity for selecting which application ought to handle an ACTION_SEND intent.
- */
-public final class ChooserActivity extends Activity {
-
-    private static final String TAG = "ChooserActivity";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        ChooserHelper.onChoose(this);
-        finish();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/chooser/ChooserHelper.java b/packages/SystemUI/src/com/android/systemui/chooser/ChooserHelper.java
deleted file mode 100644
index 6c1da47..0000000
--- a/packages/SystemUI/src/com/android/systemui/chooser/ChooserHelper.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.chooser;
-
-import android.app.Activity;
-import android.app.ActivityTaskManager;
-import android.content.Intent;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.StrictMode;
-
-/**
- * When a target is chosen from the SystemUI Chooser activity, unpack its arguments and
- * startActivityAsCaller to handle the now-chosen intent.
- */
-public class ChooserHelper {
-
-    private static final String TAG = "ChooserHelper";
-
-    static void onChoose(Activity activity) {
-        final Intent thisIntent = activity.getIntent();
-        final Bundle thisExtras = thisIntent.getExtras();
-        final Intent chosenIntent = thisIntent.getParcelableExtra(Intent.EXTRA_INTENT);
-        final Bundle options = thisIntent.getParcelableExtra(ActivityTaskManager.EXTRA_OPTIONS);
-        final IBinder permissionToken =
-                thisExtras.getBinder(ActivityTaskManager.EXTRA_PERMISSION_TOKEN);
-        final boolean ignoreTargetSecurity =
-                thisIntent.getBooleanExtra(ActivityTaskManager.EXTRA_IGNORE_TARGET_SECURITY, false);
-        final int userId = thisIntent.getIntExtra(Intent.EXTRA_USER_ID, -1);
-
-        // We're dispatching intents that might be coming from legacy apps, so
-        // (as in com.android.internal.app.ResolverActivity) exempt ourselves from death.
-        StrictMode.disableDeathOnFileUriExposure();
-        try {
-            activity.startActivityAsCaller(
-                    chosenIntent, options, permissionToken, ignoreTargetSecurity, userId);
-        } finally {
-            StrictMode.enableDeathOnFileUriExposure();
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index a17ddc8..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.setOnDismissCallback(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 8843462..0000000
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DraggableConstraintLayout.java
+++ /dev/null
@@ -1,121 +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.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;
-
-/**
- * ConstraintLayout that is draggable when touched in a specific region
- */
-public class DraggableConstraintLayout extends ConstraintLayout {
-    private final SwipeDismissHandler mSwipeDismissHandler;
-    private final GestureDetector mSwipeDetector;
-    private Runnable mOnDismiss;
-    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 onDismiss() {
-                        if (mOnDismiss != null) {
-                            mOnDismiss.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
-     */
-    public void setOnDismissCallback(Runnable callback) {
-        mOnDismiss = 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/controller/ControlsProviderLifecycleManager.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
index d2ded71..5b38e5b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
@@ -97,7 +97,11 @@
                     }
                     bindTryCount++
                     try {
-                        context.bindServiceAsUser(intent, serviceConnection, BIND_FLAGS, user)
+                        val bound = context
+                            .bindServiceAsUser(intent, serviceConnection, BIND_FLAGS, user)
+                        if (!bound) {
+                            context.unbindService(serviceConnection)
+                        }
                     } catch (e: SecurityException) {
                         Log.e(TAG, "Failed to bind to service", e)
                     }
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 f87fa96..5c1d8c3 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
@@ -23,7 +23,11 @@
 import android.content.Intent
 import android.content.pm.PackageManager
 import android.content.pm.ResolveInfo
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
 import android.os.VibrationEffect
+import android.provider.Settings
 import android.service.controls.Control
 import android.service.controls.actions.BooleanAction
 import android.service.controls.actions.CommandAction
@@ -38,6 +42,7 @@
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.settings.SecureSettings
 import com.android.wm.shell.TaskViewFactory
 import java.util.Optional
 import javax.inject.Inject
@@ -51,19 +56,41 @@
     private val keyguardStateController: KeyguardStateController,
     private val taskViewFactory: Optional<TaskViewFactory>,
     private val controlsMetricsLogger: ControlsMetricsLogger,
-    private val vibrator: VibratorHelper
+    private val vibrator: VibratorHelper,
+    private val secureSettings: SecureSettings,
+    @Main mainHandler: Handler
 ) : ControlActionCoordinator {
     private var dialog: Dialog? = null
     private var pendingAction: Action? = null
     private var actionsInProgress = mutableSetOf<String>()
     private val isLocked: Boolean
         get() = !keyguardStateController.isUnlocked()
+    private var mAllowTrivialControls: Boolean = secureSettings.getInt(
+            Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
     override lateinit var activityContext: Context
 
     companion object {
         private const val RESPONSE_TIMEOUT_IN_MILLIS = 3000L
     }
 
+    init {
+        val lockScreenShowControlsUri =
+            secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS)
+        val controlsContentObserver = object : ContentObserver(mainHandler) {
+            override fun onChange(selfChange: Boolean, uri: Uri?) {
+                super.onChange(selfChange, uri)
+                if (uri == lockScreenShowControlsUri) {
+                    mAllowTrivialControls = secureSettings.getInt(
+                            Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS, 0) != 0
+                }
+            }
+        }
+        secureSettings.registerContentObserver(
+            lockScreenShowControlsUri,
+            false /* notifyForDescendants */, controlsContentObserver
+        )
+    }
+
     override fun closeDialogs() {
         dialog?.dismiss()
         dialog = null
@@ -80,7 +107,7 @@
                 },
                 true /* blockable */
             ),
-            isAuthRequired(cvh)
+            isAuthRequired(cvh, mAllowTrivialControls)
         )
     }
 
@@ -100,7 +127,7 @@
                 },
                 blockable
             ),
-            isAuthRequired(cvh)
+            isAuthRequired(cvh, mAllowTrivialControls)
         )
     }
 
@@ -120,7 +147,7 @@
                 { cvh.action(FloatAction(templateId, newValue)) },
                 false /* blockable */
             ),
-            isAuthRequired(cvh)
+            isAuthRequired(cvh, mAllowTrivialControls)
         )
     }
 
@@ -139,7 +166,7 @@
                 },
                 false /* blockable */
             ),
-            isAuthRequired(cvh)
+            isAuthRequired(cvh, mAllowTrivialControls)
         )
     }
 
@@ -156,7 +183,11 @@
         actionsInProgress.remove(controlId)
     }
 
-    private fun isAuthRequired(cvh: ControlViewHolder) = cvh.cws.control?.isAuthRequired() ?: true
+    @VisibleForTesting()
+    fun isAuthRequired(cvh: ControlViewHolder, allowTrivialControls: Boolean): Boolean {
+        val isAuthRequired = cvh.cws.control?.isAuthRequired ?: true
+        return isAuthRequired || !allowTrivialControls
+    }
 
     private fun shouldRunAction(controlId: String) =
         if (actionsInProgress.add(controlId)) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 4819bf5..a4f9f3a 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -54,7 +54,7 @@
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.controls.controller.ControlsController
 import com.android.systemui.util.concurrency.DelayableExecutor
-import kotlin.reflect.KClass
+import java.util.function.Supplier
 
 /**
  * Wraps the widgets that make up the UI representation of a {@link Control}. Updates to the view
@@ -90,20 +90,20 @@
             status: Int,
             template: ControlTemplate,
             deviceType: Int
-        ): KClass<out Behavior> {
+        ): Supplier<out Behavior> {
             return when {
-                status != Control.STATUS_OK -> StatusBehavior::class
-                template == ControlTemplate.NO_TEMPLATE -> TouchBehavior::class
-                template is ThumbnailTemplate -> ThumbnailBehavior::class
+                status != Control.STATUS_OK -> Supplier { StatusBehavior() }
+                template == ControlTemplate.NO_TEMPLATE -> Supplier { TouchBehavior() }
+                template is ThumbnailTemplate -> Supplier { ThumbnailBehavior() }
 
                 // Required for legacy support, or where cameras do not use the new template
-                deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class
-                template is ToggleTemplate -> ToggleBehavior::class
-                template is StatelessTemplate -> TouchBehavior::class
-                template is ToggleRangeTemplate -> ToggleRangeBehavior::class
-                template is RangeTemplate -> ToggleRangeBehavior::class
-                template is TemperatureControlTemplate -> TemperatureControlBehavior::class
-                else -> DefaultBehavior::class
+                deviceType == DeviceTypes.TYPE_CAMERA -> Supplier { TouchBehavior() }
+                template is ToggleTemplate -> Supplier { ToggleBehavior() }
+                template is StatelessTemplate -> Supplier { TouchBehavior() }
+                template is ToggleRangeTemplate -> Supplier { ToggleRangeBehavior() }
+                template is RangeTemplate -> Supplier { ToggleRangeBehavior() }
+                template is TemperatureControlTemplate -> Supplier { TemperatureControlBehavior() }
+                else -> Supplier { DefaultBehavior() }
             }
         }
     }
@@ -253,13 +253,14 @@
 
     fun bindBehavior(
         existingBehavior: Behavior?,
-        clazz: KClass<out Behavior>,
+        supplier: Supplier<out Behavior>,
         offset: Int = 0
     ): Behavior {
-        val behavior = if (existingBehavior == null || existingBehavior!!::class != clazz) {
+        val newBehavior = supplier.get()
+        val behavior = if (existingBehavior == null ||
+                existingBehavior::class != newBehavior::class) {
             // Behavior changes can signal a change in template from the app or
             // first time setup
-            val newBehavior = clazz.java.newInstance()
             newBehavior.initialize(this)
 
             // let behaviors define their own, if necessary, and clear any existing ones
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
index bd472a4..fc85a85 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/FrameworkServicesModule.java
@@ -26,6 +26,7 @@
 import android.app.KeyguardManager;
 import android.app.NotificationManager;
 import android.app.StatsManager;
+import android.app.UiModeManager;
 import android.app.WallpaperManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.role.RoleManager;
@@ -71,6 +72,7 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.CaptioningManager;
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.app.IBatteryStats;
@@ -120,6 +122,12 @@
 
     @Provides
     @Singleton
+    static CaptioningManager provideCaptioningManager(Context context) {
+        return context.getSystemService(CaptioningManager.class);
+    }
+
+    @Provides
+    @Singleton
     static ColorDisplayManager provideColorDisplayManager(Context context) {
         return context.getSystemService(ColorDisplayManager.class);
     }
@@ -324,6 +332,13 @@
         return context.getSystemService(PowerManager.class);
     }
 
+    /** */
+    @Provides
+    @Singleton
+    static UiModeManager provideUiModeManager(Context context) {
+        return context.getSystemService(UiModeManager.class);
+    }
+
     @Provides
     @Main
     static Resources provideResources(Context context) {
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/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index b32f878..2f041ac 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -18,7 +18,7 @@
 
 import com.android.systemui.keyguard.dagger.KeyguardModule;
 import com.android.systemui.recents.RecentsModule;
-import com.android.systemui.statusbar.dagger.StatusBarModule;
+import com.android.systemui.statusbar.dagger.CentralSurfacesModule;
 
 import dagger.Module;
 
@@ -27,7 +27,7 @@
  */
 @Module(includes = {
         RecentsModule.class,
-        StatusBarModule.class,
+        CentralSurfacesModule.class,
         KeyguardModule.class,
 })
 public abstract class SystemUIBinder {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index a4da6b4..5d154c3 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -48,7 +48,7 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.dagger.StartStatusBarModule;
+import com.android.systemui.statusbar.dagger.StartCentralSurfacesModule;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
@@ -87,7 +87,7 @@
         MediaModule.class,
         PowerModule.class,
         QSModule.class,
-        StartStatusBarModule.class,
+        StartCentralSurfacesModule.class,
         VolumeModule.class
 })
 public abstract class SystemUIDefaultModule {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 13067bf..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,9 +66,9 @@
 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.CentralSurfaces;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -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,
@@ -131,7 +131,7 @@
             WalletModule.class
         },
         subcomponents = {
-            StatusBarComponent.class,
+            CentralSurfacesComponent.class,
             NotificationRowComponent.class,
             DozeComponent.class,
             ExpandableNotificationRowComponent.class,
@@ -175,7 +175,7 @@
     abstract Recents optionalRecents();
 
     @BindsOptionalOf
-    abstract StatusBar optionalStatusBar();
+    abstract CentralSurfaces optionalCentralSurfaces();
 
     @BindsOptionalOf
     abstract UdfpsHbmProvider optionalUdfpsHbmProvider();
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 2beed4c..d89c0be 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -31,7 +31,6 @@
     boolean isPowerSaveActive();
     boolean isPulsingBlocked();
     boolean isProvisioned();
-    boolean isBlockingDoze();
 
     /**
      * Makes a current pulse last for twice as long.
@@ -80,8 +79,9 @@
      */
     void stopPulsing();
 
-    /** Returns whether doze is suppressed. */
-    boolean isDozeSuppressed();
+    /** Returns whether always-on-display is suppressed. This does not include suppressing
+     * wake-up gestures. */
+    boolean isAlwaysOnSuppressed();
 
     interface Callback {
         /**
@@ -97,8 +97,10 @@
          */
         default void onPowerSaveChanged(boolean active) {}
 
-        /** Called when the doze suppression state changes. */
-        default void onDozeSuppressedChanged(boolean suppressed) {}
+        /**
+         * Called when the always on suppression state changes. See {@link #isAlwaysOnSuppressed()}.
+         */
+        default void onAlwaysOnSuppressedChanged(boolean suppressed) {}
     }
 
     interface PulseCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 2511520..0a2e69f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -132,14 +132,6 @@
     }
 
     /**
-     * Appends dozing event to the logs
-     * @param suppressed true if dozing is suppressed
-     */
-    public void traceDozingSuppressed(boolean suppressed) {
-        mLogger.logDozingSuppressed(suppressed);
-    }
-
-    /**
      * Appends fling event to the logs
      */
     public void traceFling(boolean expand, boolean aboveThreshold, boolean thresholdNeeded,
@@ -325,15 +317,40 @@
     }
 
     /**
-     * Appends doze suppressed event to the logs
+     * Appends the doze state that was suppressed to the doze event log
      * @param suppressedState The {@link DozeMachine.State} that was suppressed
      */
-    public void traceDozeSuppressed(DozeMachine.State suppressedState) {
-        mLogger.logDozeSuppressed(suppressedState);
+    public void traceAlwaysOnSuppressed(DozeMachine.State suppressedState) {
+        mLogger.logAlwaysOnSuppressed(suppressedState);
     }
 
     /**
-     * Appends new AOD sreen brightness to logs
+     * Appends reason why doze immediately ended.
+     */
+    public void traceImmediatelyEndDoze(String reason) {
+        mLogger.logImmediatelyEndDoze(reason);
+    }
+
+    /**
+     * Appends power save changes that may cause a new doze state
+     * @param powerSaveActive true if power saving is active
+     * @param nextState the state that we'll transition to
+     */
+    public void tracePowerSaveChanged(boolean powerSaveActive, DozeMachine.State nextState) {
+        mLogger.logPowerSaveChanged(powerSaveActive, nextState);
+    }
+
+    /**
+     * Appends an event on AOD suppression change
+     * @param suppressed true if AOD is being suppressed
+     * @param nextState the state that we'll transition to
+     */
+    public void traceAlwaysOnSuppressedChange(boolean suppressed, DozeMachine.State nextState) {
+        mLogger.logAlwaysOnSuppressedChange(suppressed, nextState);
+    }
+
+    /**
+     * Appends new AOD screen brightness to logs
      * @param brightness display brightness setting
      */
     public void traceDozeScreenBrightness(int brightness) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
index 4ba6b51..f3f6be2 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
@@ -74,11 +74,21 @@
         })
     }
 
-    fun logDozingSuppressed(isDozingSuppressed: Boolean) {
+    fun logPowerSaveChanged(powerSaveActive: Boolean, nextState: DozeMachine.State) {
         buffer.log(TAG, INFO, {
-            bool1 = isDozingSuppressed
+            bool1 = powerSaveActive
+            str1 = nextState.name
         }, {
-            "DozingSuppressed=$bool1"
+            "Power save active=$bool1 nextState=$str1"
+        })
+    }
+
+    fun logAlwaysOnSuppressedChange(isAodSuppressed: Boolean, nextState: DozeMachine.State) {
+        buffer.log(TAG, INFO, {
+            bool1 = isAodSuppressed
+            str1 = nextState.name
+        }, {
+            "Always on (AOD) suppressed changed, suppressed=$bool1 nextState=$str1"
         })
     }
 
@@ -257,11 +267,19 @@
         })
     }
 
-    fun logDozeSuppressed(state: DozeMachine.State) {
+    fun logAlwaysOnSuppressed(state: DozeMachine.State) {
         buffer.log(TAG, INFO, {
             str1 = state.name
         }, {
-            "Doze state suppressed, state=$str1"
+            "Always-on state suppressed, suppressed state=$str1"
+        })
+    }
+
+    fun logImmediatelyEndDoze(reason: String) {
+        buffer.log(TAG, INFO, {
+            str1 = reason
+        }, {
+            "Doze immediately ended due to $str1"
         })
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 789ad62..ae01f0a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -357,9 +357,9 @@
         if (mState == State.FINISH) {
             return State.FINISH;
         }
-        if (mDozeHost.isDozeSuppressed() && requestedState.isAlwaysOn()) {
+        if (mDozeHost.isAlwaysOnSuppressed() && requestedState.isAlwaysOn()) {
             Log.i(TAG, "Doze is suppressed. Suppressing state: " + requestedState);
-            mDozeLog.traceDozeSuppressed(requestedState);
+            mDozeLog.traceAlwaysOnSuppressed(requestedState);
             return State.DOZE;
         }
         if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD_PAUSING
@@ -415,7 +415,6 @@
         pw.print(" state="); pw.println(mState);
         pw.print(" wakeLockHeldForCurrentState="); pw.println(mWakeLockHeldForCurrentState);
         pw.print(" wakeLock="); pw.println(mWakeLock);
-        pw.print(" isDozeSuppressed="); pw.println(mDozeHost.isDozeSuppressed());
         pw.println("Parts:");
         for (Part p : mParts) {
             p.dump(pw);
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
new file mode 100644
index 0000000..31d43b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java
@@ -0,0 +1,195 @@
+/*
+ * 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.doze;
+
+import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE;
+
+import android.app.UiModeManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Configuration;
+import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.text.TextUtils;
+
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.doze.dagger.DozeScope;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+
+import java.io.PrintWriter;
+
+import javax.inject.Inject;
+
+import dagger.Lazy;
+
+/**
+ * Handles suppressing doze on:
+ * 1. INITIALIZED, don't allow dozing at all when:
+ *      - in CAR_MODE
+ *      - device is NOT provisioned
+ *      - there's a pending authentication
+ * 2. PowerSaveMode active
+ *      - no always-on-display (DOZE_AOD)
+ *      - continues to allow doze triggers (DOZE, DOZE_REQUEST_PULSE)
+ * 3. Suppression changes from the PowerManager API. See {@link PowerManager#suppressAmbientDisplay}
+ *      and {@link DozeHost#isAlwaysOnSuppressed()}.
+ *      - no always-on-display (DOZE_AOD)
+ *      - allow doze triggers (DOZE), but disallow notifications (handled by {@link DozeTriggers})
+ *      - See extra check in {@link DozeMachine} to guarantee device never enters always-on states
+ */
+@DozeScope
+public class DozeSuppressor implements DozeMachine.Part {
+    private static final String TAG = "DozeSuppressor";
+
+    private DozeMachine mMachine;
+    private final DozeHost mDozeHost;
+    private final AmbientDisplayConfiguration mConfig;
+    private final DozeLog mDozeLog;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final UiModeManager mUiModeManager;
+    private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
+
+    private boolean mBroadcastReceiverRegistered;
+
+    @Inject
+    public DozeSuppressor(
+            DozeHost dozeHost,
+            AmbientDisplayConfiguration config,
+            DozeLog dozeLog,
+            BroadcastDispatcher broadcastDispatcher,
+            UiModeManager uiModeManager,
+            Lazy<BiometricUnlockController> biometricUnlockControllerLazy) {
+        mDozeHost = dozeHost;
+        mConfig = config;
+        mDozeLog = dozeLog;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mUiModeManager = uiModeManager;
+        mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
+    }
+
+    @Override
+    public void setDozeMachine(DozeMachine dozeMachine) {
+        mMachine = dozeMachine;
+    }
+
+    @Override
+    public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+        switch (newState) {
+            case INITIALIZED:
+                registerBroadcastReceiver();
+                mDozeHost.addCallback(mHostCallback);
+                checkShouldImmediatelyEndDoze();
+                break;
+            case FINISH:
+                destroy();
+                break;
+            default:
+        }
+    }
+
+    @Override
+    public void destroy() {
+        unregisterBroadcastReceiver();
+        mDozeHost.removeCallback(mHostCallback);
+    }
+
+    private void checkShouldImmediatelyEndDoze() {
+        String reason = null;
+        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
+            reason = "car_mode";
+        } else if (!mDozeHost.isProvisioned()) {
+            reason = "device_unprovisioned";
+        } else if (mBiometricUnlockControllerLazy.get().hasPendingAuthentication()) {
+            reason = "has_pending_auth";
+        }
+
+        if (!TextUtils.isEmpty(reason)) {
+            mDozeLog.traceImmediatelyEndDoze(reason);
+            mMachine.requestState(DozeMachine.State.FINISH);
+        }
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        pw.println(" uiMode=" + mUiModeManager.getCurrentModeType());
+        pw.println(" hasPendingAuth="
+                + mBiometricUnlockControllerLazy.get().hasPendingAuthentication());
+        pw.println(" isProvisioned=" + mDozeHost.isProvisioned());
+        pw.println(" isAlwaysOnSuppressed=" + mDozeHost.isAlwaysOnSuppressed());
+        pw.println(" aodPowerSaveActive=" + mDozeHost.isPowerSaveActive());
+    }
+
+    private void registerBroadcastReceiver() {
+        if (mBroadcastReceiverRegistered) {
+            return;
+        }
+        IntentFilter filter = new IntentFilter(ACTION_ENTER_CAR_MODE);
+        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
+        mBroadcastReceiverRegistered = true;
+    }
+
+    private void unregisterBroadcastReceiver() {
+        if (!mBroadcastReceiverRegistered) {
+            return;
+        }
+        mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
+        mBroadcastReceiverRegistered = false;
+    }
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
+                mDozeLog.traceImmediatelyEndDoze("car_mode");
+                mMachine.requestState(DozeMachine.State.FINISH);
+            }
+        }
+    };
+
+    private DozeHost.Callback mHostCallback = new DozeHost.Callback() {
+        @Override
+        public void onPowerSaveChanged(boolean active) {
+            DozeMachine.State nextState = null;
+            if (mDozeHost.isPowerSaveActive()) {
+                nextState = DozeMachine.State.DOZE;
+            } else if (mMachine.getState() == DozeMachine.State.DOZE
+                    && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
+                nextState = DozeMachine.State.DOZE_AOD;
+            }
+
+            if (nextState != null) {
+                mDozeLog.tracePowerSaveChanged(mDozeHost.isPowerSaveActive(), nextState);
+                mMachine.requestState(nextState);
+            }
+        }
+
+        @Override
+        public void onAlwaysOnSuppressedChanged(boolean suppressed) {
+            final DozeMachine.State nextState;
+            if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !suppressed) {
+                nextState = DozeMachine.State.DOZE_AOD;
+            } else {
+                nextState = DozeMachine.State.DOZE;
+            }
+            mDozeLog.traceAlwaysOnSuppressedChange(suppressed, nextState);
+            mMachine.requestState(nextState);
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 8bff3ba..74044e2 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -17,12 +17,10 @@
 package com.android.systemui.doze;
 
 import android.annotation.Nullable;
-import android.app.UiModeManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Configuration;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -88,7 +86,6 @@
     private final AsyncSensorManager mSensorManager;
     private final WakeLock mWakeLock;
     private final boolean mAllowPulseTriggers;
-    private final UiModeManager mUiModeManager;
     private final TriggerReceiver mBroadcastReceiver = new TriggerReceiver();
     private final DockEventListener mDockEventListener = new DockEventListener();
     private final DockManager mDockManager;
@@ -203,8 +200,6 @@
         mDozeSensors = new DozeSensors(context, mSensorManager, dozeParameters,
                 config, wakeLock, this::onSensor, this::onProximityFar, dozeLog, proximitySensor,
                 secureSettings, authController, devicePostureController);
-
-        mUiModeManager = mContext.getSystemService(UiModeManager.class);
         mDockManager = dockManager;
         mProxCheck = proxCheck;
         mDozeLog = dozeLog;
@@ -247,7 +242,7 @@
             mDozeLog.tracePulseDropped("pulseOnNotificationsDisabled");
             return;
         }
-        if (mDozeHost.isDozeSuppressed()) {
+        if (mDozeHost.isAlwaysOnSuppressed()) {
             runIfNotNull(onPulseSuppressedListener);
             mDozeLog.tracePulseDropped("dozeSuppressed");
             return;
@@ -456,10 +451,9 @@
                 mAodInterruptRunnable = null;
                 sWakeDisplaySensorState = true;
                 mBroadcastReceiver.register(mBroadcastDispatcher);
-                mDozeHost.addCallback(mHostCallback);
                 mDockManager.addListener(mDockEventListener);
                 mDozeSensors.requestTemporaryDisable();
-                checkTriggersAtInit();
+                mDozeHost.addCallback(mHostCallback);
                 break;
             case DOZE:
             case DOZE_AOD:
@@ -516,15 +510,6 @@
         }
     }
 
-
-    private void checkTriggersAtInit() {
-        if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
-                || mDozeHost.isBlockingDoze()
-                || !mDozeHost.isProvisioned()) {
-            mMachine.requestState(DozeMachine.State.FINISH);
-        }
-    }
-
     private void requestPulse(final int reason, boolean performedProxCheck,
             Runnable onPulseSuppressedListener) {
         Assert.isMainThread();
@@ -608,9 +593,6 @@
                 requestPulse(DozeLog.PULSE_REASON_INTENT, false, /* performedProxCheck */
                         null /* onPulseSuppressedListener */);
             }
-            if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
-                mMachine.requestState(DozeMachine.State.FINISH);
-            }
             if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
                 mDozeSensors.onUserSwitched();
             }
@@ -621,7 +603,6 @@
                 return;
             }
             IntentFilter filter = new IntentFilter(PULSE_ACTION);
-            filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
             filter.addAction(Intent.ACTION_USER_SWITCHED);
             broadcastDispatcher.registerReceiver(this, filter);
             mRegistered = true;
@@ -659,26 +640,5 @@
         public void onNotificationAlerted(Runnable onPulseSuppressedListener) {
             onNotification(onPulseSuppressedListener);
         }
-
-        @Override
-        public void onPowerSaveChanged(boolean active) {
-            if (mDozeHost.isPowerSaveActive()) {
-                mMachine.requestState(DozeMachine.State.DOZE);
-            } else if (mMachine.getState() == DozeMachine.State.DOZE
-                    && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
-                mMachine.requestState(DozeMachine.State.DOZE_AOD);
-            }
-        }
-
-        @Override
-        public void onDozeSuppressedChanged(boolean suppressed) {
-            final DozeMachine.State nextState;
-            if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !suppressed) {
-                nextState = DozeMachine.State.DOZE_AOD;
-            } else {
-                nextState = DozeMachine.State.DOZE;
-            }
-            mMachine.requestState(nextState);
-        }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
index 32b7658..98cd2d7 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/dagger/DozeModule.java
@@ -33,6 +33,7 @@
 import com.android.systemui.doze.DozeScreenState;
 import com.android.systemui.doze.DozeScreenStatePreventingAdapter;
 import com.android.systemui.doze.DozeSensors;
+import com.android.systemui.doze.DozeSuppressor;
 import com.android.systemui.doze.DozeSuspendScreenStatePreventingAdapter;
 import com.android.systemui.doze.DozeTriggers;
 import com.android.systemui.doze.DozeUi;
@@ -77,11 +78,12 @@
     }
 
     @Provides
-    static DozeMachine.Part[] providesDozeMachinePartes(DozePauser dozePauser,
+    static DozeMachine.Part[] providesDozeMachineParts(DozePauser dozePauser,
             DozeFalsingManagerAdapter dozeFalsingManagerAdapter, DozeTriggers dozeTriggers,
             DozeUi dozeUi, DozeScreenState dozeScreenState,
             DozeScreenBrightness dozeScreenBrightness, DozeWallpaperState dozeWallpaperState,
-            DozeDockHandler dozeDockHandler, DozeAuthRemover dozeAuthRemover) {
+            DozeDockHandler dozeDockHandler, DozeAuthRemover dozeAuthRemover,
+            DozeSuppressor dozeSuppressor) {
         return new DozeMachine.Part[]{
                 dozePauser,
                 dozeFalsingManagerAdapter,
@@ -91,7 +93,8 @@
                 dozeScreenBrightness,
                 dozeWallpaperState,
                 dozeDockHandler,
-                dozeAuthRemover
+                dozeAuthRemover,
+                dozeSuppressor
         };
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
index be76e8f..69f15e6 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -18,18 +18,15 @@
 
 import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
 
-import android.graphics.Rect;
-import android.graphics.Region;
 import android.os.Handler;
+import android.util.MathUtils;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
 
 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.complication.dagger.ComplicationHostViewComponent;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
 import com.android.systemui.dreams.dagger.DreamOverlayModule;
 import com.android.systemui.util.ViewController;
@@ -59,56 +56,26 @@
     // The interval in milliseconds between burn-in protection updates.
     private final long mBurnInProtectionUpdateInterval;
 
+    // Amount of time in milliseconds to linear interpolate toward the final jitter offset. Once
+    // this time is achieved, the normal jitter algorithm applies in full.
+    private final long mMillisUntilFullJitter;
+
     // Main thread handler used to schedule periodic tasks (e.g. burn-in protection updates).
     private final Handler mHandler;
 
-    // A hook into the internal inset calculation where we declare the overlays as the only
-    // touchable regions.
-    private final ViewTreeObserver.OnComputeInternalInsetsListener
-            mOnComputeInternalInsetsListener =
-            new ViewTreeObserver.OnComputeInternalInsetsListener() {
-                @Override
-                public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
-                    inoutInfo.setTouchableInsets(
-                            ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
-                    final Region region = new Region();
-                    final Rect rect = new Rect();
-                    final int childCount = mDreamOverlayContentView.getChildCount();
-                    for (int i = 0; i < childCount; i++) {
-                        View child = mDreamOverlayContentView.getChildAt(i);
-
-                        if (mComplicationHostViewController.getView() == child) {
-                            region.op(mComplicationHostViewController.getTouchRegions(),
-                                    Region.Op.UNION);
-                            continue;
-                        }
-
-                        if (child.getGlobalVisibleRect(rect)) {
-                            region.op(rect, Region.Op.UNION);
-                        }
-                    }
-
-                    // Add the notifications drag area to the tap region (otherwise the
-                    // notifications shade can't be dragged down).
-                    if (mDreamOverlayContentView.getGlobalVisibleRect(rect)) {
-                        rect.bottom = rect.top + mDreamOverlayNotificationsDragAreaHeight;
-                        region.op(rect, Region.Op.UNION);
-                    }
-
-                    inoutInfo.touchableRegion.set(region);
-                }
-            };
+    private long mJitterStartTimeMillis;
 
     @Inject
     public DreamOverlayContainerViewController(
             DreamOverlayContainerView containerView,
-            ComplicationHostViewComponent.Factory complicationHostViewFactory,
+            ComplicationHostViewController complicationHostViewController,
             @Named(DreamOverlayModule.DREAM_OVERLAY_CONTENT_VIEW) ViewGroup contentView,
             DreamOverlayStatusBarViewController statusBarViewController,
             @Main Handler handler,
             @Named(DreamOverlayModule.MAX_BURN_IN_OFFSET) int maxBurnInOffset,
             @Named(DreamOverlayModule.BURN_IN_PROTECTION_UPDATE_INTERVAL) long
-                    burnInProtectionUpdateInterval) {
+                    burnInProtectionUpdateInterval,
+            @Named(DreamOverlayModule.MILLIS_UNTIL_FULL_JITTER) long millisUntilFullJitter) {
         super(containerView);
         mDreamOverlayContentView = contentView;
         mStatusBarViewController = statusBarViewController;
@@ -116,7 +83,7 @@
                 mView.getResources().getDimensionPixelSize(
                         R.dimen.dream_overlay_notifications_drag_area_height);
 
-        mComplicationHostViewController = complicationHostViewFactory.create().getController();
+        mComplicationHostViewController = complicationHostViewController;
         final View view = mComplicationHostViewController.getView();
 
         mDreamOverlayContentView.addView(view,
@@ -126,6 +93,7 @@
         mHandler = handler;
         mMaxBurnInOffset = maxBurnInOffset;
         mBurnInProtectionUpdateInterval = burnInProtectionUpdateInterval;
+        mMillisUntilFullJitter = millisUntilFullJitter;
     }
 
     @Override
@@ -136,16 +104,13 @@
 
     @Override
     protected void onViewAttached() {
-        mView.getViewTreeObserver()
-                .addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
+        mJitterStartTimeMillis = System.currentTimeMillis();
         mHandler.postDelayed(this::updateBurnInOffsets, mBurnInProtectionUpdateInterval);
     }
 
     @Override
     protected void onViewDetached() {
         mHandler.removeCallbacks(this::updateBurnInOffsets);
-        mView.getViewTreeObserver()
-                .removeOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
     }
 
     View getContainerView() {
@@ -158,12 +123,24 @@
     }
 
     private void updateBurnInOffsets() {
+        int burnInOffset = mMaxBurnInOffset;
+
+        // Make sure the offset starts at zero, to avoid a big jump in the overlay when it first
+        // appears.
+        long millisSinceStart = System.currentTimeMillis() - mJitterStartTimeMillis;
+        if (millisSinceStart < mMillisUntilFullJitter) {
+            float lerpAmount = (float) millisSinceStart / (float) mMillisUntilFullJitter;
+            burnInOffset = Math.round(MathUtils.lerp(0f, burnInOffset, lerpAmount));
+        }
+
         // These translation values change slowly, and the set translation methods are idempotent,
         // so no translation occurs when the values don't change.
-        mView.setTranslationX(getBurnInOffset(mMaxBurnInOffset * 2, true)
-                - mMaxBurnInOffset);
-        mView.setTranslationY(getBurnInOffset(mMaxBurnInOffset * 2, false)
-                - mMaxBurnInOffset);
+        int burnInOffsetX = getBurnInOffset(burnInOffset * 2, true)
+                - burnInOffset;
+        int burnInOffsetY = getBurnInOffset(burnInOffset * 2, false)
+                - burnInOffset;
+        mView.setTranslationX(burnInOffsetX);
+        mView.setTranslationY(burnInOffsetY);
 
         mHandler.postDelayed(this::updateBurnInOffsets, mBurnInProtectionUpdateInterval);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 338a8b2..dfbb0c7 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -19,6 +19,8 @@
 import android.content.Context;
 import android.graphics.drawable.ColorDrawable;
 import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowInsets;
 import android.view.WindowManager;
@@ -33,6 +35,7 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.dreams.complication.DreamPreviewComplication;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
 import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
 
@@ -57,10 +60,14 @@
     // content area).
     private final DreamOverlayContainerViewController mDreamOverlayContainerViewController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+    private final DreamPreviewComplication mPreviewComplication;
 
     // 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() {
@@ -96,12 +103,14 @@
             @Main Executor executor,
             DreamOverlayComponent.Factory dreamOverlayComponentFactory,
             DreamOverlayStateController stateController,
-            KeyguardUpdateMonitor keyguardUpdateMonitor) {
+            KeyguardUpdateMonitor keyguardUpdateMonitor,
+            DreamPreviewComplication previewComplication) {
         mContext = context;
         mExecutor = executor;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
         mStateController = stateController;
+        mPreviewComplication = previewComplication;
 
         final DreamOverlayComponent component =
                 dreamOverlayComponentFactory.create(mViewModelStore, mHost);
@@ -125,6 +134,10 @@
             windowManager.removeView(mWindow.getDecorView());
         }
         mStateController.setOverlayActive(false);
+        mPreviewComplication.setDreamLabel(null);
+        mStateController.removeComplication(mPreviewComplication);
+        mStateController.setPreviewMode(false);
+        mDestroyed = true;
         super.onDestroy();
     }
 
@@ -132,7 +145,17 @@
     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()) {
+                mPreviewComplication.setDreamLabel(getDreamLabel());
+                mStateController.addComplication(mPreviewComplication);
+            }
             addOverlayWindowLocked(layoutParams);
             setCurrentState(Lifecycle.State.RESUMED);
             mStateController.setOverlayActive(true);
@@ -165,9 +188,26 @@
         }
 
         mDreamOverlayContainerViewController.init();
+        // Make extra sure the container view has been removed from its old parent (otherwise we
+        // risk an IllegalStateException in some cases when setting the container view as the
+        // window's content view and the container view hasn't been properly removed previously).
+        removeContainerViewFromParent();
         mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView());
 
         final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
         windowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
     }
+
+    private void removeContainerViewFromParent() {
+        View containerView = mDreamOverlayContainerViewController.getContainerView();
+        if (containerView == null) {
+            return;
+        }
+        ViewGroup parentView = (ViewGroup) containerView.getParent();
+        if (parentView == null) {
+            return;
+        }
+        Log.w(TAG, "Removing dream overlay container view parent!");
+        parentView.removeView(containerView);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
index fc71e2f..6860998 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStateController.java
@@ -50,6 +50,7 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     public static final int STATE_DREAM_OVERLAY_ACTIVE = 1 << 0;
+    public static final int STATE_PREVIEW_MODE = 1 << 1;
 
     private static final int OP_CLEAR_STATE = 1;
     private static final int OP_SET_STATE = 2;
@@ -249,4 +250,18 @@
             mCallbacks.forEach(Callback::onAvailableComplicationTypesChanged);
         });
     }
+
+    /**
+     * Sets whether the dream is running in preview mode.
+     */
+    public void setPreviewMode(boolean isPreviewMode) {
+        modifyState(isPreviewMode ? OP_SET_STATE : OP_CLEAR_STATE, STATE_PREVIEW_MODE);
+    }
+
+    /**
+     * Returns whether the dream is running in preview mode.
+     */
+    public boolean isPreviewMode() {
+        return containsState(STATE_PREVIEW_MODE);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
index 2d96920..d2ab611 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarView.java
@@ -16,23 +16,44 @@
 
 package com.android.systemui.dreams;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
-import android.widget.ImageView;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
 
-import com.android.internal.util.Preconditions;
 import com.android.systemui.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
 /**
  * {@link DreamOverlayStatusBarView} is the view responsible for displaying the status bar in a
  * dream. The status bar displays conditional status icons such as "priority mode" and "no wifi".
  */
 public class DreamOverlayStatusBarView extends ConstraintLayout {
 
-    private ImageView mWifiStatusView;
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "STATUS_ICON_" }, value = {
+            STATUS_ICON_NOTIFICATIONS,
+            STATUS_ICON_WIFI_UNAVAILABLE,
+            STATUS_ICON_ALARM_SET,
+            STATUS_ICON_MIC_CAMERA_DISABLED,
+            STATUS_ICON_PRIORITY_MODE_ON
+    })
+    public @interface StatusIconType {}
+    public static final int STATUS_ICON_NOTIFICATIONS = 0;
+    public static final int STATUS_ICON_WIFI_UNAVAILABLE = 1;
+    public static final int STATUS_ICON_ALARM_SET = 2;
+    public static final int STATUS_ICON_MIC_CAMERA_DISABLED = 3;
+    public static final int STATUS_ICON_PRIORITY_MODE_ON = 4;
+
+    private final Map<Integer, View> mStatusIcons = new HashMap<>();
 
     public DreamOverlayStatusBarView(Context context) {
         this(context, null);
@@ -55,16 +76,35 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
 
-        mWifiStatusView = Preconditions.checkNotNull(findViewById(R.id.dream_overlay_wifi_status),
-                "R.id.dream_overlay_wifi_status must not be null");
+        mStatusIcons.put(STATUS_ICON_WIFI_UNAVAILABLE,
+                fetchStatusIconForResId(R.id.dream_overlay_wifi_status));
+        mStatusIcons.put(STATUS_ICON_ALARM_SET,
+                fetchStatusIconForResId(R.id.dream_overlay_alarm_set));
+        mStatusIcons.put(STATUS_ICON_MIC_CAMERA_DISABLED,
+                fetchStatusIconForResId(R.id.dream_overlay_camera_mic_off));
+        mStatusIcons.put(STATUS_ICON_NOTIFICATIONS,
+                fetchStatusIconForResId(R.id.dream_overlay_notification_indicator));
+        mStatusIcons.put(STATUS_ICON_PRIORITY_MODE_ON,
+                fetchStatusIconForResId(R.id.dream_overlay_priority_mode));
     }
 
-    /**
-     * Whether to show the wifi status icon.
-     * @param show True if the wifi status icon should be shown.
-     */
-    void showWifiStatus(boolean show) {
-        // Only show the wifi status icon when wifi isn't available.
-        mWifiStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
+    void showIcon(@StatusIconType int iconType, boolean show) {
+        showIcon(iconType, show, null);
+    }
+
+    void showIcon(@StatusIconType int iconType, boolean show, @Nullable String contentDescription) {
+        View icon = mStatusIcons.get(iconType);
+        if (icon == null) {
+            return;
+        }
+        if (show && contentDescription != null) {
+            icon.setContentDescription(contentDescription);
+        }
+        icon.setVisibility(show ? View.VISIBLE : View.GONE);
+    }
+
+    private View fetchStatusIconForResId(int resId) {
+        final View statusIcon = findViewById(resId);
+        return Objects.requireNonNull(statusIcon);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
index ed82ab0..a25a742 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayStatusBarViewController.java
@@ -16,18 +16,35 @@
 
 package com.android.systemui.dreams;
 
-import android.annotation.IntDef;
+import android.app.AlarmManager;
+import android.content.res.Resources;
+import android.hardware.SensorPrivacyManager;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.notification.NotificationListenerService.RankingMap;
+import android.service.notification.StatusBarNotification;
+import android.text.format.DateFormat;
+import android.util.PluralsMessageFormatter;
 
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
+import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.touch.TouchInsetManager;
 import com.android.systemui.util.ViewController;
+import com.android.systemui.util.time.DateFormatUtil;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import java.util.Locale;
+import java.util.Map;
 
 import javax.inject.Inject;
 
@@ -36,18 +53,15 @@
  */
 @DreamOverlayComponent.DreamOverlayScope
 public class DreamOverlayStatusBarViewController extends ViewController<DreamOverlayStatusBarView> {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = { "WIFI_STATUS_" }, value = {
-            WIFI_STATUS_UNKNOWN,
-            WIFI_STATUS_UNAVAILABLE,
-            WIFI_STATUS_AVAILABLE
-    })
-    private @interface WifiStatus {}
-    private static final int WIFI_STATUS_UNKNOWN = 0;
-    private static final int WIFI_STATUS_UNAVAILABLE = 1;
-    private static final int WIFI_STATUS_AVAILABLE = 2;
-
     private final ConnectivityManager mConnectivityManager;
+    private final TouchInsetManager.TouchInsetSession mTouchInsetSession;
+    private final NextAlarmController mNextAlarmController;
+    private final AlarmManager mAlarmManager;
+    private final Resources mResources;
+    private final DateFormatUtil mDateFormatUtil;
+    private final IndividualSensorPrivacyController mSensorPrivacyController;
+    private final NotificationListener mNotificationListener;
+    private final ZenModeController mZenModeController;
 
     private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
             .clearCapabilities()
@@ -57,57 +71,183 @@
         @Override
         public void onCapabilitiesChanged(
                 Network network, NetworkCapabilities networkCapabilities) {
-            onWifiAvailabilityChanged(
-                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
+            updateWifiUnavailableStatusIcon();
         }
 
         @Override
         public void onAvailable(Network network) {
-            onWifiAvailabilityChanged(true);
+            updateWifiUnavailableStatusIcon();
         }
 
         @Override
         public void onLost(Network network) {
-            onWifiAvailabilityChanged(false);
+            updateWifiUnavailableStatusIcon();
         }
     };
 
-    private @WifiStatus int mWifiStatus = WIFI_STATUS_UNKNOWN;
+    private final IndividualSensorPrivacyController.Callback mSensorCallback =
+            (sensor, blocked) -> updateMicCameraBlockedStatusIcon();
+
+    private final NextAlarmController.NextAlarmChangeCallback mNextAlarmCallback =
+            nextAlarm -> updateAlarmStatusIcon();
+
+    private final NotificationHandler mNotificationHandler = new NotificationHandler() {
+        @Override
+        public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+            updateNotificationsStatusIcon();
+        }
+
+        @Override
+        public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+            updateNotificationsStatusIcon();
+        }
+
+        @Override
+        public void onNotificationRemoved(
+                StatusBarNotification sbn,
+                RankingMap rankingMap,
+                int reason) {
+            updateNotificationsStatusIcon();
+        }
+
+        @Override
+        public void onNotificationRankingUpdate(RankingMap rankingMap) {
+        }
+
+        @Override
+        public void onNotificationsInitialized() {
+            updateNotificationsStatusIcon();
+        }
+    };
+
+    private final ZenModeController.Callback mZenModeCallback = new ZenModeController.Callback() {
+        @Override
+        public void onZenChanged(int zen) {
+            updatePriorityModeStatusIcon();
+        }
+    };
 
     @Inject
     public DreamOverlayStatusBarViewController(
             DreamOverlayStatusBarView view,
-            ConnectivityManager connectivityManager) {
+            @Main Resources resources,
+            ConnectivityManager connectivityManager,
+            TouchInsetManager.TouchInsetSession touchInsetSession,
+            AlarmManager alarmManager,
+            NextAlarmController nextAlarmController,
+            DateFormatUtil dateFormatUtil,
+            IndividualSensorPrivacyController sensorPrivacyController,
+            NotificationListener notificationListener,
+            ZenModeController zenModeController) {
         super(view);
+        mResources = resources;
         mConnectivityManager = connectivityManager;
+        mTouchInsetSession = touchInsetSession;
+        mAlarmManager = alarmManager;
+        mNextAlarmController = nextAlarmController;
+        mDateFormatUtil = dateFormatUtil;
+        mSensorPrivacyController = sensorPrivacyController;
+        mNotificationListener = notificationListener;
+        mZenModeController = zenModeController;
+
+        // Handlers can be added to NotificationListener, but apparently they can't be removed. So
+        // add the handler here in the constructor rather than in onViewAttached to avoid confusion.
+        mNotificationListener.addNotificationHandler(mNotificationHandler);
     }
 
     @Override
     protected void onViewAttached() {
-        mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
+        updateNotificationsStatusIcon();
 
-        NetworkCapabilities capabilities =
-                mConnectivityManager.getNetworkCapabilities(
-                        mConnectivityManager.getActiveNetwork());
-        onWifiAvailabilityChanged(
-                capabilities != null
-                        && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
+        mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
+        updateWifiUnavailableStatusIcon();
+
+        mNextAlarmController.addCallback(mNextAlarmCallback);
+        updateAlarmStatusIcon();
+
+        mSensorPrivacyController.addCallback(mSensorCallback);
+        updateMicCameraBlockedStatusIcon();
+
+        mZenModeController.addCallback(mZenModeCallback);
+        updatePriorityModeStatusIcon();
+
+        mTouchInsetSession.addViewToTracking(mView);
     }
 
     @Override
     protected void onViewDetached() {
+        mZenModeController.removeCallback(mZenModeCallback);
+        mSensorPrivacyController.removeCallback(mSensorCallback);
+        mNextAlarmController.removeCallback(mNextAlarmCallback);
         mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+        mTouchInsetSession.clear();
     }
 
-    /**
-     * Wifi availability has changed. Update the wifi status icon as appropriate.
-     * @param available Whether wifi is available.
-     */
-    private void onWifiAvailabilityChanged(boolean available) {
-        final int newWifiStatus = available ? WIFI_STATUS_AVAILABLE : WIFI_STATUS_UNAVAILABLE;
-        if (mWifiStatus != newWifiStatus) {
-            mWifiStatus = newWifiStatus;
-            mView.showWifiStatus(mWifiStatus == WIFI_STATUS_UNAVAILABLE);
+    private void updateWifiUnavailableStatusIcon() {
+        final NetworkCapabilities capabilities =
+                mConnectivityManager.getNetworkCapabilities(
+                        mConnectivityManager.getActiveNetwork());
+        final boolean available = capabilities != null
+                && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
+        mView.showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, !available);
+    }
+
+    private void updateAlarmStatusIcon() {
+        final AlarmManager.AlarmClockInfo alarm =
+                mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
+        final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
+        mView.showIcon(
+                DreamOverlayStatusBarView.STATUS_ICON_ALARM_SET,
+                hasAlarm,
+                hasAlarm ? buildAlarmContentDescription(alarm) : null);
+    }
+
+    private String buildAlarmContentDescription(AlarmManager.AlarmClockInfo alarm) {
+        final String skeleton = mDateFormatUtil.is24HourFormat() ? "EHm" : "Ehma";
+        final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
+        final String dateString = DateFormat.format(pattern, alarm.getTriggerTime()).toString();
+
+        return mResources.getString(R.string.accessibility_quick_settings_alarm, dateString);
+    }
+
+    private void updateMicCameraBlockedStatusIcon() {
+        final boolean micBlocked = mSensorPrivacyController
+                .isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE);
+        final boolean cameraBlocked = mSensorPrivacyController
+                .isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA);
+        mView.showIcon(
+                DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED,
+                micBlocked && cameraBlocked);
+    }
+
+    private void updateNotificationsStatusIcon() {
+        if (mView == null) {
+            // It is possible for this method to be called before the view is attached, which makes
+            // null-checking necessary.
+            return;
         }
+
+        final StatusBarNotification[] notifications =
+                mNotificationListener.getActiveNotifications();
+        final int notificationCount = notifications != null ? notifications.length : 0;
+        mView.showIcon(
+                DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS,
+                notificationCount > 0,
+                notificationCount > 0
+                        ? buildNotificationsContentDescription(notificationCount)
+                        : null);
+    }
+
+    private String buildNotificationsContentDescription(int notificationCount) {
+        return PluralsMessageFormatter.format(
+                mResources,
+                Map.of("count", notificationCount),
+                R.string.dream_overlay_status_bar_notification_indicator);
+    }
+
+    private void updatePriorityModeStatusIcon() {
+        mView.showIcon(
+                DreamOverlayStatusBarView.STATUS_ICON_PRIORITY_MODE_ON,
+                mZenModeController.getZen() != Settings.Global.ZEN_MODE_OFF);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/SmartSpaceComplication.java
index 240389a..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,20 +75,27 @@
 
         @Override
         public void start() {
-            if (mSmartSpaceController.isEnabled()) {
-                mDreamOverlayStateController.addComplication(mComplication);
-            }
+            mDreamOverlayStateController.addCallback(new DreamOverlayStateController.Callback() {
+                @Override
+                public void onStateChanged() {
+                    if (mDreamOverlayStateController.isOverlayActive()) {
+                        mSmartSpaceController.addListener(mSmartspaceListener);
+                    } else {
+                        mSmartSpaceController.removeListener(mSmartspaceListener);
+                    }
+                }
+            });
         }
     }
 
     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;
         }
@@ -97,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/Complication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/Complication.java
index fe458f4..51bd311 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/Complication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/Complication.java
@@ -186,6 +186,19 @@
     }
 
     /**
+     * The implementation of this interface is in charge of managing the visible state of
+     * the shown complication.
+     */
+    interface VisibilityController {
+        /**
+         * Called to set the visibility of all shown and future complications.
+         * @param visibility The desired future visibility.
+         * @param animate whether the change should be animated.
+         */
+        void setVisibility(@View.Visibility int visibility, boolean animate);
+    }
+
+    /**
      * Returned through {@link Complication#createView(ComplicationViewModel)}, {@link ViewHolder}
      * is a container for a single {@link Complication} instance. The {@link Host} guarantees that
      * the {@link ViewHolder} will be retained for the lifetime of the {@link Complication}
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 f627f15..4e528bb 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationHostViewController.java
@@ -16,11 +16,12 @@
 
 package com.android.systemui.dreams.complication;
 
-import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewComponent.SCOPED_COMPLICATIONS_LAYOUT;
+import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.SCOPED_COMPLICATIONS_LAYOUT;
 import static com.android.systemui.dreams.complication.dagger.ComplicationModule.SCOPED_COMPLICATIONS_MODEL;
 
 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/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
index 0b80d8a..aa43383 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/ComplicationLayoutEngine.java
@@ -16,17 +16,24 @@
 
 package com.android.systemui.dreams.complication;
 
-import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewComponent.COMPLICATION_MARGIN;
-import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewComponent.SCOPED_COMPLICATIONS_LAYOUT;
+import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATIONS_FADE_IN_DURATION;
+import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATIONS_FADE_OUT_DURATION;
+import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGIN;
+import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.SCOPED_COMPLICATIONS_LAYOUT;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 
 import androidx.constraintlayout.widget.ConstraintLayout;
 import androidx.constraintlayout.widget.Constraints;
 
 import com.android.systemui.R;
+import com.android.systemui.dreams.dagger.DreamOverlayComponent;
+import com.android.systemui.touch.TouchInsetManager;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -42,7 +49,8 @@
  * their layout parameters and attributes. The management of this set is done by
  * {@link ComplicationHostViewController}.
  */
-public class ComplicationLayoutEngine  {
+@DreamOverlayComponent.DreamOverlayScope
+public class ComplicationLayoutEngine implements Complication.VisibilityController {
     public static final String TAG = "ComplicationLayoutEngine";
 
     /**
@@ -52,6 +60,7 @@
     private static class ViewEntry implements Comparable<ViewEntry> {
         private final View mView;
         private final ComplicationLayoutParams mLayoutParams;
+        private final TouchInsetManager.TouchInsetSession mTouchInsetSession;
         private final Parent mParent;
         @Complication.Category
         private final int mCategory;
@@ -61,7 +70,8 @@
          * Default constructor. {@link Parent} allows for the {@link ViewEntry}'s surrounding
          * view hierarchy to be accessed without traversing the entire view tree.
          */
-        ViewEntry(View view, ComplicationLayoutParams layoutParams, int category, Parent parent,
+        ViewEntry(View view, ComplicationLayoutParams layoutParams,
+                TouchInsetManager.TouchInsetSession touchSession, int category, Parent parent,
                 int margin) {
             mView = view;
             // Views that are generated programmatically do not have a unique id assigned to them
@@ -70,9 +80,12 @@
             // {@link Complication.ViewHolder} should not reference the root container by id.
             mView.setId(View.generateViewId());
             mLayoutParams = layoutParams;
+            mTouchInsetSession = touchSession;
             mCategory = category;
             mParent = parent;
             mMargin = margin;
+
+            touchSession.addViewToTracking(mView);
         }
 
         /**
@@ -217,6 +230,7 @@
             mParent.removeEntry(this);
 
             ((ViewGroup) mView.getParent()).removeView(mView);
+            mTouchInsetSession.removeViewFromTracking(mView);
         }
 
         @Override
@@ -242,15 +256,18 @@
          */
         private static class Builder {
             private final View mView;
+            private final TouchInsetManager.TouchInsetSession mTouchSession;
             private final ComplicationLayoutParams mLayoutParams;
             private final int mCategory;
             private Parent mParent;
             private int mMargin;
 
-            Builder(View view, ComplicationLayoutParams lp, @Complication.Category int category) {
+            Builder(View view, TouchInsetManager.TouchInsetSession touchSession,
+                    ComplicationLayoutParams lp, @Complication.Category int category) {
                 mView = view;
                 mLayoutParams = lp;
                 mCategory = category;
+                mTouchSession = touchSession;
             }
 
             /**
@@ -291,7 +308,8 @@
              * Builds and returns the resulting {@link ViewEntry}.
              */
             ViewEntry build() {
-                return new ViewEntry(mView, mLayoutParams, mCategory, mParent, mMargin);
+                return new ViewEntry(mView, mLayoutParams, mTouchSession, mCategory, mParent,
+                        mMargin);
             }
         }
 
@@ -442,13 +460,46 @@
     private final int mMargin;
     private final HashMap<ComplicationId, ViewEntry> mEntries = new HashMap<>();
     private final HashMap<Integer, PositionGroup> mPositions = new HashMap<>();
+    private final TouchInsetManager.TouchInsetSession mSession;
+    private final int mFadeInDuration;
+    private final int mFadeOutDuration;
+    private ViewPropertyAnimator mViewPropertyAnimator;
 
     /** */
     @Inject
     public ComplicationLayoutEngine(@Named(SCOPED_COMPLICATIONS_LAYOUT) ConstraintLayout layout,
-            @Named(COMPLICATION_MARGIN) int margin) {
+            @Named(COMPLICATION_MARGIN) int margin,
+            TouchInsetManager.TouchInsetSession session,
+            @Named(COMPLICATIONS_FADE_IN_DURATION) int fadeInDuration,
+            @Named(COMPLICATIONS_FADE_OUT_DURATION) int fadeOutDuration) {
         mLayout = layout;
         mMargin = margin;
+        mSession = session;
+        mFadeInDuration = fadeInDuration;
+        mFadeOutDuration = fadeOutDuration;
+    }
+
+    @Override
+    public void setVisibility(int visibility, boolean animate) {
+        final boolean appearing = visibility == View.VISIBLE;
+
+        if (mViewPropertyAnimator != null) {
+            mViewPropertyAnimator.cancel();
+        }
+
+        if (appearing) {
+            mLayout.setVisibility(View.VISIBLE);
+        }
+
+        mViewPropertyAnimator = mLayout.animate()
+                .alpha(appearing ? 1f : 0f)
+                .setDuration(appearing ? mFadeInDuration : mFadeOutDuration)
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        mLayout.setVisibility(visibility);
+                    }
+                });
     }
 
     /**
@@ -463,12 +514,14 @@
      */
     public void addComplication(ComplicationId id, View view,
             ComplicationLayoutParams lp, @Complication.Category int category) {
+        Log.d(TAG, "engine: " + this + " addComplication");
+
         // If the complication is present, remove.
         if (mEntries.containsKey(id)) {
             removeComplication(id);
         }
 
-        final ViewEntry.Builder entryBuilder = new ViewEntry.Builder(view, lp, category)
+        final ViewEntry.Builder entryBuilder = new ViewEntry.Builder(view, mSession, lp, category)
                 .setMargin(mMargin);
 
         // Add position group if doesn't already exist
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamPreviewComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamPreviewComplication.java
new file mode 100644
index 0000000..cc2e571
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamPreviewComplication.java
@@ -0,0 +1,137 @@
+/*
+ * 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.complication;
+
+import static com.android.systemui.dreams.complication.dagger.DreamPreviewComplicationComponent.DREAM_LABEL;
+import static com.android.systemui.dreams.complication.dagger.DreamPreviewComplicationComponent.DreamPreviewComplicationModule.DREAM_PREVIEW_COMPLICATION_LAYOUT_PARAMS;
+import static com.android.systemui.dreams.complication.dagger.DreamPreviewComplicationComponent.DreamPreviewComplicationModule.DREAM_PREVIEW_COMPLICATION_VIEW;
+
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.systemui.dreams.complication.dagger.DreamPreviewComplicationComponent;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * Preview complication shown when user is previewing a dream.
+ */
+public class DreamPreviewComplication implements Complication {
+    DreamPreviewComplicationComponent.Factory mComponentFactory;
+    @Nullable
+    private CharSequence mDreamLabel;
+
+    /**
+     * Default constructor for {@link DreamPreviewComplication}.
+     */
+    @Inject
+    public DreamPreviewComplication(
+            DreamPreviewComplicationComponent.Factory componentFactory) {
+        mComponentFactory = componentFactory;
+    }
+
+    /**
+     * Create {@link DreamPreviewViewHolder}.
+     */
+    @Override
+    public ViewHolder createView(ComplicationViewModel model) {
+        return mComponentFactory.create(model, mDreamLabel).getViewHolder();
+    }
+
+    /**
+     * Sets the user-facing label for the current dream.
+     */
+    public void setDreamLabel(@Nullable CharSequence dreamLabel) {
+        mDreamLabel = dreamLabel;
+    }
+
+    /**
+     * ViewHolder to contain value/logic associated with a Preview Complication View.
+     */
+    public static class DreamPreviewViewHolder implements ViewHolder {
+        private final TextView mView;
+        private final ComplicationLayoutParams mLayoutParams;
+        private final DreamPreviewViewController mViewController;
+
+        @Inject
+        DreamPreviewViewHolder(@Named(DREAM_PREVIEW_COMPLICATION_VIEW) TextView view,
+                DreamPreviewViewController controller,
+                @Named(DREAM_PREVIEW_COMPLICATION_LAYOUT_PARAMS)
+                        ComplicationLayoutParams layoutParams,
+                @Named(DREAM_LABEL) @Nullable CharSequence dreamLabel) {
+            mView = view;
+            mLayoutParams = layoutParams;
+            mViewController = controller;
+            mViewController.init();
+
+            if (!TextUtils.isEmpty(dreamLabel)) {
+                mView.setText(dreamLabel);
+            }
+            for (Drawable drawable : mView.getCompoundDrawablesRelative()) {
+                if (drawable instanceof BitmapDrawable) {
+                    drawable.setAutoMirrored(true);
+                }
+            }
+        }
+
+        @Override
+        public View getView() {
+            return mView;
+        }
+
+        @Override
+        public ComplicationLayoutParams getLayoutParams() {
+            return mLayoutParams;
+        }
+
+        @Override
+        public int getCategory() {
+            return CATEGORY_SYSTEM;
+        }
+    }
+
+    /**
+     * ViewController to contain value/logic associated with a Preview Complication View.
+     */
+    static class DreamPreviewViewController extends ViewController<TextView> {
+        private final ComplicationViewModel mViewModel;
+
+        @Inject
+        DreamPreviewViewController(@Named(DREAM_PREVIEW_COMPLICATION_VIEW) TextView view,
+                ComplicationViewModel viewModel) {
+            super(view);
+            mViewModel = viewModel;
+        }
+
+        @Override
+        protected void onViewAttached() {
+            mView.setOnClickListener(v -> mViewModel.exitDream());
+        }
+
+        @Override
+        protected void onViewDetached() {
+            mView.setOnClickListener(null);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewComponent.java
deleted file mode 100644
index 20b0e50..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewComponent.java
+++ /dev/null
@@ -1,98 +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.dreams.complication.dagger;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import android.content.res.Resources;
-import android.view.LayoutInflater;
-
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-import com.android.internal.util.Preconditions;
-import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dreams.complication.ComplicationHostViewController;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Named;
-import javax.inject.Scope;
-
-import dagger.Module;
-import dagger.Provides;
-import dagger.Subcomponent;
-
-/**
- * {@link ComplicationHostViewComponent} encapsulates the shared logic around the host view layer
- * for complications. Anything that references the layout should be provided through this component
- * and its child module. The factory should be used in order to best tie the lifetime of the view
- * to components.
- */
-@Subcomponent(modules = {
-        ComplicationHostViewComponent.ComplicationHostViewModule.class,
-})
-@ComplicationHostViewComponent.ComplicationHostViewScope
-public interface ComplicationHostViewComponent {
-    String SCOPED_COMPLICATIONS_LAYOUT = "scoped_complications_layout";
-    String COMPLICATION_MARGIN = "complication_margin";
-    /** Scope annotation for singleton items within {@link ComplicationHostViewComponent}. */
-    @Documented
-    @Retention(RUNTIME)
-    @Scope
-    @interface ComplicationHostViewScope {}
-
-    /**
-     * Factory for generating a new scoped component.
-     */
-    @Subcomponent.Factory
-    interface Factory {
-        ComplicationHostViewComponent create();
-    }
-
-    /** */
-    ComplicationHostViewController getController();
-
-    /**
-     * Module for providing a scoped host view.
-     */
-    @Module
-    abstract class ComplicationHostViewModule {
-        /**
-         * Generates a {@link ConstraintLayout}, which can host
-         * {@link com.android.systemui.dreams.complication.Complication} instances.
-         */
-        @Provides
-        @Named(SCOPED_COMPLICATIONS_LAYOUT)
-        @ComplicationHostViewScope
-        static ConstraintLayout providesComplicationHostView(
-                LayoutInflater layoutInflater) {
-            return Preconditions.checkNotNull((ConstraintLayout)
-                            layoutInflater.inflate(R.layout.dream_overlay_complications_layer,
-                                    null),
-                    "R.layout.dream_overlay_complications_layer did not properly inflated");
-        }
-
-        @Provides
-        @Named(COMPLICATION_MARGIN)
-        @ComplicationHostViewScope
-        static int providesComplicationPadding(@Main Resources resources) {
-            return resources.getDimensionPixelSize(R.dimen.dream_overlay_complication_margin);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java
new file mode 100644
index 0000000..11d89d2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationHostViewModule.java
@@ -0,0 +1,96 @@
+/*
+ * 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.complication.dagger;
+
+import android.content.res.Resources;
+import android.view.LayoutInflater;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.android.internal.util.Preconditions;
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dreams.dagger.DreamOverlayComponent;
+
+import javax.inject.Named;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Module for providing a scoped host view.
+ */
+@Module
+public abstract class ComplicationHostViewModule {
+    public static final String SCOPED_COMPLICATIONS_LAYOUT = "scoped_complications_layout";
+    public static final String COMPLICATION_MARGIN = "complication_margin";
+    public static final String COMPLICATIONS_FADE_OUT_DURATION = "complications_fade_out_duration";
+    public static final String COMPLICATIONS_FADE_IN_DURATION = "complications_fade_in_duration";
+    public static final String COMPLICATIONS_RESTORE_TIMEOUT = "complication_restore_timeout";
+
+    /**
+     * Generates a {@link ConstraintLayout}, which can host
+     * {@link com.android.systemui.dreams.complication.Complication} instances.
+     */
+    @Provides
+    @Named(SCOPED_COMPLICATIONS_LAYOUT)
+    @DreamOverlayComponent.DreamOverlayScope
+    static ConstraintLayout providesComplicationHostView(
+            LayoutInflater layoutInflater) {
+        return Preconditions.checkNotNull((ConstraintLayout)
+                        layoutInflater.inflate(R.layout.dream_overlay_complications_layer,
+                                null),
+                "R.layout.dream_overlay_complications_layer did not properly inflated");
+    }
+
+    @Provides
+    @Named(COMPLICATION_MARGIN)
+    @DreamOverlayComponent.DreamOverlayScope
+    static int providesComplicationPadding(@Main Resources resources) {
+        return resources.getDimensionPixelSize(R.dimen.dream_overlay_complication_margin);
+    }
+
+    /**
+     * Provides the fade out duration for complications.
+     */
+    @Provides
+    @Named(COMPLICATIONS_FADE_OUT_DURATION)
+    @DreamOverlayComponent.DreamOverlayScope
+    static int providesComplicationsFadeOutDuration(@Main Resources resources) {
+        return resources.getInteger(R.integer.complicationFadeOutMs);
+    }
+
+    /**
+     * Provides the fade in duration for complications.
+     */
+    @Provides
+    @Named(COMPLICATIONS_FADE_IN_DURATION)
+    @DreamOverlayComponent.DreamOverlayScope
+    static int providesComplicationsFadeInDuration(@Main Resources resources) {
+        return resources.getInteger(R.integer.complicationFadeInMs);
+    }
+
+    /**
+     * Provides the timeout for restoring complication visibility.
+     */
+    @Provides
+    @Named(COMPLICATIONS_RESTORE_TIMEOUT)
+    @DreamOverlayComponent.DreamOverlayScope
+    static int providesComplicationsRestoreTimeout(@Main Resources resources) {
+        return resources.getInteger(R.integer.complicationRestoreMs);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java
index b29e8c9..5c2fdf5 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/ComplicationModule.java
@@ -21,7 +21,9 @@
 import androidx.lifecycle.ViewModelProvider;
 import androidx.lifecycle.ViewModelStore;
 
+import com.android.systemui.dreams.complication.Complication;
 import com.android.systemui.dreams.complication.ComplicationCollectionViewModel;
+import com.android.systemui.dreams.complication.ComplicationLayoutEngine;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
@@ -35,9 +37,10 @@
 /**
  * Module for housing components related to rendering complications.
  */
-@Module(subcomponents = {
+@Module(includes = {
+        ComplicationHostViewModule.class,
+        }, subcomponents = {
         ComplicationViewModelComponent.class,
-        ComplicationHostViewComponent.class,
 })
 public interface ComplicationModule {
     String SCOPED_COMPLICATIONS_MODEL = "scoped_complications_model";
@@ -61,4 +64,13 @@
 
         return provider.get(ComplicationCollectionViewModel.class);
     }
+
+    /**
+     * Provides the visibility controller for display complications.
+     */
+    @Provides
+    static Complication.VisibilityController providesVisibilityController(
+            ComplicationLayoutEngine engine) {
+        return engine;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamPreviewComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamPreviewComplicationComponent.java
new file mode 100644
index 0000000..502e31e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamPreviewComplicationComponent.java
@@ -0,0 +1,117 @@
+/*
+ * 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.complication.dagger;
+
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.util.Preconditions;
+import com.android.systemui.R;
+import com.android.systemui.dreams.complication.ComplicationLayoutParams;
+import com.android.systemui.dreams.complication.ComplicationViewModel;
+import com.android.systemui.dreams.complication.DreamPreviewComplication.DreamPreviewViewHolder;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Named;
+import javax.inject.Scope;
+
+import dagger.BindsInstance;
+import dagger.Module;
+import dagger.Provides;
+import dagger.Subcomponent;
+
+/**
+ * {@link DreamPreviewComplicationComponent} is responsible for generating dependencies
+ * surrounding the
+ * Preview {@link com.android.systemui.dreams.complication.Complication}, such as the layout
+ * details.
+ */
+@Subcomponent(modules = {
+        DreamPreviewComplicationComponent.DreamPreviewComplicationModule.class,
+})
+@DreamPreviewComplicationComponent.DreamPreviewComplicationScope
+public interface DreamPreviewComplicationComponent {
+    String DREAM_LABEL = "dream_label";
+
+    /**
+     * Creates {@link DreamPreviewViewHolder}.
+     */
+    DreamPreviewViewHolder getViewHolder();
+
+    @Documented
+    @Retention(RUNTIME)
+    @Scope
+    @interface DreamPreviewComplicationScope {
+    }
+
+    /**
+     * Generates {@link DreamPreviewComplicationComponent}.
+     */
+    @Subcomponent.Factory
+    interface Factory {
+        DreamPreviewComplicationComponent create(
+                @BindsInstance ComplicationViewModel viewModel,
+                @Named(DREAM_LABEL) @BindsInstance @Nullable CharSequence dreamLabel);
+    }
+
+    /**
+     * Scoped values for {@link DreamPreviewComplicationComponent}.
+     */
+    @Module
+    interface DreamPreviewComplicationModule {
+        String DREAM_PREVIEW_COMPLICATION_VIEW = "preview_complication_view";
+        String DREAM_PREVIEW_COMPLICATION_LAYOUT_PARAMS = "preview_complication_layout_params";
+        // Order weight of insert into parent container
+        int INSERT_ORDER_WEIGHT = 1000;
+
+        /**
+         * Provides the complication view.
+         */
+        @Provides
+        @DreamPreviewComplicationScope
+        @Named(DREAM_PREVIEW_COMPLICATION_VIEW)
+        static TextView provideComplicationView(LayoutInflater layoutInflater) {
+            return Preconditions.checkNotNull((TextView)
+                            layoutInflater.inflate(R.layout.dream_overlay_complication_preview,
+                                    null, false),
+                    "R.layout.dream_overlay_complication_preview did not properly inflated");
+        }
+
+        /**
+         * Provides the layout parameters for the complication view.
+         */
+        @Provides
+        @DreamPreviewComplicationScope
+        @Named(DREAM_PREVIEW_COMPLICATION_LAYOUT_PARAMS)
+        static ComplicationLayoutParams provideLayoutParams() {
+            return new ComplicationLayoutParams(0,
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    ComplicationLayoutParams.POSITION_TOP
+                            | ComplicationLayoutParams.POSITION_START,
+                    ComplicationLayoutParams.DIRECTION_DOWN,
+                    INSERT_ORDER_WEIGHT, /* snapToGuide= */ true);
+        }
+    }
+}
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 c61f796..c7b02cd 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -19,21 +19,21 @@
 import android.content.Context;
 
 import com.android.settingslib.dream.DreamBackend;
+import com.android.systemui.dreams.complication.dagger.DreamPreviewComplicationComponent;
 import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
-import com.android.systemui.dreams.touch.dagger.DreamTouchModule;
 
 import dagger.Module;
 import dagger.Provides;
 
 /**
- * Dagger Module providing Communal-related functionality.
+ * Dagger Module providing Dream-related functionality.
  */
 @Module(includes = {
-            DreamTouchModule.class,
             RegisteredComplicationsModule.class,
         },
         subcomponents = {
             DreamOverlayComponent.class,
+            DreamPreviewComplicationComponent.class,
         })
 public interface DreamModule {
     /**
@@ -43,4 +43,4 @@
     static DreamBackend providesDreamBackend(Context context) {
         return DreamBackend.getInstance(context);
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
index 05ab901..f927ba6 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
@@ -26,6 +26,7 @@
 import com.android.systemui.dreams.complication.Complication;
 import com.android.systemui.dreams.complication.dagger.ComplicationModule;
 import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
+import com.android.systemui.dreams.touch.dagger.DreamTouchModule;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.Retention;
@@ -39,6 +40,7 @@
  * Dagger subcomponent for {@link DreamOverlayModule}.
  */
 @Subcomponent(modules = {
+        DreamTouchModule.class,
         DreamOverlayModule.class,
         ComplicationModule.class,
 })
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index 839a05e..4fe1622 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -29,6 +29,9 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.DreamOverlayContainerView;
 import com.android.systemui.dreams.DreamOverlayStatusBarView;
+import com.android.systemui.touch.TouchInsetManager;
+
+import java.util.concurrent.Executor;
 
 import javax.inject.Named;
 
@@ -43,6 +46,7 @@
     public static final String MAX_BURN_IN_OFFSET = "max_burn_in_offset";
     public static final String BURN_IN_PROTECTION_UPDATE_INTERVAL =
             "burn_in_protection_update_interval";
+    public static final String MILLIS_UNTIL_FULL_JITTER = "millis_until_full_jitter";
 
     /** */
     @Provides
@@ -65,6 +69,21 @@
 
     /** */
     @Provides
+    public static TouchInsetManager.TouchInsetSession providesTouchInsetSession(
+            TouchInsetManager manager) {
+        return manager.createSession();
+    }
+
+    /** */
+    @Provides
+    @DreamOverlayComponent.DreamOverlayScope
+    public static TouchInsetManager providesTouchInsetManager(@Main Executor executor,
+            DreamOverlayContainerView view) {
+        return new TouchInsetManager(executor, view);
+    }
+
+    /** */
+    @Provides
     @DreamOverlayComponent.DreamOverlayScope
     public static DreamOverlayStatusBarView providesDreamOverlayStatusBarView(
             DreamOverlayContainerView view) {
@@ -88,6 +107,13 @@
                 R.integer.config_dreamOverlayBurnInProtectionUpdateIntervalMillis);
     }
 
+    /** */
+    @Provides
+    @Named(MILLIS_UNTIL_FULL_JITTER)
+    static long providesMillisUntilFullJitter(@Main Resources resources) {
+        return resources.getInteger(R.integer.config_dreamOverlayMillisUntilFullJitter);
+    }
+
     @Provides
     @DreamOverlayComponent.DreamOverlayScope
     static LifecycleOwner providesLifecycleOwner(Lazy<LifecycleRegistry> lifecycleRegistryLazy) {
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/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index d16c8c8..e140f6b 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -21,6 +21,9 @@
 import static com.android.systemui.dreams.touch.dagger.BouncerSwipeModule.SWIPE_TO_BOUNCER_START_REGION;
 
 import android.animation.ValueAnimator;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.GestureDetector;
 import android.view.InputEvent;
@@ -29,7 +32,7 @@
 
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
@@ -68,13 +71,15 @@
 
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private float mCurrentExpansion;
-    private final StatusBar mStatusBar;
+    private final CentralSurfaces mCentralSurfaces;
 
     private VelocityTracker mVelocityTracker;
 
     private final FlingAnimationUtils mFlingAnimationUtils;
     private final FlingAnimationUtils mFlingAnimationUtilsClosing;
 
+    private final DisplayMetrics mDisplayMetrics;
+
     private Boolean mCapture;
 
     private TouchSession mTouchSession;
@@ -85,40 +90,9 @@
 
     private final GestureDetector.OnGestureListener mOnGestureListener =
             new  GestureDetector.SimpleOnGestureListener() {
-                boolean mTrack;
-                boolean mBouncerPresent;
-
-                @Override
-                public boolean onDown(MotionEvent e) {
-                    // We only consider gestures that originate from the lower portion of the
-                    // screen.
-                    final float displayHeight = mStatusBar.getDisplayHeight();
-
-                    mBouncerPresent = mStatusBar.isBouncerShowing();
-
-                    // The target zone is either at the top or bottom of the screen, dependent on
-                    // whether the bouncer is present.
-                    final float zonePercentage =
-                            Math.abs(e.getY() - (mBouncerPresent ? 0 : displayHeight))
-                                    / displayHeight;
-
-                    mTrack =  zonePercentage < mBouncerZoneScreenPercentage;
-
-                    // Never capture onDown. While this might lead to some false positive touches
-                    // being sent to other windows/layers, this is necessary to make sure the
-                    // proper touch event sequence is received by others in the event we do not
-                    // consume the sequence here.
-                    return false;
-                }
-
                 @Override
                 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                         float distanceY) {
-                    // Do not handle scroll gestures if not tracking touch events.
-                    if (!mTrack) {
-                        return false;
-                    }
-
                     if (mCapture == null) {
                         // If the user scrolling favors a vertical direction, begin capturing
                         // scrolls.
@@ -140,10 +114,9 @@
                     // is fully hidden at full expansion (1) and fully visible when fully collapsed
                     // (0).
                     final float screenTravelPercentage =
-                            Math.abs((e1.getY() - e2.getY()) / mStatusBar.getDisplayHeight());
-                    setPanelExpansion(
-                            mBouncerPresent ? screenTravelPercentage : 1 - screenTravelPercentage);
-
+                            Math.abs((e1.getY() - e2.getY()) / mCentralSurfaces.getDisplayHeight());
+                    setPanelExpansion(mCentralSurfaces.isBouncerShowing()
+                            ? screenTravelPercentage : 1 - screenTravelPercentage);
                     return true;
                 }
             };
@@ -155,8 +128,9 @@
 
     @Inject
     public BouncerSwipeTouchHandler(
+            DisplayMetrics displayMetrics,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            StatusBar statusBar,
+            CentralSurfaces centralSurfaces,
             NotificationShadeWindowController notificationShadeWindowController,
             ValueAnimatorCreator valueAnimatorCreator,
             VelocityTrackerFactory velocityTrackerFactory,
@@ -165,7 +139,8 @@
             @Named(SWIPE_TO_BOUNCER_FLING_ANIMATION_UTILS_OPENING)
                     FlingAnimationUtils flingAnimationUtilsClosing,
             @Named(SWIPE_TO_BOUNCER_START_REGION) float swipeRegionPercentage) {
-        mStatusBar = statusBar;
+        mDisplayMetrics = displayMetrics;
+        mCentralSurfaces = centralSurfaces;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mNotificationShadeWindowController = notificationShadeWindowController;
         mBouncerZoneScreenPercentage = swipeRegionPercentage;
@@ -176,6 +151,21 @@
     }
 
     @Override
+    public void getTouchInitiationRegion(Region region) {
+        if (mCentralSurfaces.isBouncerShowing()) {
+            region.op(new Rect(0, 0, mDisplayMetrics.widthPixels,
+                    Math.round(mDisplayMetrics.heightPixels * mBouncerZoneScreenPercentage)),
+                    Region.Op.UNION);
+        } else {
+            region.op(new Rect(0,
+                    Math.round(mDisplayMetrics.heightPixels * (1 - mBouncerZoneScreenPercentage)),
+                    mDisplayMetrics.widthPixels,
+                    mDisplayMetrics.heightPixels),
+                    Region.Op.UNION);
+        }
+    }
+
+    @Override
     public void onSessionStart(TouchSession session) {
         mVelocityTracker = mVelocityTrackerFactory.obtain();
         mTouchSession = session;
@@ -202,7 +192,9 @@
         final MotionEvent motionEvent = (MotionEvent) event;
 
         switch(motionEvent.getAction()) {
+            case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
+                mTouchSession.pop();
                 // If we are not capturing any input, there is no need to consider animating to
                 // finish transition.
                 if (mCapture == null || !mCapture) {
@@ -226,7 +218,6 @@
                 if (expansion == KeyguardBouncer.EXPANSION_HIDDEN) {
                     mStatusBarKeyguardViewManager.reset(false);
                 }
-                mTouchSession.pop();
                 break;
             default:
                 mVelocityTracker.addMovement(motionEvent);
@@ -255,7 +246,7 @@
     }
 
     protected void flingToExpansion(float velocity, float expansion) {
-        final float viewHeight = mStatusBar.getDisplayHeight();
+        final float viewHeight = mCentralSurfaces.getDisplayHeight();
         final float currentHeight = viewHeight * mCurrentExpansion;
         final float targetHeight = viewHeight * expansion;
 
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
index 3e5efb2..695b59a 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dreams.touch;
 
+import android.graphics.Region;
 import android.view.GestureDetector;
 import android.view.InputEvent;
 import android.view.MotionEvent;
@@ -34,6 +35,7 @@
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.Executor;
@@ -100,6 +102,10 @@
         });
     }
 
+    private int getSessionCount() {
+        return mActiveTouchSessions.size();
+    }
+
     /**
      * {@link TouchSessionImpl} implements {@link DreamTouchHandler.TouchSession} for
      * {@link DreamOverlayTouchMonitor}. It enables the monitor to access the associated listeners
@@ -146,6 +152,11 @@
             return mTouchMonitor.pop(this);
         }
 
+        @Override
+        public int getActiveSessionCount() {
+            return mTouchMonitor.getSessionCount();
+        }
+
         /**
          * Returns the active listeners to receive touch events.
          */
@@ -229,12 +240,39 @@
         public void onInputEvent(InputEvent ev) {
             // No Active sessions are receiving touches. Create sessions for each listener
             if (mActiveTouchSessions.isEmpty()) {
+                final HashMap<DreamTouchHandler, DreamTouchHandler.TouchSession> sessionMap =
+                        new HashMap<>();
+
                 for (DreamTouchHandler handler : mHandlers) {
+                    final Region initiationRegion = Region.obtain();
+                    handler.getTouchInitiationRegion(initiationRegion);
+
+                    if (!initiationRegion.isEmpty()) {
+                        // Initiation regions require a motion event to determine pointer location
+                        // within the region.
+                        if (!(ev instanceof MotionEvent)) {
+                            continue;
+                        }
+
+                        final MotionEvent motionEvent = (MotionEvent) ev;
+
+                        // If the touch event is outside the region, then ignore.
+                        if (!initiationRegion.contains(Math.round(motionEvent.getX()),
+                                Math.round(motionEvent.getY()))) {
+                            continue;
+                        }
+                    }
+
                     final TouchSessionImpl sessionStack =
                             new TouchSessionImpl(DreamOverlayTouchMonitor.this, null);
                     mActiveTouchSessions.add(sessionStack);
-                    handler.onSessionStart(sessionStack);
+                    sessionMap.put(handler, sessionStack);
                 }
+
+                // Informing handlers of new sessions is delayed until we have all created so the
+                // final session is correct.
+                sessionMap.forEach((dreamTouchHandler, touchSession)
+                        -> dreamTouchHandler.onSessionStart(touchSession));
             }
 
             // Find active sessions and invoke on InputEvent.
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
index c73ff73..20008d5 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.dreams.touch;
 
+import android.graphics.Region;
 import android.view.GestureDetector;
 
 import com.android.systemui.shared.system.InputChannelCompat;
@@ -71,6 +72,19 @@
          * if the popped {@link TouchSession} was the initial session or has already been popped.
          */
         ListenableFuture<TouchSession> pop();
+
+        /**
+         * Returns the number of currently active sessions.
+         */
+        int getActiveSessionCount();
+    }
+
+    /**
+     * Returns the region the touch handler is interested in. By default, no region is specified,
+     * indicating the entire screen should be considered.
+     * @param region A {@link Region} that is passed in to the target entry touch region.
+     */
+    default void getTouchInitiationRegion(Region region) {
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java
new file mode 100644
index 0000000..d4ba2d8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/HideComplicationTouchHandler.java
@@ -0,0 +1,137 @@
+/*
+ * 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.touch;
+
+import static com.android.systemui.dreams.complication.dagger.ComplicationHostViewModule.COMPLICATIONS_RESTORE_TIMEOUT;
+
+import android.os.Handler;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.touch.TouchInsetManager;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * {@link HideComplicationTouchHandler} is responsible for hiding the overlay complications from
+ * visibility whenever there is touch interactions outside the overlay. The overlay interaction
+ * scope includes touches to the complication plus any touch entry region for gestures as specified
+ * to the {@link DreamOverlayTouchMonitor}.
+ *
+ * This {@link DreamTouchHandler} is also responsible for fading in the complications at the end
+ * of the {@link com.android.systemui.dreams.touch.DreamTouchHandler.TouchSession}.
+ */
+public class HideComplicationTouchHandler implements DreamTouchHandler {
+    private static final String TAG = "HideComplicationHandler";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Complication.VisibilityController mVisibilityController;
+    private final int mRestoreTimeout;
+    private final Handler mHandler;
+    private final Executor mExecutor;
+    private final TouchInsetManager mTouchInsetManager;
+
+    private final Runnable mRestoreComplications = new Runnable() {
+        @Override
+        public void run() {
+            mVisibilityController.setVisibility(View.VISIBLE, true);
+        }
+    };
+
+    @Inject
+    HideComplicationTouchHandler(Complication.VisibilityController visibilityController,
+            @Named(COMPLICATIONS_RESTORE_TIMEOUT) int restoreTimeout,
+            TouchInsetManager touchInsetManager,
+            @Main Executor executor,
+            @Main Handler handler) {
+        mVisibilityController = visibilityController;
+        mRestoreTimeout = restoreTimeout;
+        mHandler = handler;
+        mTouchInsetManager = touchInsetManager;
+        mExecutor = executor;
+    }
+
+    @Override
+    public void onSessionStart(TouchSession session) {
+        if (DEBUG) {
+            Log.d(TAG, "onSessionStart");
+        }
+
+        // If other sessions are interested in this touch, do not fade out elements.
+        if (session.getActiveSessionCount() > 1) {
+            if (DEBUG) {
+                Log.d(TAG, "multiple active touch sessions, not fading");
+            }
+            session.pop();
+            return;
+        }
+
+        session.registerInputListener(ev -> {
+            if (!(ev instanceof MotionEvent)) {
+                return;
+            }
+
+            final MotionEvent motionEvent = (MotionEvent) ev;
+
+            if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
+                if (DEBUG) {
+                    Log.d(TAG, "ACTION_DOWN received");
+                }
+
+                final ListenableFuture<Boolean> touchCheck = mTouchInsetManager
+                        .checkWithinTouchRegion(Math.round(motionEvent.getX()),
+                                Math.round(motionEvent.getY()));
+
+                touchCheck.addListener(() -> {
+                    try {
+                        if (!touchCheck.get()) {
+                            mHandler.removeCallbacks(mRestoreComplications);
+                            mVisibilityController.setVisibility(View.INVISIBLE, true);
+                        } else {
+                            // If a touch occurred inside the dream overlay touch insets, do not
+                            // handle the touch.
+                            session.pop();
+                        }
+                    } catch (InterruptedException | ExecutionException exception) {
+                        Log.e(TAG, "could not check TouchInsetManager:" + exception);
+                    }
+                }, mExecutor);
+            } else if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
+                    || motionEvent.getAction() == MotionEvent.ACTION_UP) {
+                // End session and initiate delayed reappearance of the complications.
+                session.pop();
+                mHandler.postDelayed(mRestoreComplications, mRestoreTimeout);
+            }
+        });
+    }
+
+    @Override
+    public void onSessionEnd(TouchSession session) {
+        if (DEBUG) {
+            Log.d(TAG, "onSessionEnd");
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/DreamTouchModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/DreamTouchModule.java
index dad0004..7338ecb 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/DreamTouchModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/DreamTouchModule.java
@@ -23,6 +23,7 @@
  */
 @Module(includes = {
             BouncerSwipeModule.class,
+            HideComplicationModule.class,
         }, subcomponents = {
             InputSessionComponent.class,
 })
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/HideComplicationModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/HideComplicationModule.java
new file mode 100644
index 0000000..3800ff7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/HideComplicationModule.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams.touch.dagger;
+
+import com.android.systemui.dreams.touch.DreamTouchHandler;
+import com.android.systemui.dreams.touch.HideComplicationTouchHandler;
+
+import dagger.Module;
+import dagger.Provides;
+import dagger.multibindings.IntoSet;
+
+/**
+ * Module for {@link HideComplicationTouchHandler}.
+ */
+@Module
+public class HideComplicationModule {
+    /**
+     * Provides {@link HideComplicationTouchHandler} for inclusion in touch handling over the dream.
+     */
+    @Provides
+    @IntoSet
+    public static DreamTouchHandler providesHideComplicationTouchHandler(
+            HideComplicationTouchHandler touchHandler) {
+        return touchHandler;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
index 96a90df..9d6e3c2 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
@@ -28,6 +28,9 @@
     /** Returns a boolean value for the given flag.  */
     fun isEnabled(flag: ResourceBooleanFlag): Boolean
 
+    /** Returns a boolean value for the given flag.  */
+    fun isEnabled(flag: SysPropBooleanFlag): Boolean
+
     /** Returns a string value for the given flag.  */
     fun getString(flag: StringFlag): String
 
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
index df60599..0c5f7eb 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
@@ -49,6 +49,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.TreeMap;
+import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 import javax.inject.Inject;
@@ -69,6 +70,7 @@
     private final FlagManager mFlagManager;
     private final SecureSettings mSecureSettings;
     private final Resources mResources;
+    private final SystemPropertiesHelper mSystemProperties;
     private final Supplier<Map<Integer, Flag<?>>> mFlagsCollector;
     private final Map<Integer, Boolean> mBooleanFlagCache = new TreeMap<>();
     private final Map<Integer, String> mStringFlagCache = new TreeMap<>();
@@ -79,6 +81,7 @@
             FlagManager flagManager,
             Context context,
             SecureSettings secureSettings,
+            SystemPropertiesHelper systemProperties,
             @Main Resources resources,
             DumpManager dumpManager,
             @Nullable Supplier<Map<Integer, Flag<?>>> flagsCollector,
@@ -86,11 +89,12 @@
         mFlagManager = flagManager;
         mSecureSettings = secureSettings;
         mResources = resources;
+        mSystemProperties = systemProperties;
         mFlagsCollector = flagsCollector != null ? flagsCollector : Flags::collectFlags;
         IntentFilter filter = new IntentFilter();
         filter.addAction(ACTION_SET_FLAG);
         filter.addAction(ACTION_GET_FLAGS);
-        flagManager.setRestartAction(this::restartSystemUI);
+        flagManager.setOnSettingsChangedAction(this::restartSystemUI);
         flagManager.setClearCacheAction(this::removeFromCache);
         context.registerReceiver(mReceiver, filter, null, null,
                 Context.RECEIVER_EXPORTED_UNAUDITED);
@@ -121,6 +125,17 @@
         return mBooleanFlagCache.get(id);
     }
 
+    @Override
+    public boolean isEnabled(@NonNull SysPropBooleanFlag flag) {
+        int id = flag.getId();
+        if (!mBooleanFlagCache.containsKey(id)) {
+            mBooleanFlagCache.put(
+                    id, mSystemProperties.getBoolean(flag.getName(), flag.getDefault()));
+        }
+
+        return mBooleanFlagCache.get(id);
+    }
+
     @NonNull
     @Override
     public String getString(@NonNull StringFlag flag) {
@@ -180,16 +195,28 @@
         mSecureSettings.putString(mFlagManager.idToSettingsKey(id), data);
         Log.i(TAG, "Set id " + id + " to " + value);
         removeFromCache(id);
-        mFlagManager.dispatchListenersAndMaybeRestart(id);
+        mFlagManager.dispatchListenersAndMaybeRestart(id, this::restartSystemUI);
+    }
+
+    private <T> void eraseFlag(Flag<T> flag) {
+        if (flag instanceof SysPropFlag) {
+            mSystemProperties.erase(((SysPropFlag<T>) flag).getName());
+            dispatchListenersAndMaybeRestart(flag.getId(), this::restartAndroid);
+        } else {
+            eraseFlag(flag.getId());
+        }
     }
 
     /** Erase a flag's overridden value if there is one. */
-    public void eraseFlag(int id) {
+    private void eraseFlag(int id) {
         eraseInternal(id);
         removeFromCache(id);
-        mFlagManager.dispatchListenersAndMaybeRestart(id);
+        dispatchListenersAndMaybeRestart(id, this::restartSystemUI);
     }
 
+    private void dispatchListenersAndMaybeRestart(int id, Consumer<Boolean> restartAction) {
+        mFlagManager.dispatchListenersAndMaybeRestart(id, restartAction);
+    }
     /** Works just like {@link #eraseFlag(int)} except that it doesn't restart SystemUI. */
     private void eraseInternal(int id) {
         // We can't actually "erase" things from sysprops, but we can set them to empty!
@@ -217,7 +244,11 @@
         System.exit(0);
     }
 
-    private void restartAndroid() {
+    private void restartAndroid(boolean requestSuppress) {
+        if (requestSuppress) {
+            Log.i(TAG, "Android Restart Suppressed");
+            return;
+        }
         Log.i(TAG, "Restarting Android");
         try {
             mBarService.restart();
@@ -273,7 +304,7 @@
             Flag<?> flag = flagMap.get(id);
 
             if (!extras.containsKey(EXTRA_VALUE)) {
-                eraseFlag(id);
+                eraseFlag(flag);
                 return;
             }
 
@@ -282,6 +313,12 @@
                 setFlagValue(id, (Boolean) value, BooleanFlagSerializer.INSTANCE);
             } else  if (flag instanceof ResourceBooleanFlag && value instanceof Boolean) {
                 setFlagValue(id, (Boolean) value, BooleanFlagSerializer.INSTANCE);
+            } else  if (flag instanceof SysPropBooleanFlag && value instanceof Boolean) {
+                // Store SysProp flags in SystemProperties where they can read by outside parties.
+                mSystemProperties.setBoolean(
+                        ((SysPropBooleanFlag) flag).getName(), (Boolean) value);
+                dispatchListenersAndMaybeRestart(flag.getId(),
+                        FeatureFlagsDebug.this::restartAndroid);
             } else if (flag instanceof StringFlag && value instanceof String) {
                 setFlagValue(id, (String) value, StringFlagSerializer.INSTANCE);
             } else if (flag instanceof ResourceStringFlag && value instanceof String) {
@@ -306,6 +343,9 @@
             if (f instanceof ResourceBooleanFlag) {
                 return new BooleanFlag(f.getId(), isEnabled((ResourceBooleanFlag) f));
             }
+            if (f instanceof SysPropBooleanFlag) {
+                return new BooleanFlag(f.getId(), isEnabled((SysPropBooleanFlag) f));
+            }
 
             // TODO: add support for other flag types.
             Log.w(TAG, "Unsupported Flag Type. Please file a bug.");
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
index 348a8e2..1023b11 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
@@ -31,6 +31,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Map;
 
 import javax.inject.Inject;
 
@@ -43,11 +44,17 @@
 @SysUISingleton
 public class FeatureFlagsRelease implements FeatureFlags, Dumpable {
     private final Resources mResources;
+    private final SystemPropertiesHelper mSystemProperties;
     SparseBooleanArray mBooleanCache = new SparseBooleanArray();
     SparseArray<String> mStringCache = new SparseArray<>();
+
     @Inject
-    public FeatureFlagsRelease(@Main Resources resources, DumpManager dumpManager) {
+    public FeatureFlagsRelease(
+            @Main Resources resources,
+            SystemPropertiesHelper systemProperties,
+            DumpManager dumpManager) {
         mResources = resources;
+        mSystemProperties = systemProperties;
         dumpManager.registerDumpable("SysUIFlags", this);
     }
 
@@ -59,7 +66,7 @@
 
     @Override
     public boolean isEnabled(BooleanFlag flag) {
-        return isEnabled(flag.getId(), flag.getDefault());
+        return flag.getDefault();
     }
 
     @Override
@@ -72,6 +79,17 @@
         return mBooleanCache.valueAt(cacheIndex);
     }
 
+    @Override
+    public boolean isEnabled(SysPropBooleanFlag flag) {
+        int cacheIndex = mBooleanCache.indexOfKey(flag.getId());
+        if (cacheIndex < 0) {
+            return isEnabled(
+                    flag.getId(), mSystemProperties.getBoolean(flag.getName(), flag.getDefault()));
+        }
+
+        return mBooleanCache.valueAt(cacheIndex);
+    }
+
     private boolean isEnabled(int key, boolean defaultValue) {
         mBooleanCache.append(key, defaultValue);
         return defaultValue;
@@ -103,10 +121,24 @@
     @Override
     public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
         pw.println("can override: false");
-        int numBooleans = mBooleanCache.size();
-        pw.println("booleans: " + numBooleans);
-        for (int i = 0; i < numBooleans; i++) {
-            pw.println("  sysui_flag_" + mBooleanCache.keyAt(i) + ": " + mBooleanCache.valueAt(i));
+        Map<Integer, Flag<?>> knownFlags = Flags.collectFlags();
+        for (Map.Entry<Integer, Flag<?>> idToFlag : knownFlags.entrySet()) {
+            int id = idToFlag.getKey();
+            Flag<?> flag = idToFlag.getValue();
+            boolean def = false;
+            if (mBooleanCache.indexOfKey(flag.getId()) < 0) {
+                if (flag instanceof SysPropBooleanFlag) {
+                    SysPropBooleanFlag f = (SysPropBooleanFlag) flag;
+                    def = mSystemProperties.getBoolean(f.getName(), f.getDefault());
+                } else if (flag instanceof ResourceBooleanFlag) {
+                    ResourceBooleanFlag f = (ResourceBooleanFlag) flag;
+                    def = mResources.getBoolean(f.getResourceId());
+                } else if (flag instanceof BooleanFlag) {
+                    BooleanFlag f = (BooleanFlag) flag;
+                    def = f.getDefault();
+                }
+            }
+            pw.println("  sysui_flag_" + id + ": " + (mBooleanCache.get(id, def)));
         }
         int numStrings = mStringCache.size();
         pw.println("Strings: " + numStrings);
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 5487c42..b590412 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -153,6 +153,9 @@
     public static final BooleanFlag SIMULATE_DOCK_THROUGH_CHARGING =
             new BooleanFlag(1000, true);
 
+    // 1100 - windowing
+    public static final SysPropBooleanFlag WM_ENABLE_SHELL_TRANSITIONS =
+            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/flags/SystemPropertiesHelper.kt b/packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
index 1dc5a9f..6c16097 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
@@ -34,6 +34,10 @@
         return SystemProperties.getBoolean(name, default)
     }
 
+    fun setBoolean(name: String, value: Boolean) {
+        SystemProperties.set(name, if (value) "1" else "0")
+    }
+
     fun set(name: String, value: String) {
         SystemProperties.set(name, value)
     }
@@ -41,4 +45,8 @@
     fun set(name: String, value: Int) {
         set(name, value.toString())
     }
+
+    fun erase(name: String) {
+        set(name, "")
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index e746caf..74d5bd5 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -33,7 +33,7 @@
 import javax.inject.Provider;
 
 /**
- * Manages power menu plugins and communicates power menu actions to the StatusBar.
+ * Manages power menu plugins and communicates power menu actions to the CentralSurfaces.
  */
 @SysUISingleton
 public class GlobalActionsComponent extends CoreStartable
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index e3886cd..af553c7 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -121,7 +121,7 @@
 import com.android.systemui.scrim.ScrimDrawable;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -236,7 +236,7 @@
     private int mDialogPressDelay = DIALOG_PRESS_DELAY; // ms
     protected Handler mMainHandler;
     private int mSmallestScreenWidthDp;
-    private final Optional<StatusBar> mStatusBarOptional;
+    private final Optional<CentralSurfaces> mCentralSurfacesOptional;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final DialogLaunchAnimator mDialogLaunchAnimator;
 
@@ -344,7 +344,7 @@
             RingerModeTracker ringerModeTracker,
             @Main Handler handler,
             PackageManager packageManager,
-            Optional<StatusBar> statusBarOptional,
+            Optional<CentralSurfaces> centralSurfacesOptional,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             DialogLaunchAnimator dialogLaunchAnimator) {
         mContext = context;
@@ -374,7 +374,7 @@
         mRingerModeTracker = ringerModeTracker;
         mMainHandler = handler;
         mSmallestScreenWidthDp = resources.getConfiguration().smallestScreenWidthDp;
-        mStatusBarOptional = statusBarOptional;
+        mCentralSurfacesOptional = centralSurfacesOptional;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mDialogLaunchAnimator = dialogLaunchAnimator;
 
@@ -426,8 +426,8 @@
         return mUiEventLogger;
     }
 
-    protected Optional<StatusBar> getStatusBar() {
-        return mStatusBarOptional;
+    protected Optional<CentralSurfaces> getCentralSurfaces() {
+        return mCentralSurfacesOptional;
     }
 
     protected KeyguardUpdateMonitor getKeyguardUpdateMonitor() {
@@ -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);
             }
@@ -675,7 +677,7 @@
                 com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActionsLite,
                 mAdapter, mOverflowAdapter, mSysuiColorExtractor, mStatusBarService,
                 mNotificationShadeWindowController, this::onRefresh, mKeyguardShowing,
-                mPowerAdapter, mUiEventLogger, mStatusBarOptional, mKeyguardUpdateMonitor,
+                mPowerAdapter, mUiEventLogger, mCentralSurfacesOptional, mKeyguardUpdateMonitor,
                 mLockPatternUtils);
 
         dialog.setOnDismissListener(this);
@@ -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());
@@ -866,7 +874,7 @@
             mUiEventLogger.log(GlobalActionsEvent.GA_EMERGENCY_DIALER_PRESS);
             if (mTelecomManager != null) {
                 // Close shade so user sees the activity
-                mStatusBarOptional.ifPresent(StatusBar::collapseShade);
+                mCentralSurfacesOptional.ifPresent(CentralSurfaces::collapseShade);
                 Intent intent = mTelecomManager.createLaunchEmergencyDialerIntent(
                         null /* number */);
                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
@@ -998,7 +1006,7 @@
                             mIActivityManager.requestInteractiveBugReport();
                         }
                         // Close shade so user sees the activity
-                        mStatusBarOptional.ifPresent(StatusBar::collapseShade);
+                        mCentralSurfacesOptional.ifPresent(CentralSurfaces::collapseShade);
                     } catch (RemoteException e) {
                     }
                 }
@@ -1018,7 +1026,7 @@
                 mUiEventLogger.log(GlobalActionsEvent.GA_BUGREPORT_LONG_PRESS);
                 mIActivityManager.requestFullBugReport();
                 // Close shade so user sees the activity
-                mStatusBarOptional.ifPresent(StatusBar::collapseShade);
+                mCentralSurfacesOptional.ifPresent(CentralSurfaces::collapseShade);
             } catch (RemoteException e) {
             }
             return false;
@@ -2160,7 +2168,7 @@
         protected final Runnable mOnRefreshCallback;
         private UiEventLogger mUiEventLogger;
         private GestureDetector mGestureDetector;
-        private Optional<StatusBar> mStatusBarOptional;
+        private Optional<CentralSurfaces> mCentralSurfacesOptional;
         private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
         private LockPatternUtils mLockPatternUtils;
         private float mWindowDimAmount;
@@ -2188,8 +2196,8 @@
                     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                             float distanceY) {
                         if (distanceY < 0 && distanceY > distanceX
-                                && e1.getY() <= mStatusBarOptional.map(
-                                        StatusBar::getStatusBarHeight).orElse(0)) {
+                                && e1.getY() <= mCentralSurfacesOptional.map(
+                                        CentralSurfaces::getStatusBarHeight).orElse(0)) {
                             // Downwards scroll from top
                             openShadeAndDismiss();
                             return true;
@@ -2201,8 +2209,8 @@
                     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                             float velocityY) {
                         if (velocityY > 0 && Math.abs(velocityY) > Math.abs(velocityX)
-                                && e1.getY() <= mStatusBarOptional.map(
-                                        StatusBar::getStatusBarHeight).orElse(0)) {
+                                && e1.getY() <= mCentralSurfacesOptional.map(
+                                        CentralSurfaces::getStatusBarHeight).orElse(0)) {
                             // Downwards fling from top
                             openShadeAndDismiss();
                             return true;
@@ -2217,7 +2225,8 @@
                 NotificationShadeWindowController notificationShadeWindowController,
                 Runnable onRefreshCallback, boolean keyguardShowing,
                 MyPowerOptionsAdapter powerAdapter, UiEventLogger uiEventLogger,
-                Optional<StatusBar> statusBarOptional, KeyguardUpdateMonitor keyguardUpdateMonitor,
+                Optional<CentralSurfaces> centralSurfacesOptional,
+                KeyguardUpdateMonitor keyguardUpdateMonitor,
                 LockPatternUtils lockPatternUtils) {
             // We set dismissOnDeviceLock to false because we have a custom broadcast receiver to
             // dismiss this dialog when the device is locked.
@@ -2232,7 +2241,7 @@
             mOnRefreshCallback = onRefreshCallback;
             mKeyguardShowing = keyguardShowing;
             mUiEventLogger = uiEventLogger;
-            mStatusBarOptional = statusBarOptional;
+            mCentralSurfacesOptional = centralSurfacesOptional;
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
             mLockPatternUtils = lockPatternUtils;
             mGestureDetector = new GestureDetector(mContext, mGestureListener);
@@ -2262,14 +2271,14 @@
 
         private void openShadeAndDismiss() {
             mUiEventLogger.log(GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
-            if (mStatusBarOptional.map(StatusBar::isKeyguardShowing).orElse(false)) {
+            if (mCentralSurfacesOptional.map(CentralSurfaces::isKeyguardShowing).orElse(false)) {
                 // match existing lockscreen behavior to open QS when swiping from status bar
-                mStatusBarOptional.ifPresent(
-                        statusBar -> statusBar.animateExpandSettingsPanel(null));
+                mCentralSurfacesOptional.ifPresent(
+                        centralSurfaces -> centralSurfaces.animateExpandSettingsPanel(null));
             } else {
                 // otherwise, swiping down should expand notification shade
-                mStatusBarOptional.ifPresent(
-                        statusBar -> statusBar.animateExpandNotificationsPanel());
+                mCentralSurfacesOptional.ifPresent(
+                        centralSurfaces -> centralSurfaces.animateExpandNotificationsPanel());
             }
             dismiss();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
index 32b58c2..822b1cf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
@@ -18,8 +18,8 @@
 
 import android.os.Handler;
 import android.os.Message;
-import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.Trace;
 import android.util.Log;
 
 import com.android.internal.policy.IKeyguardDrawnCallback;
@@ -83,6 +83,11 @@
             final Object obj = msg.obj;
             switch (msg.what) {
                 case SCREEN_TURNING_ON:
+                    Trace.beginSection("KeyguardLifecyclesDispatcher#SCREEN_TURNING_ON");
+                    final String onDrawWaitingTraceTag =
+                            "Waiting for KeyguardDrawnCallback#onDrawn";
+                    int traceCookie = System.identityHashCode(msg);
+                    Trace.beginAsyncSection(onDrawWaitingTraceTag, traceCookie);
                     // Ensure the drawn callback is only ever called once
                     mScreenLifecycle.dispatchScreenTurningOn(new Runnable() {
                             boolean mInvoked;
@@ -92,6 +97,7 @@
                                 if (!mInvoked) {
                                     mInvoked = true;
                                     try {
+                                        Trace.endAsyncSection(onDrawWaitingTraceTag, traceCookie);
                                         ((IKeyguardDrawnCallback) obj).onDrawn();
                                     } catch (RemoteException e) {
                                         Log.w(TAG, "Exception calling onDrawn():", e);
@@ -101,6 +107,7 @@
                                 }
                             }
                         });
+                    Trace.endSection();
                     break;
                 case SCREEN_TURNED_ON:
                     mScreenLifecycle.dispatchScreenTurnedOn();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
index 582965a..35f29b9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
@@ -23,6 +23,7 @@
 import android.graphics.Matrix
 import android.graphics.Rect
 import android.os.Handler
+import android.util.Log
 import android.view.RemoteAnimationTarget
 import android.view.SyncRtSurfaceTransactionApplier
 import android.view.View
@@ -47,6 +48,8 @@
 import javax.inject.Inject
 import kotlin.math.min
 
+const val TAG = "KeyguardUnlock"
+
 /**
  * Starting scale factor for the app/launcher surface behind the keyguard, when it's animating
  * in during keyguard exit.
@@ -584,8 +587,16 @@
      * animation.
      */
     fun hideKeyguardViewAfterRemoteAnimation() {
-        // Hide the keyguard, with no fade out since we animated it away during the unlock.
-        keyguardViewController.hide(surfaceBehindRemoteAnimationStartTime, 0 /* fadeOutDuration */)
+        if (keyguardViewController.isShowing) {
+            // Hide the keyguard, with no fade out since we animated it away during the unlock.
+            keyguardViewController.hide(
+                surfaceBehindRemoteAnimationStartTime,
+                0 /* fadeOutDuration */
+            )
+        } else {
+            Log.e(TAG, "#hideKeyguardViewAfterRemoteAnimation called when keyguard view is not " +
+                    "showing. Ignoring...")
+        }
     }
 
     private fun applyParamsToSurface(params: SyncRtSurfaceTransactionApplier.SurfaceParams) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index ae7147e..c01d2c3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -127,7 +127,7 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -1667,11 +1667,16 @@
             return;
         }
 
-        // if the keyguard is already showing, don't bother. check flags in both files
-        // to account for the hiding animation which results in a delay and discrepancy
-        // between flags
-        if (mShowing && mKeyguardViewControllerLazy.get().isShowing()) {
-            if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing");
+        // If the keyguard is already showing, don't bother unless it was in the process of going
+        // away. If it was going away, keyguard state may be out of sync and we should make sure to
+        // re-show it explicitly. Check flags in both files to account for the hiding animation
+        // which results in a delay and discrepancy between flags.
+        if ((mShowing && mKeyguardViewControllerLazy.get().isShowing())
+                && !mKeyguardStateController.isKeyguardGoingAway()) {
+            if (DEBUG) {
+                Log.d(TAG, "doKeyguard: not showing "
+                        + "because it is already showing and not going away");
+            }
             resetStateLocked();
             return;
         }
@@ -2186,7 +2191,14 @@
             mKeyguardExitAnimationRunner = null;
             mScreenOnCoordinator.setWakeAndUnlocking(false);
             mPendingLock = false;
-            setShowingLocked(true);
+
+            // If we're asked to re-show while the keyguard is going away, force callbacks to ensure
+            // that state is re-set correctly. Otherwise, we might short circuit since mShowing is
+            // true during the keyguard going away process, despite having partially set some state
+            // to unlocked.
+            setShowingLocked(
+                    true, mKeyguardStateController.isKeyguardGoingAway() /* forceCallbacks */);
+
             mKeyguardViewControllerLazy.get().show(options);
             resetKeyguardDonePendingLocked();
             mHideAnimationRun = false;
@@ -2356,14 +2368,28 @@
                             @Override
                             public void onAnimationFinished() throws RemoteException {
                                 try {
+                                    // WindowManager always needs to know that this animation
+                                    // finished so it does not wait the 10s until timeout.
                                     finishedCallback.onAnimationFinished();
                                 } catch (RemoteException e) {
                                     Slog.w(TAG, "Failed to call onAnimationFinished", e);
                                 }
-                                onKeyguardExitFinished();
-                                mKeyguardViewControllerLazy.get().hide(0 /* startTime */,
-                                        0 /* fadeoutDuration */);
-                                mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
+
+                                // If we're not interactive, it means the device is going back to
+                                // sleep. This happens if the power button is pressed during the
+                                // activity launch. If we're going back to sleep, we should *not*
+                                // run keyguard exit finished callbacks and hide the keyguard, since
+                                // we are in the process of locking again and this might result in
+                                // the device staying unlocked when it shouldn't.
+                                // We need to directly query isInteractive rather than mGoingToSleep
+                                // because mGoingToSleep is set in onStartedGoingToSleep, which is
+                                // dispatched asynchronously.
+                                if (mPM.isInteractive()) {
+                                    onKeyguardExitFinished();
+                                    mKeyguardViewControllerLazy.get().hide(0 /* startTime */,
+                                            0 /* fadeoutDuration */);
+                                    mInteractionJankMonitor.end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
+                                }
                             }
 
                             @Override
@@ -2717,22 +2743,22 @@
     }
 
     /**
-     * Registers the StatusBar to which the Keyguard View is mounted.
+     * Registers the CentralSurfaces to which the Keyguard View is mounted.
      *
-     * @param statusBar
+     * @param centralSurfaces
      * @param panelView
      * @param biometricUnlockController
      * @param notificationContainer
      * @param bypassController
      * @return the View Controller for the Keyguard View this class is mediating.
      */
-    public KeyguardViewController registerStatusBar(StatusBar statusBar,
+    public KeyguardViewController registerCentralSurfaces(CentralSurfaces centralSurfaces,
             NotificationPanelViewController panelView,
             @Nullable PanelExpansionStateManager panelExpansionStateManager,
             BiometricUnlockController biometricUnlockController,
             View notificationContainer, KeyguardBypassController bypassController) {
-        mKeyguardViewControllerLazy.get().registerStatusBar(
-                statusBar,
+        mKeyguardViewControllerLazy.get().registerCentralSurfaces(
+                centralSurfaces,
                 panelView,
                 panelExpansionStateManager,
                 biometricUnlockController,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
index 195ef1a..c69f947 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java
@@ -48,10 +48,10 @@
 import com.android.systemui.statusbar.NotificationShadeDepthController;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.statusbar.phone.KeyguardLiftController;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.util.DeviceConfigProxy;
@@ -64,7 +64,7 @@
 import dagger.Provides;
 
 /**
- * Dagger Module providing {@link StatusBar}.
+ * Dagger Module providing keyguard.
  */
 @Module(subcomponents = {
         KeyguardQsUserSwitchComponent.class,
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index b323586..ae7a671 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -154,6 +154,28 @@
         return factory.create("SwipeStatusBarAwayLog", 30);
     }
 
+    /**
+     * Provides a logging buffer for logs related to the media tap-to-transfer chip on the sender
+     * device. See {@link com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger}.
+     */
+    @Provides
+    @SysUISingleton
+    @MediaTttSenderLogBuffer
+    public static LogBuffer provideMediaTttSenderLogBuffer(LogBufferFactory factory) {
+        return factory.create("MediaTttSender", 20);
+    }
+
+    /**
+     * Provides a logging buffer for logs related to the media tap-to-transfer chip on the receiver
+     * device. See {@link com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger}.
+     */
+    @Provides
+    @SysUISingleton
+    @MediaTttReceiverLogBuffer
+    public static LogBuffer provideMediaTttReceiverLogBuffer(LogBufferFactory factory) {
+        return factory.create("MediaTttReceiver", 20);
+    }
+
     /** Allows logging buffers to be tweaked via adb on debug builds but not on prod builds. */
     @Provides
     @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTttReceiverLogBuffer.java b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTttReceiverLogBuffer.java
new file mode 100644
index 0000000..5c572e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTttReceiverLogBuffer.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * A {@link LogBuffer} for
+ * {@link com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger}.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface MediaTttReceiverLogBuffer {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTttSenderLogBuffer.java b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTttSenderLogBuffer.java
new file mode 100644
index 0000000..edab8c3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/MediaTttSenderLogBuffer.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/**
+ * A {@link LogBuffer} for
+ * {@link com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger}.
+ */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface MediaTttSenderLogBuffer {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 7b85050..fab06c2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -550,13 +550,13 @@
 
         // Album art
         val notif: Notification = sbn.notification
-        var artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ART)
+        var artworkBitmap = metadata?.let { loadBitmapFromUri(it) }
+        if (artworkBitmap == null) {
+            artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ART)
+        }
         if (artworkBitmap == null) {
             artworkBitmap = metadata?.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
         }
-        if (artworkBitmap == null && metadata != null) {
-            artworkBitmap = loadBitmapFromUri(metadata)
-        }
         val artWorkIcon = if (artworkBitmap == null) {
             notif.getLargeIcon()
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index eee3955..18b6699 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -741,10 +741,11 @@
      * Updates the bounds that the view wants to be in at the end of the animation.
      */
     private fun updateTargetState() {
-        if (isCurrentlyInGuidedTransformation() && !isCurrentlyFading()) {
+        var starthost = getHost(previousLocation)
+        var endHost = getHost(desiredLocation)
+        if (isCurrentlyInGuidedTransformation() && !isCurrentlyFading() && starthost != null &&
+            endHost != null) {
             val progress = getTransformationProgress()
-            var endHost = getHost(desiredLocation)!!
-            var starthost = getHost(previousLocation)!!
             // If either of the hosts are invisible, let's keep them at the other host location to
             // have a nicer disappear animation. Otherwise the currentBounds of the state might
             // be undefined
@@ -756,8 +757,8 @@
             val newBounds = endHost.currentBounds
             val previousBounds = starthost.currentBounds
             targetBounds = interpolateBounds(previousBounds, newBounds, progress)
-        } else {
-            val bounds = getHost(desiredLocation)?.currentBounds ?: return
+        } else if (endHost != null) {
+            val bounds = endHost.currentBounds
             targetBounds.set(bounds)
         }
     }
@@ -785,7 +786,11 @@
      * @return true if this transformation is guided by an external progress like a finger
      */
     private fun isCurrentlyInGuidedTransformation(): Boolean {
-        return getTransformationProgress() >= 0
+        return hasValidStartAndEndLocations() && getTransformationProgress() >= 0
+    }
+
+    private fun hasValidStartAndEndLocations(): Boolean {
+        return previousLocation != -1 && desiredLocation != -1
     }
 
     /**
@@ -795,6 +800,9 @@
     @TransformationType
     fun calculateTransformationType(): Int {
         if (isTransitioningToFullShade) {
+            if (inSplitShade) {
+                return TRANSFORMATION_TYPE_TRANSITION
+            }
             return TRANSFORMATION_TYPE_FADE
         }
         if (previousLocation == LOCATION_LOCKSCREEN && desiredLocation == LOCATION_QS ||
@@ -961,6 +969,7 @@
             (qsExpansion > 0.0f || inSplitShade) && !onLockscreen -> LOCATION_QS
             qsExpansion > 0.4f && onLockscreen -> LOCATION_QS
             !hasActiveMedia -> LOCATION_QS
+            onLockscreen && isSplitShadeExpanding() -> LOCATION_QS
             onLockscreen && isTransformingToFullShadeAndInQQS() -> LOCATION_QQS
             onLockscreen && allowedOnLockscreen -> LOCATION_LOCKSCREEN
             else -> LOCATION_QQS
@@ -986,6 +995,10 @@
         return location
     }
 
+    private fun isSplitShadeExpanding(): Boolean {
+        return inSplitShade && isTransitioningToFullShade
+    }
+
     /**
      * Are we currently transforming to the full shade and already in QQS
      */
@@ -993,6 +1006,10 @@
         if (!isTransitioningToFullShade) {
             return false
         }
+        if (inSplitShade) {
+            // Split shade doesn't use QQS.
+            return false
+        }
         return fullShadeTransitionProgress > 0.5f
     }
 
@@ -1000,6 +1017,10 @@
      * Is the current transformationType fading
      */
     private fun isCurrentlyFading(): Boolean {
+        if (isSplitShadeExpanding()) {
+            // Split shade always uses transition instead of fade.
+            return false
+        }
         if (isTransitioningToFullShade) {
             return true
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index e2716e9..77873e8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -38,12 +38,10 @@
 import android.text.TextUtils;
 import android.text.style.StyleSpan;
 import android.util.Log;
-import android.view.View;
 import android.view.Window;
-import android.view.WindowManager;
-import android.widget.TextView;
 
 import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.util.Utils;
 
 public class MediaProjectionPermissionActivity extends Activity
@@ -56,7 +54,7 @@
     private int mUid;
     private IMediaProjectionManager mService;
 
-    private AlertDialog mDialog;
+    private SystemUIDialog mDialog;
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -143,25 +141,18 @@
             dialogTitle = getString(R.string.media_projection_dialog_title, appName);
         }
 
-        View dialogTitleView = View.inflate(this, R.layout.media_projection_dialog_title, null);
-        TextView titleText = (TextView) dialogTitleView.findViewById(R.id.dialog_title);
-        titleText.setText(dialogTitle);
-
-        mDialog = new AlertDialog.Builder(this)
-                .setCustomTitle(dialogTitleView)
-                .setMessage(dialogText)
-                .setPositiveButton(R.string.media_projection_action_text, this)
-                .setNegativeButton(android.R.string.cancel, this)
-                .setOnCancelListener(this)
-                .create();
+        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.create();
         mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
 
         final Window w = mDialog.getWindow();
-        // QS is not closed when pressing CastTile. Match the type of the dialog shown from the
-        // tile.
-        w.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
         w.addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
 
         mDialog.show();
diff --git a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
index c3b4354..66c036c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dagger/MediaModule.java
@@ -17,6 +17,9 @@
 package com.android.systemui.media.dagger;
 
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.log.LogBuffer;
+import com.android.systemui.log.dagger.MediaTttReceiverLogBuffer;
+import com.android.systemui.log.dagger.MediaTttSenderLogBuffer;
 import com.android.systemui.media.MediaDataManager;
 import com.android.systemui.media.MediaFlags;
 import com.android.systemui.media.MediaHierarchyManager;
@@ -27,8 +30,11 @@
 import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
 import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper;
 import com.android.systemui.media.taptotransfer.MediaTttFlags;
+import com.android.systemui.media.taptotransfer.common.MediaTttLogger;
 import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver;
+import com.android.systemui.media.taptotransfer.receiver.MediaTttReceiverLogger;
 import com.android.systemui.media.taptotransfer.sender.MediaTttChipControllerSender;
+import com.android.systemui.media.taptotransfer.sender.MediaTttSenderLogger;
 
 import java.util.Optional;
 
@@ -112,6 +118,24 @@
         return Optional.of(controllerReceiverLazy.get());
     }
 
+    @Provides
+    @SysUISingleton
+    @MediaTttSenderLogger
+    static MediaTttLogger providesMediaTttSenderLogger(
+            @MediaTttSenderLogBuffer LogBuffer buffer
+    ) {
+        return new MediaTttLogger("Sender", buffer);
+    }
+
+    @Provides
+    @SysUISingleton
+    @MediaTttReceiverLogger
+    static MediaTttLogger providesMediaTttReceiverLogger(
+            @MediaTttReceiverLogBuffer LogBuffer buffer
+    ) {
+        return new MediaTttLogger("Receiver", buffer);
+    }
+
     /** */
     @Provides
     @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 3cd3905..0b23ad5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -54,6 +54,7 @@
             MediaOutputDialog mediaOutputDialog) {
         super(controller);
         mMediaOutputDialog = mediaOutputDialog;
+        setHasStableIds(true);
     }
 
     @Override
@@ -79,6 +80,20 @@
     }
 
     @Override
+    public long getItemId(int position) {
+        final int size = mController.getMediaDevices().size();
+        if (position == size && mController.isZeroMode()) {
+            return -1;
+        } else if (position < size) {
+            return ((List<MediaDevice>) (mController.getMediaDevices()))
+                    .get(position).getId().hashCode();
+        } else if (DEBUG) {
+            Log.d(TAG, "Incorrect position for item id: " + position);
+        }
+        return position;
+    }
+
+    @Override
     public int getItemCount() {
         if (mController.isZeroMode()) {
             // Add extra one for "pair new" or dynamic group
@@ -159,7 +174,7 @@
                         onCheckBoxClicked(false, device);
                     });
                     setCheckBoxColor(mCheckBox, mController.getColorActiveItem());
-                    initSessionSeekbar();
+                    initSeekbar(device);
                 } else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) {
                     mStatusIcon.setImageDrawable(
                             mContext.getDrawable(R.drawable.media_output_status_check));
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 1f11d0c..c96aca3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -249,7 +249,7 @@
             mSeekBar.setMin(0);
             final int currentVolume = device.getCurrentVolume();
             if (mSeekBar.getProgress() != currentVolume) {
-                mSeekBar.setProgress(currentVolume);
+                mSeekBar.setProgress(currentVolume, true);
             }
             mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                 @Override
@@ -278,7 +278,7 @@
             mSeekBar.setMin(0);
             final int currentVolume = mController.getSessionVolume();
             if (mSeekBar.getProgress() != currentVolume) {
-                mSeekBar.setProgress(currentVolume);
+                mSeekBar.setProgress(currentVolume, true);
             }
             mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                 @Override
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..355c69f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -211,10 +211,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 e929b5e..0c202e0 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;
@@ -61,6 +65,7 @@
 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;
@@ -70,6 +75,9 @@
 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 +85,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);
@@ -92,10 +101,11 @@
     private final DialogLaunchAnimator mDialogLaunchAnimator;
     private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>();
     private final boolean mAboveStatusbar;
-    private final boolean mVolumeAdjustmentForRemoteGroupSessions;
     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
@@ -117,7 +127,8 @@
             boolean aboveStatusbar, MediaSessionManager mediaSessionManager, LocalBluetoothManager
             lbm, ShadeController shadeController, ActivityStarter starter,
             CommonNotifCollection notifCollection, UiEventLogger uiEventLogger,
-            DialogLaunchAnimator dialogLaunchAnimator) {
+            DialogLaunchAnimator dialogLaunchAnimator,
+            Optional<NearbyMediaDevicesManager> nearbyMediaDevicesManagerOptional) {
         mContext = context;
         mPackageName = packageName;
         mMediaSessionManager = mediaSessionManager;
@@ -131,8 +142,7 @@
         mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
         mUiEventLogger = uiEventLogger;
         mDialogLaunchAnimator = dialogLaunchAnimator;
-        mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
+        mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
         mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
                 R.color.media_dialog_active_item_main_content);
         mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
@@ -147,6 +157,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)) {
@@ -190,6 +204,10 @@
             mLocalMediaManager.stopScan();
         }
         mMediaDevices.clear();
+        if (mNearbyMediaDevicesManager != null) {
+            mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
+        }
+        mNearbyDeviceInfoMap.clear();
     }
 
     @Override
@@ -420,6 +438,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() {
@@ -607,7 +634,9 @@
         // We show the output group dialog from the output dialog.
         MediaOutputController controller = new MediaOutputController(mContext, mPackageName,
                 mAboveStatusbar, mMediaSessionManager, mLocalBluetoothManager, mShadeController,
-                mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+                mActivityStarter, mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
+
         MediaOutputGroupDialog dialog = new MediaOutputGroupDialog(mContext, mAboveStatusbar,
                 controller);
         mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog);
@@ -621,10 +650,29 @@
                 || features.contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK));
     }
 
+    private boolean isPlayBackInfoLocal() {
+        return mMediaController.getPlaybackInfo() != null
+                && mMediaController.getPlaybackInfo().getPlaybackType()
+                == MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL;
+    }
+
     boolean isVolumeControlEnabled(@NonNull MediaDevice device) {
-        // TODO(b/202500642): Also enable volume control for remote non-group sessions.
-        return !isActiveRemoteDevice(device)
-            || mVolumeAdjustmentForRemoteGroupSessions;
+        return isPlayBackInfoLocal()
+                || 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() {
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..a7e5480 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.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
 
 /**
@@ -38,7 +40,8 @@
     private val starter: ActivityStarter,
     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
@@ -50,8 +53,8 @@
         mediaOutputDialog?.dismiss()
 
         val controller = MediaOutputController(context, packageName, aboveStatusBar,
-            mediaSessionManager, lbm, shadeController, starter, notifCollection,
-            uiEventLogger, dialogLaunchAnimator)
+                mediaSessionManager, lbm, shadeController, starter, notifCollection,
+                uiEventLogger, dialogLaunchAnimator, nearbyMediaDevicesManagerOptional)
         val dialog = MediaOutputDialog(context, aboveStatusBar, controller, uiEventLogger)
         mediaOutputDialog = dialog
 
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/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
new file mode 100644
index 0000000..3cc99a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
@@ -0,0 +1,30 @@
+/*
+ * 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
+
+/**
+ * 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 ee2fba0..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,17 +19,24 @@
 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
+import com.android.systemui.statusbar.gesture.TapGestureDetector
 import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.view.ViewUtil
 
 /**
  * A superclass controller that provides common functionality for showing chips on the sender device
@@ -37,11 +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. */
@@ -58,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.
@@ -69,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
@@ -78,43 +92,67 @@
         }
         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(this::removeChip, TIMEOUT_MILLIS)
-    }
-
-    /** Hides the chip. */
-    fun removeChip() {
-        // TODO(b/203800347): We may not want to hide the chip if we're currently in a
-        //  TransferTriggered state: Once the user has initiated the transfer, they should be able
-        //  to move away from the receiver device but still see the status of the transfer.
-        if (chipView == null) { return }
-        windowManager.removeView(chipView)
-        chipView = null
+        cancelChipViewTimeout = mainExecutor.executeDelayed(
+            { removeChip(MediaTttRemovalReason.REASON_TIMEOUT) },
+            chipInfo.getTimeoutMs()
+        )
     }
 
     /**
-     * A method implemented by subclasses to update [currentChipView] based on [chipState].
+     * Hides the chip.
+     *
+     * @param removalReason a short string describing why the chip was removed (timeout, state
+     *     change, etc.)
      */
-    abstract fun updateChipView(chipState: T, currentChipView: ViewGroup)
+    open fun removeChip(removalReason: String) {
+        if (chipView == null) { return }
+        logger.logChipRemoval(removalReason)
+        tapGestureDetector.removeOnGestureDetectedCallback(TAG)
+        windowManager.removeView(chipView)
+        chipView = null
+        // No need to time the chip out since it's already gone
+        cancelChipViewTimeout?.run()
+    }
+
+    /**
+     * A method implemented by subclasses to update [currentChipView] based on [chipInfo].
+     */
+    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 {
@@ -123,10 +161,47 @@
         appIconView.setImageDrawable(appIcon)
         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
+        // chip is tappable).
+        if (!viewUtil.touchIsWithinView(view, e.x, e.y)) {
+            removeChip(MediaTttRemovalReason.REASON_SCREEN_TAP)
+        }
+    }
 }
 
 // Used in CTS tests UpdateMediaTapToTransferSenderDisplayTest and
 // UpdateMediaTapToTransferReceiverDisplayTest
 private const val WINDOW_TITLE = "Media Transfer Chip View"
-@VisibleForTesting
-const val TIMEOUT_MILLIS = 3000L
+private val TAG = MediaTttChipControllerCommon::class.simpleName!!
+
+object MediaTttRemovalReason {
+    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 2da48ce..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipState.kt
+++ /dev/null
@@ -1,57 +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
-        }
-    }
-}
-
-private val TAG = MediaTttChipState::class.simpleName!!
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
new file mode 100644
index 0000000..d3b5bc6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
@@ -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.
+ */
+
+package com.android.systemui.media.taptotransfer.common
+
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.MediaTttSenderLogBuffer
+
+/**
+ * A logger for media tap-to-transfer events.
+ *
+ * @property deviceTypeTag the type of device triggering the logs -- "Sender" or "Receiver".
+ */
+class MediaTttLogger(
+    private val deviceTypeTag: String,
+    @MediaTttSenderLogBuffer private val buffer: LogBuffer
+){
+    /** Logs a change in the chip state for the given [mediaRouteId]. */
+    fun logStateChange(stateName: String, mediaRouteId: String) {
+        buffer.log(
+            BASE_TAG + deviceTypeTag,
+            LogLevel.DEBUG,
+            {
+                str1 = stateName
+                str2 = mediaRouteId
+            },
+            { "State changed to $str1 for ID=$str2" }
+        )
+    }
+
+    /** Logs that we removed the chip for the given [reason]. */
+    fun logChipRemoval(reason: String) {
+        buffer.log(
+            BASE_TAG + deviceTypeTag,
+            LogLevel.DEBUG,
+            { str1 = reason },
+            { "Chip removed due to $str1" }
+        )
+    }
+}
+
+private const val BASE_TAG = "MediaTtt"
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 214a888..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,18 +18,25 @@
 
 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
+import com.android.systemui.statusbar.gesture.TapGestureDetector
 import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.view.ViewUtil
 import javax.inject.Inject
 
 /**
@@ -41,11 +48,23 @@
 class MediaTttChipControllerReceiver @Inject constructor(
     commandQueue: CommandQueue,
     context: Context,
+    @MediaTttReceiverLogger logger: MediaTttLogger,
     windowManager: WindowManager,
+    viewUtil: ViewUtil,
     mainExecutor: DelayableExecutor,
+    tapGestureDetector: TapGestureDetector,
+    powerManager: PowerManager,
     @Main private val mainHandler: Handler,
-) : MediaTttChipControllerCommon<ChipStateReceiver>(
-    context, windowManager, mainExecutor, R.layout.media_ttt_chip_receiver
+    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 {
         override fun updateMediaTapToTransferReceiverDisplay(
@@ -70,33 +89,52 @@
         appIcon: Icon?,
         appName: CharSequence?
     ) {
-        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()
-            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)
+    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"
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLogger.kt
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
copy to packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLogger.kt
index 2894780..54fc48d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLogger.kt
@@ -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.
@@ -13,14 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.media.taptotransfer.receiver
 
-package com.android.systemui.dagger;
+import java.lang.annotation.Documented
+import java.lang.annotation.Retention
+import java.lang.annotation.RetentionPolicy
+import javax.inject.Qualifier
 
-import dagger.Module;
-
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
-}
+@Qualifier
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+annotation class MediaTttReceiverLogger
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 9b537fb..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,153 +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 }
+
+        /**
+         * 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
     }
 }
 
-/**
- * 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
-}
-
-/**
- * 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
-}
-
-/**
- * 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)
-    }
-}
+// 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
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 482e604..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,9 +29,14 @@
 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
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.gesture.TapGestureDetector
 import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.view.ViewUtil
 import javax.inject.Inject
 
 /**
@@ -41,11 +47,25 @@
 class MediaTttChipControllerSender @Inject constructor(
     commandQueue: CommandQueue,
     context: Context,
+    @MediaTttSenderLogger logger: MediaTttLogger,
     windowManager: WindowManager,
-    @Main private val mainExecutor: DelayableExecutor,
-) : MediaTttChipControllerCommon<ChipStateSender>(
-    context, windowManager, mainExecutor,  R.layout.media_ttt_chip
+    viewUtil: ViewUtil,
+    @Main mainExecutor: DelayableExecutor,
+    tapGestureDetector: TapGestureDetector,
+    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
+
     private val commandQueueCallbacks = object : CommandQueue.Callbacks {
         override fun updateMediaTapToTransferSenderDisplay(
                 @StatusBarManager.MediaTransferSenderState displayState: Int,
@@ -67,64 +87,83 @@
         routeInfo: MediaRoute2Info,
         undoCallback: IUndoMediaTransferCallback?
     ) {
-        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()
-                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?.isMidTransfer == true
+                && removalReason != MediaTttRemovalReason.REASON_TIMEOUT) {
+            return
+        }
+        super.removeChip(removalReason)
+        currentlyDisplayedChipState = null
+    }
+
+    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"
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
copy to packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
index 2894780..4393af9 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
@@ -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.
@@ -13,14 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package com.android.systemui.media.taptotransfer.sender
 
-package com.android.systemui.dagger;
+import java.lang.annotation.Documented
+import java.lang.annotation.Retention
+import java.lang.annotation.RetentionPolicy
+import javax.inject.Qualifier
 
-import dagger.Module;
-
-/**
- * Dagger module for including the WMComponent.
- */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
-}
+@Qualifier
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+annotation class MediaTttSenderLogger
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/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index 5e9edb7..a1a3198 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -49,8 +49,7 @@
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -79,7 +78,7 @@
         Dumpable {
     private final AccessibilityManager mAccessibilityManager;
     private final Lazy<AssistManager> mAssistManagerLazy;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final UserTracker mUserTracker;
     private final SystemActions mSystemActions;
     private final AccessibilityButtonModeObserver mAccessibilityButtonModeObserver;
@@ -113,7 +112,7 @@
             SystemActions systemActions,
             OverviewProxyService overviewProxyService,
             Lazy<AssistManager> assistManagerLazy,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             NavigationModeController navigationModeController,
             UserTracker userTracker,
             DumpManager dumpManager) {
@@ -121,7 +120,7 @@
         mContentResolver = mContext.getContentResolver();
         mAccessibilityManager = accessibilityManager;
         mAssistManagerLazy = assistManagerLazy;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mUserTracker = userTracker;
         mSystemActions = systemActions;
         accessibilityManager.addAccessibilityServicesStateChangeListener(
@@ -295,8 +294,8 @@
      * {@link InputMethodService} and the keyguard states.
      */
     public boolean isImeShown(int vis) {
-        View shadeWindowView = mStatusBarOptionalLazy.get().get().getNotificationShadeWindowView();
-        boolean isKeyguardShowing = mStatusBarOptionalLazy.get().get().isKeyguardShowing();
+        View shadeWindowView = mCentralSurfacesOptionalLazy.get().get().getNotificationShadeWindowView();
+        boolean isKeyguardShowing = mCentralSurfacesOptionalLazy.get().get().isKeyguardShowing();
         boolean imeVisibleOnShade = shadeWindowView != null && shadeWindowView.isAttachedToWindow()
                 && shadeWindowView.getRootWindowInsets().isVisible(WindowInsets.Type.ime());
         return imeVisibleOnShade
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 8b39e5c..ec6094d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -53,11 +53,10 @@
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
-import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE;
-import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_WINDOW_STATE;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.dumpBarTransitions;
 
 import android.annotation.IdRes;
-import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.IActivityTaskManager;
 import android.app.StatusBarManager;
@@ -135,12 +134,11 @@
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.wm.shell.back.BackAnimation;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.pip.Pip;
 
 import java.io.PrintWriter;
@@ -178,7 +176,7 @@
     private final MetricsLogger mMetricsLogger;
     private final Lazy<AssistManager> mAssistManagerLazy;
     private final SysUiState mSysUiFlagsContainer;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final ShadeController mShadeController;
     private final NotificationRemoteInputManager mNotificationRemoteInputManager;
     private final OverviewProxyService mOverviewProxyService;
@@ -187,7 +185,6 @@
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final CommandQueue mCommandQueue;
     private final Optional<Pip> mPipOptional;
-    private final Optional<LegacySplitScreen> mSplitScreenOptional;
     private final Optional<Recents> mRecentsOptional;
     private final Optional<BackAnimation> mBackAnimation;
     private final Handler mHandler;
@@ -440,7 +437,9 @@
                         mHomeButtonLongPressDurationMs = Optional.of(
                             properties.getLong(HOME_BUTTON_LONG_PRESS_DURATION_MS, 0)
                         ).filter(duration -> duration != 0);
-                        reconfigureHomeLongClick();
+                        if (mNavigationBarView != null) {
+                            reconfigureHomeLongClick();
+                        }
                     }
                 }
             };
@@ -486,9 +485,8 @@
             BroadcastDispatcher broadcastDispatcher,
             CommandQueue commandQueue,
             Optional<Pip> pipOptional,
-            Optional<LegacySplitScreen> splitScreenOptional,
             Optional<Recents> recentsOptional,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             ShadeController shadeController,
             NotificationRemoteInputManager notificationRemoteInputManager,
             NotificationShadeDepthController notificationShadeDepthController,
@@ -511,7 +509,7 @@
         mMetricsLogger = metricsLogger;
         mAssistManagerLazy = assistManagerLazy;
         mSysUiFlagsContainer = sysUiFlagsContainer;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mShadeController = shadeController;
         mNotificationRemoteInputManager = notificationRemoteInputManager;
         mOverviewProxyService = overviewProxyService;
@@ -520,7 +518,6 @@
         mBroadcastDispatcher = broadcastDispatcher;
         mCommandQueue = commandQueue;
         mPipOptional = pipOptional;
-        mSplitScreenOptional = splitScreenOptional;
         mRecentsOptional = recentsOptional;
         mBackAnimation = backAnimation;
         mHandler = mainHandler;
@@ -614,7 +611,7 @@
     public void onViewAttachedToWindow(View v) {
         final Display display = v.getDisplay();
         mNavigationBarView.setComponents(mRecentsOptional);
-        mNavigationBarView.setComponents(mStatusBarOptionalLazy.get().get().getPanelController());
+        mNavigationBarView.setComponents(mCentralSurfacesOptionalLazy.get().get().getPanelController());
         mNavigationBarView.setDisabledFlags(mDisabledFlags1);
         mNavigationBarView.setOnVerticalChangedListener(this::onVerticalChanged);
         mNavigationBarView.setOnTouchListener(this::onNavigationTouch);
@@ -627,7 +624,6 @@
 
         mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
 
-        mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener);
         mPipOptional.ifPresent(mNavigationBarView::addPipExclusionBoundsChangeListener);
         mBackAnimation.ifPresent(mNavigationBarView::registerBackAnimation);
 
@@ -761,7 +757,8 @@
                         | WindowManager.LayoutParams.FLAG_SLIPPERY,
                 PixelFormat.TRANSLUCENT);
         mOrientationParams.setTitle("SecondaryHomeHandle" + mContext.getDisplayId());
-        mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
+        mOrientationParams.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION
+                | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
         mWindowManager.addView(mOrientationHandle, mOrientationParams);
         mOrientationHandle.setVisibility(View.GONE);
         mOrientationParams.setFitInsetsTypes(0 /* types*/);
@@ -786,10 +783,7 @@
             return;
         }
 
-        if (mStartingQuickSwitchRotation == -1 || mSplitScreenOptional
-                .map(LegacySplitScreen::isDividerVisible).orElse(false)) {
-            // Hide the secondary home handle if we are in multiwindow since apps in multiwindow
-            // aren't allowed to set the display orientation
+        if (mStartingQuickSwitchRotation == -1) {
             resetSecondaryHandle();
         } else {
             int deltaRotation = deltaRotation(mCurrentRotation, mStartingQuickSwitchRotation);
@@ -1172,13 +1166,14 @@
         // If an incoming call is ringing, HOME is totally disabled.
         // (The user is already on the InCallUI at this point,
         // and their ONLY options are to answer or reject the call.)
-        final Optional<StatusBar> statusBarOptional = mStatusBarOptionalLazy.get();
+        final Optional<CentralSurfaces> centralSurfacesOptional = mCentralSurfacesOptionalLazy.get();
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 mHomeBlockedThisTouch = false;
                 if (mTelecomManagerOptional.isPresent()
                         && mTelecomManagerOptional.get().isRinging()) {
-                    if (statusBarOptional.map(StatusBar::isKeyguardShowing).orElse(false)) {
+                    if (centralSurfacesOptional.map(CentralSurfaces::isKeyguardShowing)
+                            .orElse(false)) {
                         Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
                                 "No heads up");
                         mHomeBlockedThisTouch = true;
@@ -1194,14 +1189,14 @@
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
                 mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
-                statusBarOptional.ifPresent(StatusBar::awakenDreams);
+                centralSurfacesOptional.ifPresent(CentralSurfaces::awakenDreams);
                 break;
         }
         return false;
     }
 
     private void onVerticalChanged(boolean isVertical) {
-        mStatusBarOptionalLazy.get().ifPresent(
+        mCentralSurfacesOptionalLazy.get().ifPresent(
                 statusBar -> statusBar.setQsScrimEnabled(!isVertical));
     }
 
@@ -1228,7 +1223,7 @@
                 AssistManager.INVOCATION_TYPE_KEY,
                 AssistManager.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
         mAssistManagerLazy.get().startAssist(args);
-        mStatusBarOptionalLazy.get().ifPresent(StatusBar::awakenDreams);
+        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::awakenDreams);
         mNavigationBarView.abortCurrentGesture();
         return true;
     }
@@ -1254,7 +1249,7 @@
             LatencyTracker.getInstance(mContext).onActionStart(
                     LatencyTracker.ACTION_TOGGLE_RECENTS);
         }
-        mStatusBarOptionalLazy.get().ifPresent(StatusBar::awakenDreams);
+        mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::awakenDreams);
         mCommandQueue.toggleRecentApps();
     }
 
@@ -1324,7 +1319,7 @@
                         return true;
                     } else if (v.getId() == btnId2) {
                         return btnId2 == R.id.recent_apps
-                                ? onLongPressRecents()
+                                ? false
                                 : onHomeLongClick(
                                         mNavigationBarView.getHomeButton().getCurrentView());
                     }
@@ -1349,24 +1344,6 @@
         return false;
     }
 
-    private boolean onLongPressRecents() {
-        if (mRecentsOptional.isPresent() || !ActivityTaskManager.supportsMultiWindow(mContext)
-                || ActivityManager.isLowRamDeviceStatic()
-                // If we are connected to the overview service, then disable the recents button
-                || mOverviewProxyService.getProxy() != null
-                || !mSplitScreenOptional.map(splitScreen ->
-                splitScreen.getDividerView().getSnapAlgorithm().isSplitScreenFeasible())
-                .orElse(false)) {
-            return false;
-        }
-
-        return mStatusBarOptionalLazy.get().map(
-                statusBar -> statusBar.toggleSplitScreenMode(
-                        MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
-                        MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS))
-            .orElse(false);
-    }
-
     private void onAccessibilityClick(View v) {
         final Display display = v.getDisplay();
         mAccessibilityManager.notifyAccessibilityButtonClicked(
@@ -1456,7 +1433,7 @@
     private void checkBarModes() {
         // We only have status bar on default display now.
         if (mIsOnDefaultDisplay) {
-            mStatusBarOptionalLazy.get().ifPresent(StatusBar::checkBarModes);
+            mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::checkBarModes);
         } else {
             checkNavBarModes();
         }
@@ -1475,7 +1452,8 @@
      */
     public void checkNavBarModes() {
         final boolean anim =
-                mStatusBarOptionalLazy.get().map(StatusBar::isDeviceInteractive).orElse(false)
+                mCentralSurfacesOptionalLazy.get().map(CentralSurfaces::isDeviceInteractive)
+                        .orElse(false)
                 && mNavigationBarWindowState != WINDOW_STATE_HIDDEN;
         mNavigationBarView.getBarTransitions().transitionTo(mNavigationBarMode, anim);
     }
@@ -1588,7 +1566,8 @@
         }
         lp.token = new Binder();
         lp.accessibilityTitle = mContext.getString(R.string.nav_bar);
-        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
+        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC
+                | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
         lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
         lp.windowAnimations = 0;
         lp.setTitle("NavigationBar" + mContext.getDisplayId());
@@ -1650,9 +1629,8 @@
         private final BroadcastDispatcher mBroadcastDispatcher;
         private final CommandQueue mCommandQueue;
         private final Optional<Pip> mPipOptional;
-        private final Optional<LegacySplitScreen> mSplitScreenOptional;
         private final Optional<Recents> mRecentsOptional;
-        private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+        private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
         private final ShadeController mShadeController;
         private final NotificationRemoteInputManager mNotificationRemoteInputManager;
         private final NotificationShadeDepthController mNotificationShadeDepthController;
@@ -1682,9 +1660,8 @@
                 BroadcastDispatcher broadcastDispatcher,
                 CommandQueue commandQueue,
                 Optional<Pip> pipOptional,
-                Optional<LegacySplitScreen> splitScreenOptional,
                 Optional<Recents> recentsOptional,
-                Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+                Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
                 ShadeController shadeController,
                 NotificationRemoteInputManager notificationRemoteInputManager,
                 NotificationShadeDepthController notificationShadeDepthController,
@@ -1711,9 +1688,8 @@
             mBroadcastDispatcher = broadcastDispatcher;
             mCommandQueue = commandQueue;
             mPipOptional = pipOptional;
-            mSplitScreenOptional = splitScreenOptional;
             mRecentsOptional = recentsOptional;
-            mStatusBarOptionalLazy = statusBarOptionalLazy;
+            mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
             mShadeController = shadeController;
             mNotificationRemoteInputManager = notificationRemoteInputManager;
             mNotificationShadeDepthController = notificationShadeDepthController;
@@ -1738,7 +1714,7 @@
                     mOverviewProxyService, mNavigationModeController,
                     mAccessibilityButtonModeObserver, mStatusBarStateController,
                     mSysUiFlagsContainer, mBroadcastDispatcher, mCommandQueue, mPipOptional,
-                    mSplitScreenOptional, mRecentsOptional, mStatusBarOptionalLazy,
+                    mRecentsOptional, mCentralSurfacesOptionalLazy,
                     mShadeController, mNotificationRemoteInputManager,
                     mNotificationShadeDepthController, mMainHandler,
                     mNavbarOverlayController, mUiEventLogger, mNavBarHelper,
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 80a7a4ae..017bbdf 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -90,9 +90,8 @@
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.LightBarTransitionsController;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.wm.shell.back.BackAnimation;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.pip.Pip;
 
 import java.io.PrintWriter;
@@ -1363,7 +1362,7 @@
         getContextDisplay().getRealSize(size);
 
         pw.println("NavigationBarView:");
-        pw.println(String.format("      this: " + StatusBar.viewInfo(this)
+        pw.println(String.format("      this: " + CentralSurfaces.viewInfo(this)
                         + " " + visibilityToString(getVisibility())));
 
         getWindowVisibleDisplayFrame(r);
@@ -1425,10 +1424,6 @@
         return super.onApplyWindowInsets(insets);
     }
 
-    void registerDockedListener(LegacySplitScreen legacySplitScreen) {
-        legacySplitScreen.registerInSplitScreenListener(mDockedListener);
-    }
-
     void addPipExclusionBoundsChangeListener(Pip pip) {
         pip.addPipExclusionBoundsChangeListener(mPipListener);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 9ea2763..4dacf5d 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -263,6 +263,15 @@
                     // Notify FalsingManager that an intentional gesture has occurred.
                     // TODO(b/186519446): use a different method than isFalseTouch
                     mFalsingManager.isFalseTouch(BACK_GESTURE);
+                    // Only inject back keycodes when ahead-of-time back dispatching is disabled.
+                    if (mBackAnimation == null) {
+                        boolean sendDown = sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
+                        boolean sendUp = sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
+                        if (DEBUG_MISSING_GESTURE) {
+                            Log.d(DEBUG_MISSING_GESTURE_TAG, "Triggered back: down="
+                                    + sendDown + ", up=" + sendUp);
+                        }
+                    }
 
                     mOverviewProxyService.notifyBackAction(true, (int) mDownPoint.x,
                             (int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
@@ -936,6 +945,9 @@
 
     public void setBackAnimation(BackAnimation backAnimation) {
         mBackAnimation = backAnimation;
+        if (mEdgeBackPlugin != null && mEdgeBackPlugin instanceof NavigationBarEdgePanel) {
+            ((NavigationBarEdgePanel) mEdgeBackPlugin).setBackAnimation(backAnimation);
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
index a6bad15..a6919e8 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/NavigationBarEdgePanel.java
@@ -280,7 +280,7 @@
                 }
             };
     private BackCallback mBackCallback;
-    private final BackAnimation mBackAnimation;
+    private BackAnimation mBackAnimation;
 
     public NavigationBarEdgePanel(Context context,
             BackAnimation backAnimation) {
@@ -385,6 +385,10 @@
         mShowProtection = !isPrimaryDisplay;
     }
 
+    public void setBackAnimation(BackAnimation backAnimation) {
+        mBackAnimation = backAnimation;
+    }
+
     @Override
     public void onDestroy() {
         cancelFailsafe();
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index dbd641b..b4e20fd 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -97,7 +97,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";
@@ -118,8 +118,8 @@
     private static final String ACTION_AUTO_SAVER_NO_THANKS =
             "PNW.autoSaverNoThanks";
 
-    private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
-            "android.settings.BATTERY_SAVER_SETTINGS";
+    private static final String ACTION_ENABLE_SEVERE_BATTERY_DIALOG = "PNW.enableSevereDialog";
+
     public static final String BATTERY_SAVER_SCHEDULE_SCREEN_INTENT_ACTION =
             "com.android.settings.BATTERY_SAVER_SCHEDULE_SETTINGS";
 
@@ -138,6 +138,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;
@@ -168,6 +171,7 @@
         mKeyguard = mContext.getSystemService(KeyguardManager.class);
         mReceiver.init();
         mActivityStarter = activityStarter;
+        mUseSevereDialog = mContext.getResources().getBoolean(R.bool.config_severe_battery_dialog);
     }
 
     @Override
@@ -253,20 +257,25 @@
     }
 
     protected void showWarningNotification() {
-        final String percentage = NumberFormat.getPercentInstance()
-                .format((double) mCurrentBatterySnapshot.getBatteryLevel() / 100.0);
-
-        // get shared standard notification copy
-        String title = mContext.getString(R.string.battery_low_title);
-        String contentText;
-
-        // get correct content text if notification is hybrid or not
-        if (mCurrentBatterySnapshot.isHybrid()) {
-            contentText = getHybridContentString(percentage);
-        } else {
-            contentText = mContext.getString(R.string.battery_low_percent_format, percentage);
+        if (showSevereLowBatteryDialog()) {
+            mContext.sendBroadcast(new Intent(ACTION_ENABLE_SEVERE_BATTERY_DIALOG)
+                    .setPackage(mContext.getPackageName())
+                    .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                            | Intent.FLAG_RECEIVER_FOREGROUND));
+            // Reset the state once dialog been enabled
+            dismissLowBatteryNotification();
+            mPlaySound = false;
+            return;
         }
 
+        final int warningLevel = mContext.getResources().getInteger(
+                com.android.internal.R.integer.config_lowBatteryWarningLevel);
+        final String percentage = NumberFormat.getPercentInstance()
+                .format((double) warningLevel / 100.0);
+        final String title = mContext.getString(R.string.battery_low_title);
+        final String contentText = mContext.getString(
+                R.string.battery_low_description, percentage);
+
         final Notification.Builder nb =
                 new Notification.Builder(mContext, NotificationChannels.BATTERY)
                         .setSmallIcon(R.drawable.ic_power_low)
@@ -276,21 +285,23 @@
                         .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
-        if (!mCurrentBatterySnapshot.isHybrid() || mBucket < 0
+        if (!mCurrentBatterySnapshot.isHybrid() || mBucket < -1
                 || mCurrentBatterySnapshot.getTimeRemainingMillis()
                         < mCurrentBatterySnapshot.getSevereThresholdMillis()) {
             nb.setColor(Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorError));
         }
 
         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));
@@ -303,6 +314,11 @@
         mNoMan.notifyAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, n, UserHandle.ALL);
     }
 
+    private boolean showSevereLowBatteryDialog() {
+        final boolean isSevereState = !mCurrentBatterySnapshot.isHybrid() || mBucket < -1;
+        return isSevereState && mUseSevereDialog;
+    }
+
     private void showAutoSaverSuggestionNotification() {
         final CharSequence message = mContext.getString(R.string.auto_saver_text);
         final Notification.Builder nb =
@@ -662,8 +678,7 @@
 
         // If there's no link, use the string with no "learn more".
         if (TextUtils.isEmpty(learnMoreUrl)) {
-            return mContext.getText(
-                    com.android.internal.R.string.battery_saver_description);
+            return mContext.getText(R.string.battery_low_intro);
         }
 
         // If we have a link, use the string with the "learn more" link.
@@ -735,7 +750,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);
@@ -755,9 +770,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 642af59..61b434d 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -47,11 +47,10 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 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;
@@ -69,8 +68,7 @@
     private static final long TEMPERATURE_LOGGING_INTERVAL = DateUtils.HOUR_IN_MILLIS;
     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 = 45;
-    private static final long SIX_HOURS_MILLIS = Duration.ofHours(6).toMillis();
+    private static final int CHARGE_CYCLE_PERCENT_RESET = 30;
     public static final int NO_ESTIMATE_AVAILABLE = -1;
     private static final String BOOT_COUNT_KEY = "boot_count";
     private static final String PREFS = "powerui_prefs";
@@ -108,17 +106,17 @@
     private IThermalEventListener mUsbThermalEventListener;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final CommandQueue mCommandQueue;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
 
     @Inject
     public PowerUI(Context context, BroadcastDispatcher broadcastDispatcher,
-            CommandQueue commandQueue, Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            CommandQueue commandQueue, Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             WarningsUI warningsUI, EnhancedEstimates enhancedEstimates,
             PowerManager powerManager) {
         super(context);
         mBroadcastDispatcher = broadcastDispatcher;
         mCommandQueue = commandQueue;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mWarnings = warningsUI;
         mEnhancedEstimates = enhancedEstimates;
         mPowerManager = powerManager;
@@ -206,7 +204,8 @@
      *
      * 1 means that the battery is "ok"
      * 0 means that the battery is between "ok" and what we should warn about.
-     * less than 0 means that the battery is low
+     * less than 0 means that the battery is low, -1 means the battery is reaching warning level,
+     * -2 means the battery is reaching severe level.
      */
     private int findBatteryLevelBucket(int level) {
         if (level >= mLowBatteryAlertCloseLevel) {
@@ -388,12 +387,8 @@
     @VisibleForTesting
     void maybeShowHybridWarning(BatteryStateSnapshot currentSnapshot,
             BatteryStateSnapshot lastSnapshot) {
-        // if we are now over 45% battery & 6 hours remaining so we can trigger hybrid
-        // notification again
-        final long timeRemainingMillis = currentSnapshot.getTimeRemainingMillis();
-        if (currentSnapshot.getBatteryLevel() >= CHARGE_CYCLE_PERCENT_RESET
-                && (timeRemainingMillis > SIX_HOURS_MILLIS
-                || timeRemainingMillis == NO_ESTIMATE_AVAILABLE)) {
+        // if we are now over 30% battery, we can trigger hybrid notification again
+        if (currentSnapshot.getBatteryLevel() >= CHARGE_CYCLE_PERCENT_RESET) {
             mLowWarningShownThisChargeCycle = false;
             mSevereWarningShownThisChargeCycle = false;
             if (DEBUG) {
@@ -403,6 +398,7 @@
 
         final boolean playSound = currentSnapshot.getBucket() != lastSnapshot.getBucket()
                 || lastSnapshot.getPlugged();
+        final long timeRemainingMillis = currentSnapshot.getTimeRemainingMillis();
 
         if (shouldShowHybridWarning(currentSnapshot)) {
             mWarnings.showLowBatteryWarning(playSound);
@@ -444,19 +440,13 @@
             return false;
         }
 
-        final long timeRemainingMillis = snapshot.getTimeRemainingMillis();
         // Only show the low warning if enabled once per charge cycle & no battery saver
-        final boolean canShowWarning = snapshot.isLowWarningEnabled()
-                && !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver()
-                && ((timeRemainingMillis != NO_ESTIMATE_AVAILABLE
-                && timeRemainingMillis < snapshot.getLowThresholdMillis())
-                || snapshot.getBatteryLevel() <= snapshot.getLowLevelThreshold());
+        final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver()
+                && snapshot.getBatteryLevel() <= snapshot.getLowLevelThreshold();
 
         // Only show the severe warning once per charge cycle
         final boolean canShowSevereWarning = !mSevereWarningShownThisChargeCycle
-                && ((timeRemainingMillis != NO_ESTIMATE_AVAILABLE
-                && timeRemainingMillis < snapshot.getSevereThresholdMillis())
-                || snapshot.getBatteryLevel() <= snapshot.getSevereLevelThreshold());
+                && snapshot.getBatteryLevel() <= snapshot.getSevereLevelThreshold();
 
         final boolean canShow = canShowWarning || canShowSevereWarning;
 
@@ -712,8 +702,10 @@
             int status = temp.getStatus();
 
             if (status >= Temperature.THROTTLING_EMERGENCY) {
-                final Optional<StatusBar> statusBarOptional = mStatusBarOptionalLazy.get();
-                if (!statusBarOptional.map(StatusBar::isDeviceInVrMode).orElse(false)) {
+                final Optional<CentralSurfaces> centralSurfacesOptional =
+                        mCentralSurfacesOptionalLazy.get();
+                if (!centralSurfacesOptional.map(CentralSurfaces::isDeviceInVrMode)
+                        .orElse(false)) {
                     mWarnings.showHighTemperatureWarning();
                     Slog.d(TAG, "SkinThermalEventListener: notifyThrottling was called "
                             + ", current skin status = " + status
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
index 89735c3..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
         }
     }
@@ -370,6 +387,7 @@
                 PowerExemptionManager.REASON_SYSTEM_UID,
                 PowerExemptionManager.REASON_DEVICE_DEMO_MODE -> UIControl.HIDE_ENTRY
 
+                PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE,
                 PowerExemptionManager.REASON_DEVICE_OWNER,
                 PowerExemptionManager.REASON_PROFILE_OWNER,
                 PowerExemptionManager.REASON_PROC_STATE_PERSISTENT,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
index a262b8a..27da6f3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.util.settings.GlobalSettings
 import javax.inject.Inject
 import javax.inject.Named
+import javax.inject.Provider
 
 /**
  * Manages [FooterActionsView] behaviour, both when it's placed in QS or QQS (split shade).
@@ -69,7 +70,7 @@
     private val fgsManagerFooterController: QSFgsManagerFooter,
     private val falsingManager: FalsingManager,
     private val metricsLogger: MetricsLogger,
-    private val globalActionsDialog: GlobalActionsDialogLite,
+    private val globalActionsDialogProvider: Provider<GlobalActionsDialogLite>,
     private val uiEventLogger: UiEventLogger,
     @Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
     private val globalSetting: GlobalSettings,
@@ -77,6 +78,8 @@
     private val featureFlags: FeatureFlags
 ) : ViewController<FooterActionsView>(view) {
 
+    private var globalActionsDialog: GlobalActionsDialogLite? = null
+
     private var lastExpansion = -1f
     private var listening: Boolean = false
 
@@ -131,7 +134,7 @@
             startSettingsActivity()
         } else if (v === powerMenuLite) {
             uiEventLogger.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
-            globalActionsDialog.showOrHideDialog(false, true, v)
+            globalActionsDialog?.showOrHideDialog(false, true, v)
         }
     }
 
@@ -158,6 +161,7 @@
 
     @VisibleForTesting
     public override fun onViewAttached() {
+        globalActionsDialog = globalActionsDialogProvider.get()
         if (showPMLiteButton) {
             powerMenuLite.visibility = View.VISIBLE
             powerMenuLite.setOnClickListener(onClickListener)
@@ -165,6 +169,7 @@
             powerMenuLite.visibility = View.GONE
         }
         settingsButton.setOnClickListener(onClickListener)
+        multiUserSetting.isListening = true
         if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
             val securityFooter = securityFooterController.view as DualHeightHorizontalLinearLayout
             securityFootersContainer?.addView(securityFooter)
@@ -214,7 +219,10 @@
     }
 
     override fun onViewDetached() {
+        globalActionsDialog?.destroy()
+        globalActionsDialog = null
         setListening(false)
+        multiUserSetting.isListening = false
     }
 
     fun setListening(listening: Boolean) {
@@ -222,7 +230,6 @@
             return
         }
         this.listening = listening
-        multiUserSetting.isListening = listening
         if (this.listening) {
             userInfoController.addCallback(onUserInfoChangedListener)
             updateView()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt b/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
index 8afb793..95b4b72 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
@@ -118,7 +118,7 @@
             // If the privacy chip is visible, it means there were some indicators
             uiEventLogger.log(PrivacyChipEvent.ONGOING_INDICATORS_CHIP_CLICK)
             if (safetyCenterEnabled) {
-                showSafetyHub()
+                showSafetyCenter()
             } else {
                 privacyDialogController.showDialog(privacyChip.context)
             }
@@ -131,16 +131,16 @@
         updatePrivacyIconSlots()
     }
 
-    private fun showSafetyHub() {
+    private fun showSafetyCenter() {
         backgroundExecutor.execute {
             val usage = ArrayList(permGroupUsage())
             privacyLogger.logUnfilteredPermGroupUsage(usage)
-            val startSafetyHub = Intent(Intent.ACTION_VIEW_SAFETY_HUB)
-            startSafetyHub.putParcelableArrayListExtra(PermissionManager.EXTRA_PERMISSION_USAGES,
+            val startSafetyCenter = Intent(Intent.ACTION_VIEW_SAFETY_CENTER_QS)
+            startSafetyCenter.putParcelableArrayListExtra(PermissionManager.EXTRA_PERMISSION_USAGES,
                 usage)
-            startSafetyHub.flags = Intent.FLAG_ACTIVITY_NEW_TASK
+            startSafetyCenter.flags = Intent.FLAG_ACTIVITY_NEW_TASK
             uiExecutor.execute {
-                activityStarter.startActivity(startSafetyHub, true,
+                activityStarter.startActivity(startSafetyCenter, true,
                     ActivityLaunchAnimator.Controller.fromView(privacyChip))
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 3c7933f..3ef7220 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -513,7 +513,8 @@
         mContainer.setExpansion(expansion);
         final float translationScaleY = (mInSplitShade
                 ? 1 : QSAnimator.SHORT_PARALLAX_AMOUNT) * (expansion - 1);
-        boolean onKeyguardAndExpanded = isKeyguardState() && !mShowCollapsedOnKeyguard;
+        boolean onKeyguard = isKeyguardState();
+        boolean onKeyguardAndExpanded = onKeyguard && !mShowCollapsedOnKeyguard;
         if (!mHeaderAnimating && !headerWillBeAnimating()) {
             getView().setTranslationY(
                     onKeyguardAndExpanded
@@ -547,6 +548,7 @@
                 mHeader.updateResources();
             }
         }
+        mQSPanelController.setIsOnKeyguard(onKeyguard);
         mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
         mQSFooterActionController.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
         mQSPanelController.setRevealExpansion(expansion);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 5126fcb..b04d752 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -110,6 +110,8 @@
     private final ArrayMap<View, Integer> mChildrenLayoutTop = new ArrayMap<>();
     private final Rect mClippingRect = new Rect();
     private boolean mUseNewFooter = false;
+    private ViewGroup mMediaHostView;
+    private boolean mShouldMoveMediaOnExpansion = true;
 
     public QSPanel(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -289,9 +291,15 @@
         for (int i = 0; i < getChildCount(); i++) {
             View child = getChildAt(i);
             if (move) {
+                int topOffset;
+                if (child == mMediaHostView && !mShouldMoveMediaOnExpansion) {
+                    topOffset = 0;
+                } else {
+                    topOffset = tileHeightOffset;
+                }
                 int top = Objects.requireNonNull(mChildrenLayoutTop.get(child));
-                child.setLeftTopRightBottom(child.getLeft(), top + tileHeightOffset,
-                        child.getRight(), top + tileHeightOffset + child.getHeight());
+                child.setLeftTopRightBottom(child.getLeft(), top + topOffset,
+                        child.getRight(), top + topOffset + child.getHeight());
             }
             if (child == mTileLayout) {
                 move = true;
@@ -463,6 +471,7 @@
         if (!mUsingMediaPlayer) {
             return;
         }
+        mMediaHostView = hostView;
         ViewGroup newParent = horizontal ? mHorizontalLinearLayout : this;
         ViewGroup currentParent = (ViewGroup) hostView.getParent();
         if (currentParent != newParent) {
@@ -656,6 +665,19 @@
         updatePadding();
     }
 
+    /**
+     * Sets whether the media container should move during the expansion of the QS Panel.
+     *
+     * As the QS Panel expands and the QS unsquish, the views below the QS tiles move to adapt to
+     * the new height of the QS tiles.
+     *
+     * In some cases this might not be wanted for media. One example is when there is a transition
+     * animation of the media container happening on split shade lock screen.
+     */
+    public void setShouldMoveMediaOnExpansion(boolean shouldMoveMediaOnExpansion) {
+        mShouldMoveMediaOnExpansion = shouldMoveMediaOnExpansion;
+    }
+
     private class H extends Handler {
         private static final int ANNOUNCE_FOR_ACCESSIBILITY = 1;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 9834129..865f093 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -33,8 +33,10 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.flags.Flags;
+import com.android.systemui.media.MediaFlags;
 import com.android.systemui.media.MediaHierarchyManager;
 import com.android.systemui.media.MediaHost;
+import com.android.systemui.media.MediaHostState;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.qs.customize.QSCustomizerController;
 import com.android.systemui.qs.dagger.QSScope;
@@ -63,6 +65,7 @@
     private final FalsingManager mFalsingManager;
     private final BrightnessController mBrightnessController;
     private final BrightnessSliderController mBrightnessSliderController;
+    private final MediaFlags mMediaFlags;
     private final BrightnessMirrorHandler mBrightnessMirrorHandler;
     private final FeatureFlags mFeatureFlags;
 
@@ -102,7 +105,8 @@
             DumpManager dumpManager, MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
             QSLogger qsLogger, BrightnessController.Factory brightnessControllerFactory,
             BrightnessSliderController.Factory brightnessSliderFactory,
-            FalsingManager falsingManager, FeatureFlags featureFlags) {
+            FalsingManager falsingManager, FeatureFlags featureFlags,
+            MediaFlags mediaFlags) {
         super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost,
                 metricsLogger, uiEventLogger, qsLogger, dumpManager);
         mQSFgsManagerFooter = qsFgsManagerFooter;
@@ -113,6 +117,7 @@
         mFalsingManager = falsingManager;
 
         mBrightnessSliderController = brightnessSliderFactory.create(getContext(), mView);
+        mMediaFlags = mediaFlags;
         mView.setBrightnessView(mBrightnessSliderController.getRootView());
 
         mBrightnessController = brightnessControllerFactory.create(mBrightnessSliderController);
@@ -133,7 +138,14 @@
     }
 
     private void updateMediaExpansion() {
-        mMediaHost.setExpansion(Utils.shouldUseSplitNotificationShade(getResources()) ? 0 : 1);
+        boolean inSplitShade = Utils.shouldUseSplitNotificationShade(getResources());
+        float expansion;
+        if (inSplitShade && !mMediaFlags.useMediaSessionLayout()) {
+            expansion = MediaHostState.COLLAPSED;
+        } else {
+            expansion = MediaHostState.EXPANDED;
+        }
+        mMediaHost.setExpansion(expansion);
     }
 
     @Override
@@ -187,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/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 3172aa9..6572daa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -419,6 +419,16 @@
         return mView.getBrightnessView();
     }
 
+    /** Sets whether we are currently on lock screen. */
+    public void setIsOnKeyguard(boolean isOnKeyguard) {
+        boolean isOnSplitShadeLockscreen = mShouldUseSplitNotificationShade && isOnKeyguard;
+        // When the split shade is expanding on lockscreen, the media container transitions from the
+        // lockscreen to QS.
+        // We have to prevent the media container position from moving during the transition to have
+        // a smooth translation animation without stuttering.
+        mView.setShouldMoveMediaOnExpansion(!isOnSplitShadeLockscreen);
+    }
+
     /** */
     public static final class TileRecord {
         public TileRecord(QSTile tile, com.android.systemui.plugins.qs.QSTileView tileView) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
index fb55cd2..3824e1b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSSecurityFooter.java
@@ -83,6 +83,8 @@
 import com.android.systemui.animation.DialogLaunchAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.dagger.QSScope;
 import com.android.systemui.settings.UserTracker;
@@ -119,7 +121,7 @@
     protected H mHandler;
 
     // Does it move between footer and header? Remove this once all the flagging is removed
-    private boolean mIsMovable = true;
+    private final boolean mNewQsFooter;
 
     private boolean mIsVisible;
     @Nullable
@@ -135,7 +137,7 @@
     QSSecurityFooter(@Named(QS_SECURITY_FOOTER_VIEW) View rootView,
             UserTracker userTracker, @Main Handler mainHandler, ActivityStarter activityStarter,
             SecurityController securityController, DialogLaunchAnimator dialogLaunchAnimator,
-            @Background Looper bgLooper) {
+            @Background Looper bgLooper, FeatureFlags featureFlags) {
         mRootView = rootView;
         mRootView.setOnClickListener(this);
         mFooterText = mRootView.findViewById(R.id.footer_text);
@@ -149,6 +151,7 @@
         mHandler = new H(bgLooper);
         mUserTracker = userTracker;
         mDialogLaunchAnimator = dialogLaunchAnimator;
+        mNewQsFooter = featureFlags.isEnabled(Flags.NEW_FOOTER);
     }
 
     public void setListening(boolean listening) {
@@ -168,13 +171,10 @@
 
     public void onConfigurationChanged() {
         FontSizeUtils.updateFontSize(mFooterText, R.dimen.qs_tile_text_size);
+        Resources r = mContext.getResources();
 
-        if (mIsMovable) {
-            Resources r = mContext.getResources();
-
+        if (!mNewQsFooter) {
             mFooterText.setMaxLines(r.getInteger(R.integer.qs_security_footer_maxLines));
-            int padding = r.getDimensionPixelSize(R.dimen.qs_footer_padding);
-            mRootView.setPaddingRelative(padding, padding, padding, padding);
 
             int bottomMargin = r.getDimensionPixelSize(R.dimen.qs_footers_margin_bottom);
             ViewGroup.MarginLayoutParams lp =
@@ -183,8 +183,10 @@
             lp.width = r.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT
                     ? MATCH_PARENT : WRAP_CONTENT;
             mRootView.setLayoutParams(lp);
-
         }
+
+        int padding = r.getDimensionPixelSize(R.dimen.qs_footer_padding);
+        mRootView.setPaddingRelative(padding, padding, padding, padding);
         mRootView.setBackground(mContext.getDrawable(R.drawable.qs_security_footer_background));
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index c693075..47af7de 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -53,7 +53,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -102,7 +102,7 @@
     private final StatusBarIconController mIconController;
     private final ArrayList<QSFactory> mQsFactories = new ArrayList<>();
     private int mCurrentUser;
-    private final Optional<StatusBar> mStatusBarOptional;
+    private final Optional<CentralSurfaces> mCentralSurfacesOptional;
     private Context mUserContext;
     private UserTracker mUserTracker;
     private SecureSettings mSecureSettings;
@@ -121,7 +121,7 @@
             Provider<AutoTileManager> autoTiles,
             DumpManager dumpManager,
             BroadcastDispatcher broadcastDispatcher,
-            Optional<StatusBar> statusBarOptional,
+            Optional<CentralSurfaces> centralSurfacesOptional,
             QSLogger qsLogger,
             UiEventLogger uiEventLogger,
             UserTracker userTracker,
@@ -143,7 +143,7 @@
         mTileLifeCycleManagerFactory = tileLifecycleManagerFactory;
 
         mInstanceIdSequence = new InstanceIdSequence(MAX_QS_INSTANCE_ID);
-        mStatusBarOptional = statusBarOptional;
+        mCentralSurfacesOptional = centralSurfacesOptional;
 
         mQsFactories.add(defaultFactory);
         pluginManager.addPluginListener(this, QSFactory.class, true);
@@ -227,17 +227,17 @@
 
     @Override
     public void collapsePanels() {
-        mStatusBarOptional.ifPresent(StatusBar::postAnimateCollapsePanels);
+        mCentralSurfacesOptional.ifPresent(CentralSurfaces::postAnimateCollapsePanels);
     }
 
     @Override
     public void forceCollapsePanels() {
-        mStatusBarOptional.ifPresent(StatusBar::postAnimateForceCollapsePanels);
+        mCentralSurfacesOptional.ifPresent(CentralSurfaces::postAnimateForceCollapsePanels);
     }
 
     @Override
     public void openPanels() {
-        mStatusBarOptional.ifPresent(StatusBar::postAnimateOpenPanels);
+        mCentralSurfacesOptional.ifPresent(CentralSurfaces::postAnimateOpenPanels);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
index 32e0805..a49d3fd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java
@@ -204,6 +204,9 @@
                                 | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
                                 | Context.BIND_WAIVE_PRIORITY,
                         mUser);
+                if (!mIsBound) {
+                    mContext.unbindService(this);
+                }
             } catch (SecurityException e) {
                 Log.e(TAG, "Failed to bind to service", e);
                 mIsBound = false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 131589f..999818f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -116,7 +116,8 @@
 
     private String mTileSpec;
     @Nullable
-    private EnforcedAdmin mEnforcedAdmin;
+    @VisibleForTesting
+    protected EnforcedAdmin mEnforcedAdmin;
     private boolean mShowingDetail;
     private int mIsFullQs;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index c61c18a..f736231 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.text.TextUtils;
@@ -114,6 +115,7 @@
 
     @Override
     protected void handleUpdateState(BooleanState state, Object arg) {
+        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_BLUETOOTH);
         final boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
         final boolean enabled = transientEnabling || mController.isBluetoothEnabled();
         final boolean connected = mController.isBluetoothConnected();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 597f7b7..f389df0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -26,7 +26,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.shared.recents.IOverviewProxy;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.util.Optional;
 
@@ -42,7 +42,7 @@
 
     private final static String TAG = "OverviewProxyRecentsImpl";
     @Nullable
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
 
     private Context mContext;
     private Handler mHandler;
@@ -51,8 +51,8 @@
 
     @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
     @Inject
-    public OverviewProxyRecentsImpl(Lazy<Optional<StatusBar>> statusBarOptionalLazy) {
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+    public OverviewProxyRecentsImpl(Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy) {
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
     }
 
     @Override
@@ -109,9 +109,10 @@
                 }
             };
             // Preload only if device for current user is unlocked
-            final Optional<StatusBar> statusBarOptional = mStatusBarOptionalLazy.get();
-            if (statusBarOptional.map(StatusBar::isKeyguardShowing).orElse(false)) {
-                statusBarOptional.get().executeRunnableDismissingKeyguard(() -> {
+            final Optional<CentralSurfaces> centralSurfacesOptional =
+                    mCentralSurfacesOptionalLazy.get();
+            if (centralSurfacesOptional.map(CentralSurfaces::isKeyguardShowing).orElse(false)) {
+                centralSurfacesOptional.get().executeRunnableDismissingKeyguard(() -> {
                         mHandler.post(toggleRecents);
                     }, null,  true /* dismissShade */, false /* afterKeyguardGone */,
                     true /* deferred */);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 6b251b0..a3dea1c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -102,11 +102,10 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarWindowCallback;
 import com.android.systemui.statusbar.policy.CallbackController;
 import com.android.wm.shell.back.BackAnimation;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.pip.Pip;
 import com.android.wm.shell.pip.PipAnimationController;
@@ -147,8 +146,7 @@
 
     private final Context mContext;
     private final Optional<Pip> mPipOptional;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
-    private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final Optional<SplitScreen> mSplitScreenOptional;
     private SysUiState mSysUiState;
     private final Handler mHandler;
@@ -188,7 +186,7 @@
         @Override
         public void startScreenPinning(int taskId) {
             verifyCallerAndClearCallingIdentityPostMain("startScreenPinning", () ->
-                    mStatusBarOptionalLazy.get().ifPresent(
+                    mCentralSurfacesOptionalLazy.get().ifPresent(
                             statusBar -> statusBar.showScreenPinningRequest(taskId,
                                     false /* allowCancel */)));
         }
@@ -209,9 +207,9 @@
         public void onStatusBarMotionEvent(MotionEvent event) {
             verifyCallerAndClearCallingIdentity("onStatusBarMotionEvent", () -> {
                 // TODO move this logic to message queue
-                mStatusBarOptionalLazy.get().ifPresent(statusBar -> {
+                mCentralSurfacesOptionalLazy.get().ifPresent(centralSurfaces -> {
                     if (event.getActionMasked() == ACTION_DOWN) {
-                        statusBar.getPanelController().startExpandLatencyTracking();
+                        centralSurfaces.getPanelController().startExpandLatencyTracking();
                     }
                     mHandler.post(() -> {
                         int action = event.getActionMasked();
@@ -219,7 +217,7 @@
                             mInputFocusTransferStarted = true;
                             mInputFocusTransferStartY = event.getY();
                             mInputFocusTransferStartMillis = event.getEventTime();
-                            statusBar.onInputFocusTransfer(
+                            centralSurfaces.onInputFocusTransfer(
                                     mInputFocusTransferStarted, false /* cancel */,
                                     0 /* velocity */);
                         }
@@ -227,7 +225,7 @@
                             mInputFocusTransferStarted = false;
                             float velocity = (event.getY() - mInputFocusTransferStartY)
                                     / (event.getEventTime() - mInputFocusTransferStartMillis);
-                            statusBar.onInputFocusTransfer(mInputFocusTransferStarted,
+                            centralSurfaces.onInputFocusTransfer(mInputFocusTransferStarted,
                                     action == ACTION_CANCEL,
                                     velocity);
                         }
@@ -298,14 +296,8 @@
 
         @Override
         public Rect getNonMinimizedSplitScreenSecondaryBounds() {
-            return verifyCallerAndClearCallingIdentity(
-                    "getNonMinimizedSplitScreenSecondaryBounds",
-                    () -> mLegacySplitScreenOptional.map(splitScreen ->
-                            splitScreen
-                                    .getDividerView()
-                                    .getNonMinimizedSplitScreenSecondaryBounds())
-                            .orElse(null)
-            );
+            // Deprecated
+            return null;
         }
 
         @Override
@@ -362,8 +354,7 @@
 
         @Override
         public void setSplitScreenMinimized(boolean minimized) {
-            mLegacySplitScreenOptional.ifPresent(
-                    splitScreen -> splitScreen.setMinimized(minimized));
+            // Deprecated
         }
 
         @Override
@@ -410,7 +401,7 @@
         @Override
         public void toggleNotificationPanel() {
             verifyCallerAndClearCallingIdentityPostMain("toggleNotificationPanel", () ->
-                    mStatusBarOptionalLazy.get().ifPresent(StatusBar::togglePanel));
+                    mCentralSurfacesOptionalLazy.get().ifPresent(CentralSurfaces::togglePanel));
         }
 
 
@@ -564,11 +555,10 @@
     @Inject
     public OverviewProxyService(Context context, CommandQueue commandQueue,
             Lazy<NavigationBarController> navBarControllerLazy,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             NavigationModeController navModeController,
             NotificationShadeWindowController statusBarWinController, SysUiState sysUiState,
             Optional<Pip> pipOptional,
-            Optional<LegacySplitScreen> legacySplitScreenOptional,
             Optional<SplitScreen> splitScreenOptional,
             Optional<OneHanded> oneHandedOptional,
             Optional<RecentTasks> recentTasks,
@@ -583,7 +573,7 @@
         super(broadcastDispatcher);
         mContext = context;
         mPipOptional = pipOptional;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mHandler = new Handler();
         mNavBarControllerLazy = navBarControllerLazy;
         mStatusBarWinController = statusBarWinController;
@@ -634,9 +624,6 @@
         mCommandQueue = commandQueue;
 
         mSplitScreenOptional = splitScreenOptional;
-        legacySplitScreenOptional.ifPresent(splitScreen ->
-                splitScreen.registerBoundsChangeListener(mSplitScreenBoundsChangeListener));
-        mLegacySplitScreenOptional = legacySplitScreenOptional;
 
         // Listen for user setup
         startTracking();
@@ -678,7 +665,7 @@
         final NavigationBarView navBarView =
                 mNavBarControllerLazy.get().getNavigationBarView(mContext.getDisplayId());
         final NotificationPanelViewController panelController =
-                mStatusBarOptionalLazy.get().get().getPanelController();
+                mCentralSurfacesOptionalLazy.get().get().getPanelController();
         if (SysUiState.DEBUG) {
             Log.d(TAG_OPS, "Updating sysui state flags: navBarFragment=" + navBarFragment
                     + " navBarView=" + navBarView + " panelController=" + panelController);
@@ -744,17 +731,13 @@
     public void cleanupAfterDeath() {
         if (mInputFocusTransferStarted) {
             mHandler.post(() -> {
-                mStatusBarOptionalLazy.get().ifPresent(statusBar -> {
+                mCentralSurfacesOptionalLazy.get().ifPresent(centralSurfaces -> {
                     mInputFocusTransferStarted = false;
-                    statusBar.onInputFocusTransfer(false, true /* cancel */, 0 /* velocity */);
+                    centralSurfaces.onInputFocusTransfer(false, true /* cancel */, 0 /* velocity */);
                 });
             });
         }
         startConnectionToCurrentUser();
-
-        // Clean up the minimized state if launcher dies
-        mLegacySplitScreenOptional.ifPresent(
-                splitScreen -> splitScreen.setMinimized(false));
     }
 
     public void startConnectionToCurrentUser() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 7f130cb..15ad779 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -56,7 +56,7 @@
 import com.android.systemui.navigationbar.NavigationModeController;
 import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.util.leak.RotationUtils;
 
 import java.util.ArrayList;
@@ -70,7 +70,7 @@
         NavigationModeController.ModeChangedListener {
 
     private final Context mContext;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
 
     private final AccessibilityManager mAccessibilityService;
     private final WindowManager mWindowManager;
@@ -83,9 +83,11 @@
     private int taskId;
 
     @Inject
-    public ScreenPinningRequest(Context context, Lazy<Optional<StatusBar>> statusBarOptionalLazy) {
+    public ScreenPinningRequest(
+            Context context,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy) {
         mContext = context;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mAccessibilityService = (AccessibilityManager)
                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
         mWindowManager = (WindowManager)
@@ -267,9 +269,10 @@
                         .setVisibility(View.INVISIBLE);
             }
 
-            final Optional<StatusBar> statusBarOptional = mStatusBarOptionalLazy.get();
+            final Optional<CentralSurfaces> centralSurfacesOptional =
+                    mCentralSurfacesOptionalLazy.get();
             NavigationBarView navigationBarView =
-                    statusBarOptional.map(StatusBar::getNavigationBarView).orElse(null);
+                    centralSurfacesOptional.map(CentralSurfaces::getNavigationBarView).orElse(null);
             final boolean recentsVisible = navigationBarView != null
                     && navigationBarView.isRecentsButtonVisible();
             boolean touchExplorationEnabled = mAccessibilityService.isTouchExplorationEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
index f140446..daaa897 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
@@ -24,7 +24,7 @@
 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_DISALLOW_ENTER_PIP;
 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_ID;
 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED;
-import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_SCREENSHOT;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.SYSTEM_DIALOG_REASON_SCREENSHOT;
 
 import android.app.ActivityOptions;
 import android.app.PendingIntent;
@@ -36,7 +36,7 @@
 import android.view.WindowManagerGlobal;
 
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.util.Optional;
 
@@ -49,15 +49,15 @@
 public class ActionProxyReceiver extends BroadcastReceiver {
     private static final String TAG = "ActionProxyReceiver";
 
-    private final StatusBar mStatusBar;
+    private final CentralSurfaces mCentralSurfaces;
     private final ActivityManagerWrapper mActivityManagerWrapper;
     private final ScreenshotSmartActions mScreenshotSmartActions;
 
     @Inject
-    public ActionProxyReceiver(Optional<StatusBar> statusBar,
+    public ActionProxyReceiver(Optional<CentralSurfaces> centralSurfacesOptional,
             ActivityManagerWrapper activityManagerWrapper,
             ScreenshotSmartActions screenshotSmartActions) {
-        mStatusBar = statusBar.orElse(null);
+        mCentralSurfaces = centralSurfacesOptional.orElse(null);
         mActivityManagerWrapper = activityManagerWrapper;
         mScreenshotSmartActions = screenshotSmartActions;
     }
@@ -89,8 +89,8 @@
 
         };
 
-        if (mStatusBar != null) {
-            mStatusBar.executeRunnableDismissingKeyguard(startActivityRunnable, null,
+        if (mCentralSurfaces != null) {
+            mCentralSurfaces.executeRunnableDismissingKeyguard(startActivityRunnable, null,
                     true /* dismissShade */, true /* afterKeyguardGone */,
                     true /* deferred */);
         } else {
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/ScreenshotView.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java
index 4a9a1f1..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,23 +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 onDismiss() {
-                        if (DEBUG_DISMISS) {
-                            Log.d(ScreenshotView.TAG, "dismiss triggered via swipe gesture");
-                        }
-                        mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SWIPE_DISMISSED, 0,
-                                mPackageName);
-                        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() {
@@ -636,8 +633,6 @@
                 requestLayout();
 
                 createScreenshotActionsShadeAnimation().start();
-
-                setOnTouchListener(mSwipeDismissHandler);
             }
         });
 
@@ -946,7 +941,7 @@
     }
 
     boolean isDismissing() {
-        return mSwipeDismissHandler.isDismissing();
+        return mScreenshotStatic.isDismissing();
     }
 
     boolean isPendingSharedTransition() {
@@ -954,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");
         }
@@ -995,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 451fb13..0000000
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SwipeDismissHandler.java
+++ /dev/null
@@ -1,227 +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), post-dismissal animation
-         */
-        void onDismiss();
-    }
-
-    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()) {
-                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())) {
-                dismiss(velocityX / (float) 1000);
-                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(1);
-    }
-
-    private void dismiss(float velocity) {
-        mDismissAnimation = createSwipeDismissAnimation(velocity);
-        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.onDismiss();
-                }
-            }
-        });
-        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/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
index 991a68f..7801c68 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -54,7 +54,7 @@
 import javax.inject.Inject;
 
 public class BrightnessController implements ToggleSlider.Listener, MirroredBrightnessController {
-    private static final String TAG = "StatusBar.BrightnessController";
+    private static final String TAG = "CentralSurfaces.BrightnessController";
     private static final int SLIDER_ANIMATION_DURATION = 3000;
 
     private static final int MSG_UPDATE_SLIDER = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 10aa12b..6abf339 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -23,13 +23,8 @@
 import android.view.KeyEvent;
 import android.view.WindowManagerGlobal;
 
-import com.android.internal.policy.DividerSnapAlgorithm;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.dagger.SysUISingleton;
-import com.android.wm.shell.legacysplitscreen.DividerView;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
-
-import java.util.Optional;
 
 import javax.inject.Inject;
 
@@ -41,7 +36,6 @@
         implements ShortcutKeyServiceProxy.Callbacks {
 
     private static final String TAG = "ShortcutKeyDispatcher";
-    private final Optional<LegacySplitScreen> mSplitScreenOptional;
 
     private ShortcutKeyServiceProxy mShortcutKeyServiceProxy = new ShortcutKeyServiceProxy(this);
     private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
@@ -55,9 +49,8 @@
     protected final long SC_DOCK_RIGHT = META_MASK | KeyEvent.KEYCODE_RIGHT_BRACKET;
 
     @Inject
-    public ShortcutKeyDispatcher(Context context, Optional<LegacySplitScreen> splitScreenOptional) {
+    public ShortcutKeyDispatcher(Context context) {
         super(context);
-        mSplitScreenOptional = splitScreenOptional;
     }
 
     /**
@@ -89,24 +82,6 @@
     }
 
     private void handleDockKey(long shortcutCode) {
-        mSplitScreenOptional.ifPresent(splitScreen -> {
-            if (splitScreen.isDividerVisible()) {
-                // If there is already a docked window, we respond by resizing the docking pane.
-                DividerView dividerView = splitScreen.getDividerView();
-                DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm();
-                int dividerPosition = dividerView.getCurrentPosition();
-                DividerSnapAlgorithm.SnapTarget currentTarget =
-                        snapAlgorithm.calculateNonDismissingSnapTarget(dividerPosition);
-                DividerSnapAlgorithm.SnapTarget target = (shortcutCode == SC_DOCK_LEFT)
-                        ? snapAlgorithm.getPreviousTarget(currentTarget)
-                        : snapAlgorithm.getNextTarget(currentTarget);
-                dividerView.startDragging(true /* animate */, false /* touching */);
-                dividerView.stopDragging(target.position, 0f, false /* avoidDismissStart */,
-                        true /* logMetrics */);
-                return;
-            } else {
-                splitScreen.splitPrimaryTask();
-            }
-        });
+        // TODO(b/220262470) : implement it with new split screen.
     }
 }
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 645c5ac..5932a64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -23,7 +23,7 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 
-import static com.android.systemui.statusbar.phone.StatusBar.ONLY_CORE_APPS;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.ONLY_CORE_APPS;
 
 import android.annotation.Nullable;
 import android.app.ITransientNotificationCallback;
@@ -310,11 +310,11 @@
                 long requestId, @BiometricMultiSensorMode int multiSensorConfig) {
         }
 
-        /** @see IStatusBar#onBiometricAuthenticated() */
-        default void onBiometricAuthenticated() {
+        /** @see IStatusBar#onBiometricAuthenticated(int) */
+        default void onBiometricAuthenticated(@Modality int modality) {
         }
 
-        /** @see IStatusBar#onBiometricHelp(String) */
+        /** @see IStatusBar#onBiometricHelp(int, String) */
         default void onBiometricHelp(@Modality int modality, String message) {
         }
 
@@ -963,9 +963,11 @@
     }
 
     @Override
-    public void onBiometricAuthenticated() {
+    public void onBiometricAuthenticated(@Modality int modality) {
         synchronized (mLock) {
-            mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget();
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = modality;
+            mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED, args).sendToTarget();
         }
     }
 
@@ -1465,9 +1467,11 @@
                     break;
                 }
                 case MSG_BIOMETRIC_AUTHENTICATED: {
+                    SomeArgs someArgs = (SomeArgs) msg.obj;
                     for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).onBiometricAuthenticated();
+                        mCallbacks.get(i).onBiometricAuthenticated(someArgs.argi1 /* modality */);
                     }
+                    someArgs.recycle();
                     break;
                 }
                 case MSG_BIOMETRIC_HELP: {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 0509a7c..ccec0c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -50,6 +50,7 @@
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.BatteryManager;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.UserHandle;
@@ -122,7 +123,7 @@
     private final Context mContext;
     private final BroadcastDispatcher mBroadcastDispatcher;
     private final KeyguardStateController mKeyguardStateController;
-    private final StatusBarStateController mStatusBarStateController;
+    protected final StatusBarStateController mStatusBarStateController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private ViewGroup mIndicationArea;
     private KeyguardIndicationTextView mTopIndicationView;
@@ -138,6 +139,7 @@
     private final IActivityManager mIActivityManager;
     private final FalsingManager mFalsingManager;
     private final KeyguardBypassController mKeyguardBypassController;
+    private final Handler mHandler;
 
     protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
     private BroadcastReceiver mBroadcastReceiver;
@@ -194,7 +196,9 @@
      * Creates a new KeyguardIndicationController and registers callbacks.
      */
     @Inject
-    public KeyguardIndicationController(Context context,
+    public KeyguardIndicationController(
+            Context context,
+            @Main Looper mainLooper,
             WakeLock.Builder wakeLockBuilder,
             KeyguardStateController keyguardStateController,
             StatusBarStateController statusBarStateController,
@@ -230,6 +234,19 @@
         mKeyguardBypassController = keyguardBypassController;
         mScreenLifecycle = screenLifecycle;
         mScreenLifecycle.addObserver(mScreenObserver);
+
+        mHandler = new Handler(mainLooper) {
+            @Override
+            public void handleMessage(Message msg) {
+                if (msg.what == MSG_HIDE_TRANSIENT) {
+                    hideTransientIndication();
+                } else if (msg.what == MSG_SHOW_ACTION_TO_UNLOCK) {
+                    showActionToUnlock();
+                } else if (msg.what == MSG_HIDE_BIOMETRIC_MESSAGE) {
+                    hideBiometricMessage();
+                }
+            }
+        };
     }
 
     /** Call this after construction to finish setting up the instance. */
@@ -242,7 +259,6 @@
         mDockManager.addAlignmentStateListener(
                 alignState -> mHandler.post(() -> handleAlignStateChanged(alignState)));
         mKeyguardUpdateMonitor.registerCallback(getKeyguardCallback());
-        mKeyguardUpdateMonitor.registerCallback(mTickReceiver);
         mStatusBarStateController.addCallback(mStatusBarStateListener);
         mKeyguardStateController.addCallback(mKeyguardStateCallback);
 
@@ -260,7 +276,7 @@
             mLockScreenIndicationView,
             mExecutor,
             mStatusBarStateController);
-        updateIndication(false /* animate */);
+        updateDeviceEntryIndication(false /* animate */);
         updateOrganizedOwnedDevice();
         if (mBroadcastReceiver == null) {
             // Update the disclosure proactively to avoid IPC on the critical path.
@@ -288,7 +304,7 @@
         }
         if (!alignmentIndication.equals(mAlignmentIndication)) {
             mAlignmentIndication = alignmentIndication;
-            updateIndication(false);
+            updateDeviceEntryIndication(false);
         }
     }
 
@@ -309,28 +325,30 @@
         return mUpdateMonitorCallback;
     }
 
-    /**
-     * This method also doesn't update transient messages like biometrics since those messages
-     * are also updated separately.
-     */
-    private void updatePersistentIndications(boolean animate, int userId) {
-        updateDisclosure();
-        updateOwnerInfo();
-        updateBattery(animate);
-        updateUserLocked(userId);
-        updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication());
-        updateAlignment();
-        updateLogoutView();
-        updateResting();
+    private void updateLockScreenIndications(boolean animate, int userId) {
+        // update transient messages:
+        updateBiometricMessage();
+        updateTransient();
+
+        // Update persistent messages. The following methods should only be called if we're on the
+        // lock screen:
+        updateLockScreenDisclosureMsg();
+        updateLockScreenOwnerInfo();
+        updateLockScreenBatteryMsg(animate);
+        updateLockScreenUserLockedMsg(userId);
+        updateLockScreenTrustMsg(userId, getTrustGrantedIndication(), getTrustManagedIndication());
+        updateLockScreenAlignmentMsg();
+        updateLockScreenLogoutView();
+        updateLockScreenRestingMsg();
     }
 
     private void updateOrganizedOwnedDevice() {
         // avoid calling this method since it has an IPC
         mOrganizationOwnedDevice = whitelistIpcs(this::isOrganizationOwnedDevice);
-        updatePersistentIndications(false, KeyguardUpdateMonitor.getCurrentUser());
+        updateDeviceEntryIndication(false);
     }
 
-    private void updateDisclosure() {
+    private void updateLockScreenDisclosureMsg() {
         if (mOrganizationOwnedDevice) {
             mBackgroundExecutor.execute(() -> {
                 final CharSequence organizationName = getOrganizationOwnedDeviceOrganizationName();
@@ -374,7 +392,7 @@
         }
     }
 
-    private void updateOwnerInfo() {
+    private void updateLockScreenOwnerInfo() {
         // Check device owner info on a bg thread.
         // It makes multiple IPCs that could block the thread it's run on.
         mBackgroundExecutor.execute(() -> {
@@ -406,7 +424,7 @@
         });
     }
 
-    private void updateBattery(boolean animate) {
+    private void updateLockScreenBatteryMsg(boolean animate) {
         if (mPowerPluggedIn || mEnableBatteryDefender) {
             String powerIndication = computePowerIndication();
             if (DEBUG_CHARGING_SPEED) {
@@ -426,7 +444,7 @@
         }
     }
 
-    private void updateUserLocked(int userId) {
+    private void updateLockScreenUserLockedMsg(int userId) {
         if (!mKeyguardUpdateMonitor.isUserUnlocked(userId)) {
             mRotateTextViewController.updateIndication(
                     INDICATION_TYPE_USER_LOCKED,
@@ -442,6 +460,11 @@
     }
 
     private void updateBiometricMessage() {
+        if (mDozing) {
+            updateDeviceEntryIndication(false);
+            return;
+        }
+
         if (!TextUtils.isEmpty(mBiometricMessage)) {
             mRotateTextViewController.updateIndication(
                     INDICATION_TYPE_BIOMETRIC_MESSAGE,
@@ -455,25 +478,22 @@
         } else {
             mRotateTextViewController.hideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE);
         }
-
-        if (mDozing) {
-            updateIndication(false);
-        }
     }
 
     private void updateTransient() {
+        if (mDozing) {
+            updateDeviceEntryIndication(false);
+            return;
+        }
+
         if (!TextUtils.isEmpty(mTransientIndication)) {
             mRotateTextViewController.showTransient(mTransientIndication);
         } else {
             mRotateTextViewController.hideTransient();
         }
-
-        if (mDozing) {
-            updateIndication(false);
-        }
     }
 
-    private void updateTrust(int userId, CharSequence trustGrantedIndication,
+    private void updateLockScreenTrustMsg(int userId, CharSequence trustGrantedIndication,
             CharSequence trustManagedIndication) {
         if (!TextUtils.isEmpty(trustGrantedIndication)
                 && mKeyguardUpdateMonitor.getUserHasTrust(userId)) {
@@ -499,7 +519,7 @@
         }
     }
 
-    private void updateAlignment() {
+    private void updateLockScreenAlignmentMsg() {
         if (!TextUtils.isEmpty(mAlignmentIndication)) {
             mRotateTextViewController.updateIndication(
                     INDICATION_TYPE_ALIGNMENT,
@@ -514,7 +534,7 @@
         }
     }
 
-    private void updateResting() {
+    private void updateLockScreenRestingMsg() {
         if (!TextUtils.isEmpty(mRestingIndication)
                 && !mRotateTextViewController.hasIndications()) {
             mRotateTextViewController.updateIndication(
@@ -529,7 +549,7 @@
         }
     }
 
-    private void updateLogoutView() {
+    private void updateLockScreenLogoutView() {
         final boolean shouldShowLogout = mKeyguardUpdateMonitor.isLogoutEnabled()
                 && KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
         if (shouldShowLogout) {
@@ -608,7 +628,7 @@
             if (!mHandler.hasMessages(MSG_HIDE_TRANSIENT)) {
                 hideTransientIndication();
             }
-            updateIndication(false);
+            updateDeviceEntryIndication(false);
         } else if (!visible) {
             // If we unlock and return to keyguard quickly, previous error should not be shown
             hideTransientIndication();
@@ -620,7 +640,7 @@
      */
     public void setRestingIndication(String restingIndication) {
         mRestingIndication = restingIndication;
-        updateIndication(false);
+        updateDeviceEntryIndication(false);
     }
 
     /**
@@ -697,6 +717,10 @@
      * Shows {@param biometricMessage} until it is hidden by {@link #hideBiometricMessage}.
      */
     private void showBiometricMessage(CharSequence biometricMessage) {
+        if (TextUtils.equals(biometricMessage, mBiometricMessage)) {
+            return;
+        }
+
         mBiometricMessage = biometricMessage;
 
         mHandler.removeMessages(MSG_SHOW_ACTION_TO_UNLOCK);
@@ -725,7 +749,12 @@
         }
     }
 
-    protected final void updateIndication(boolean animate) {
+    /**
+     * Updates message shown to the user. If the device is dozing, a single message with the highest
+     * precedence is shown. If the device is not dozing (on the lock screen), then several messages
+     * may continuously be cycled through.
+     */
+    protected final void updateDeviceEntryIndication(boolean animate) {
         if (!mVisible) {
             return;
         }
@@ -734,44 +763,37 @@
         mIndicationArea.setVisibility(VISIBLE);
 
         // Walk down a precedence-ordered list of what indication
-        // should be shown based on user or device state
-        // AoD
+        // should be shown based on device state
         if (mDozing) {
             mLockScreenIndicationView.setVisibility(View.GONE);
             mTopIndicationView.setVisibility(VISIBLE);
             // When dozing we ignore any text color and use white instead, because
             // colors can be hard to read in low brightness.
             mTopIndicationView.setTextColor(Color.WHITE);
+
+            CharSequence newIndication = null;
             if (!TextUtils.isEmpty(mBiometricMessage)) {
-                mWakeLock.setAcquired(true);
-                mTopIndicationView.switchIndication(mBiometricMessage, null,
-                        true, () -> mWakeLock.setAcquired(false));
+                newIndication = mBiometricMessage;
             } else if (!TextUtils.isEmpty(mTransientIndication)) {
-                mWakeLock.setAcquired(true);
-                mTopIndicationView.switchIndication(mTransientIndication, null,
-                        true, () -> mWakeLock.setAcquired(false));
+                newIndication = mTransientIndication;
             } else if (!mBatteryPresent) {
                 // If there is no battery detected, hide the indication and bail
                 mIndicationArea.setVisibility(GONE);
+                return;
             } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
-                mTopIndicationView.switchIndication(mAlignmentIndication, null,
-                        false /* animate */, null /* onAnimationEndCallback */);
+                newIndication = mAlignmentIndication;
                 mTopIndicationView.setTextColor(mContext.getColor(R.color.misalignment_text_color));
             } else if (mPowerPluggedIn || mEnableBatteryDefender) {
-                String indication = computePowerIndication();
-                if (animate) {
-                    mWakeLock.setAcquired(true);
-                    mTopIndicationView.switchIndication(indication, null, true /* animate */,
-                            () -> mWakeLock.setAcquired(false));
-                } else {
-                    mTopIndicationView.switchIndication(indication, null, false /* animate */,
-                            null /* onAnimationEndCallback */);
-                }
+                newIndication = computePowerIndication();
             } else {
-                String percentage = NumberFormat.getPercentInstance()
+                newIndication = NumberFormat.getPercentInstance()
                         .format(mBatteryLevel / 100f);
-                mTopIndicationView.switchIndication(percentage, null /* indication */,
-                        false /* animate */, null /* onAnimationEnd*/);
+            }
+
+            if (!TextUtils.equals(mTopIndicationView.getText(), newIndication)) {
+                mWakeLock.setAcquired(true);
+                mTopIndicationView.switchIndication(newIndication, null,
+                        true, () -> mWakeLock.setAcquired(false));
             }
             return;
         }
@@ -780,7 +802,7 @@
         mTopIndicationView.setVisibility(GONE);
         mTopIndicationView.setText(null);
         mLockScreenIndicationView.setVisibility(View.VISIBLE);
-        updatePersistentIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
+        updateLockScreenIndications(animate, KeyguardUpdateMonitor.getCurrentUser());
     }
 
     protected String computePowerIndication() {
@@ -842,29 +864,6 @@
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
     }
 
-    private final KeyguardUpdateMonitorCallback mTickReceiver =
-            new KeyguardUpdateMonitorCallback() {
-                @Override
-                public void onTimeChanged() {
-                    if (mVisible) {
-                        updateIndication(false /* animate */);
-                    }
-                }
-            };
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == MSG_HIDE_TRANSIENT) {
-                hideTransientIndication();
-            } else if (msg.what == MSG_SHOW_ACTION_TO_UNLOCK) {
-                showActionToUnlock();
-            } else if (msg.what == MSG_HIDE_BIOMETRIC_MESSAGE) {
-                hideBiometricMessage();
-            }
-        }
-    };
-
     /**
      * Show message on the keyguard for how the user can unlock/enter their device.
      */
@@ -929,7 +928,7 @@
         pw.println("  mBiometricMessage: " + mBiometricMessage);
         pw.println("  mBatteryLevel: " + mBatteryLevel);
         pw.println("  mBatteryPresent: " + mBatteryPresent);
-        pw.println("  mTextView.getText(): " + (
+        pw.println("  AOD text: " + (
                 mTopIndicationView == null ? null : mTopIndicationView.getText()));
         pw.println("  computePowerIndication(): " + computePowerIndication());
         pw.println("  trustGrantedIndication: " + getTrustGrantedIndication());
@@ -940,6 +939,13 @@
         public static final int HIDE_DELAY_MS = 5000;
 
         @Override
+        public void onTimeChanged() {
+            if (mVisible) {
+                updateDeviceEntryIndication(false /* animate */);
+            }
+        }
+
+        @Override
         public void onRefreshBatteryInfo(BatteryStatus status) {
             boolean isChargingOrFull = status.status == BatteryManager.BATTERY_STATUS_CHARGING
                     || status.isCharged();
@@ -962,7 +968,7 @@
                 Log.e(TAG, "Error calling IBatteryStats: ", e);
                 mChargingTimeRemaining = -1;
             }
-            updateIndication(!wasPluggedIn && mPowerPluggedInWired);
+            updateDeviceEntryIndication(!wasPluggedIn && mPowerPluggedInWired);
             if (mDozing) {
                 if (!wasPluggedIn && mPowerPluggedIn) {
                     showTransientIndication(computePowerIndication());
@@ -1084,14 +1090,13 @@
             if (KeyguardUpdateMonitor.getCurrentUser() != userId) {
                 return;
             }
-            updateTrust(userId, getTrustGrantedIndication(), getTrustManagedIndication());
+            updateDeviceEntryIndication(false);
         }
 
         @Override
         public void showTrustGrantedMessage(CharSequence message) {
             mTrustGrantedIndication = message;
-            updateTrust(KeyguardUpdateMonitor.getCurrentUser(), getTrustGrantedIndication(),
-                    getTrustManagedIndication());
+            updateDeviceEntryIndication(false);
         }
 
         @Override
@@ -1125,21 +1130,21 @@
         @Override
         public void onUserSwitchComplete(int userId) {
             if (mVisible) {
-                updateIndication(false);
+                updateDeviceEntryIndication(false);
             }
         }
 
         @Override
         public void onUserUnlocked() {
             if (mVisible) {
-                updateIndication(false);
+                updateDeviceEntryIndication(false);
             }
         }
 
         @Override
         public void onLogoutEnabledChanged() {
             if (mVisible) {
-                updateIndication(false);
+                updateDeviceEntryIndication(false);
             }
         }
 
@@ -1167,7 +1172,7 @@
             if (mDozing) {
                 hideBiometricMessage();
             }
-            updateIndication(false);
+            updateDeviceEntryIndication(false);
         }
     };
 
@@ -1175,7 +1180,7 @@
             new KeyguardStateController.Callback() {
         @Override
         public void onUnlockedChanged() {
-            updateIndication(false);
+            updateDeviceEntryIndication(false);
         }
 
         @Override
@@ -1185,7 +1190,7 @@
                 mTopIndicationView.clearMessages();
                 mRotateTextViewController.clearMessages();
             } else {
-                updatePersistentIndications(false, KeyguardUpdateMonitor.getCurrentUser());
+                updateDeviceEntryIndication(false);
             }
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 8366bdd..1ab0345 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -38,7 +38,7 @@
 import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
 import com.android.systemui.statusbar.phone.NotificationPanelViewController
 import com.android.systemui.statusbar.phone.ScrimController
-import com.android.systemui.statusbar.phone.StatusBar
+import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.Utils
 import java.io.FileDescriptor
@@ -73,7 +73,7 @@
     private var useSplitShade: Boolean = false
     private lateinit var nsslController: NotificationStackScrollLayoutController
     lateinit var notificationPanelController: NotificationPanelViewController
-    lateinit var statusbar: StatusBar
+    lateinit var centralSurfaces: CentralSurfaces
     lateinit var qS: QS
 
     /**
@@ -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)
     }
 
@@ -197,7 +253,7 @@
         // Bind the click listener of the shelf to go to the full shade
         notificationShelfController.setOnClickListener {
             if (statusBarStateController.state == StatusBarState.KEYGUARD) {
-                statusbar.wakeUpIfDozing(SystemClock.uptimeMillis(), it, "SHADE_CLICK")
+                centralSurfaces.wakeUpIfDozing(SystemClock.uptimeMillis(), it, "SHADE_CLICK")
                 goToLockedShade(it)
             }
         }
@@ -224,7 +280,7 @@
             if (nsslController.isInLockedDownShade()) {
                 logger.logDraggedDownLockDownShade(startingChild)
                 statusBarStateController.setLeaveOpenOnKeyguardHide(true)
-                statusbar.dismissKeyguardThenExecute(OnDismissAction {
+                centralSurfaces.dismissKeyguardThenExecute(OnDismissAction {
                     nextHideKeyguardNeedsNoAnimation = true
                     false
                 }, cancelRunnable, false /* afterKeyguardGone */)
@@ -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,14 +394,17 @@
             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 */)
-                    // TODO: appear media also in split shade
-                    val mediaAmount = if (useSplitShade) 0f else field
-                    mediaHierarchyManager.setTransitionToFullShadeAmount(mediaAmount)
+
+                    mediaHierarchyManager.setTransitionToFullShadeAmount(field)
                     transitionToShadeAmountCommon(field)
                 }
             }
@@ -359,11 +419,23 @@
     private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
         val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
         scrimController.setTransitionToFullShadeProgress(scrimProgress)
+
         // Fade out all content only visible on the lockscreen
-        notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - scrimProgress)
-        depthController.transitionToFullShadeProgress = scrimProgress
-        udfpsKeyguardViewController?.setTransitionToFullShadeProgress(scrimProgress)
-        statusbar.setTransitionToFullShadeProgress(scrimProgress)
+        val npvcProgress =
+            MathUtils.saturate(dragDownAmount / npvcKeyguardContentAlphaTransitionDistance)
+        notificationPanelController.setKeyguardOnlyContentAlpha(1.0f - npvcProgress)
+
+        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 setDragDownAmountAnimated(
@@ -406,9 +478,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
         }
@@ -463,7 +536,7 @@
         animationHandler: ((Long) -> Unit)? = null,
         cancelAction: Runnable? = null
     ) {
-        if (statusbar.isShadeDisabled) {
+        if (centralSurfaces.isShadeDisabled) {
             cancelAction?.run()
             logger.logShadeDisabledOnGoToLockedShade()
             return
@@ -505,7 +578,7 @@
                 cancelAction?.run()
             }
             logger.logShowBouncerOnGoToLockedShade()
-            statusbar.showBouncerWithDimissAndCancelIfKeyguard(onDismissAction, cancelHandler)
+            centralSurfaces.showBouncerWithDimissAndCancelIfKeyguard(onDismissAction, cancelHandler)
             draggedDownEntry = entry
         } else {
             logger.logGoingToLockedShade(animationHandler != null)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 01bdb40..68d35f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -32,10 +32,10 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.statusbar.dagger.StatusBarModule;
+import com.android.systemui.statusbar.dagger.CentralSurfacesModule;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.util.time.SystemClock;
 
 import java.util.ArrayList;
@@ -54,7 +54,7 @@
 @SuppressLint("OverrideAbstract")
 public class NotificationListener extends NotificationListenerWithPlugins {
     private static final String TAG = "NotificationListener";
-    private static final boolean DEBUG = StatusBar.DEBUG;
+    private static final boolean DEBUG = CentralSurfaces.DEBUG;
     private static final long MAX_RANKING_DELAY_MILLIS = 500L;
 
     private final Context mContext;
@@ -69,7 +69,7 @@
     private long mSkippingRankingUpdatesSince = -1;
 
     /**
-     * Injected constructor. See {@link StatusBarModule}.
+     * Injected constructor. See {@link CentralSurfacesModule}.
      */
     @Inject
     public NotificationListener(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 3730d12..052c57e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -16,9 +16,9 @@
 package com.android.systemui.statusbar;
 
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
-import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_MEDIA_FAKE_ARTWORK;
-import static com.android.systemui.statusbar.phone.StatusBar.ENABLE_LOCKSCREEN_WALLPAPER;
-import static com.android.systemui.statusbar.phone.StatusBar.SHOW_LOCKSCREEN_MEDIA_ARTWORK;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG_MEDIA_FAKE_ARTWORK;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.ENABLE_LOCKSCREEN_WALLPAPER;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.SHOW_LOCKSCREEN_MEDIA_ARTWORK;
 
 import android.annotation.MainThread;
 import android.annotation.NonNull;
@@ -55,7 +55,7 @@
 import com.android.systemui.media.MediaDataManager;
 import com.android.systemui.media.SmartspaceMediaData;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.dagger.StatusBarModule;
+import com.android.systemui.statusbar.dagger.CentralSurfacesModule;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -66,11 +66,11 @@
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.LockscreenWallpaper;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ScrimState;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.Utils;
 import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -131,7 +131,7 @@
 
     private final Context mContext;
     private final ArrayList<MediaListener> mMediaListeners;
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final MediaArtworkProcessor mMediaArtworkProcessor;
     private final Set<AsyncTask<?, ?, ?>> mProcessArtworkTasks = new ArraySet<>();
 
@@ -172,11 +172,11 @@
     };
 
     /**
-     * Injected constructor. See {@link StatusBarModule}.
+     * Injected constructor. See {@link CentralSurfacesModule}.
      */
     public NotificationMediaManager(
             Context context,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             Lazy<NotificationShadeWindowController> notificationShadeWindowController,
             NotificationVisibilityProvider visibilityProvider,
             NotificationEntryManager notificationEntryManager,
@@ -193,7 +193,7 @@
         mKeyguardBypassController = keyguardBypassController;
         mMediaListeners = new ArrayList<>();
         // TODO: use KeyguardStateController#isOccluded to remove this dependency
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mNotificationShadeWindowController = notificationShadeWindowController;
         mVisibilityProvider = visibilityProvider;
         mEntryManager = notificationEntryManager;
@@ -575,7 +575,7 @@
      * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
      */
     public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
-        Trace.beginSection("StatusBar#updateMediaMetaData");
+        Trace.beginSection("CentralSurfaces#updateMediaMetaData");
         if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) {
             Trace.endSection();
             return;
@@ -653,7 +653,8 @@
         NotificationShadeWindowController windowController =
                 mNotificationShadeWindowController.get();
         boolean hideBecauseOccluded =
-                mStatusBarOptionalLazy.get().map(StatusBar::isOccluded).orElse(false);
+                mCentralSurfacesOptionalLazy.get()
+                        .map(CentralSurfaces::isOccluded).orElse(false);
 
         final boolean hasArtwork = artworkDrawable != null;
         mColorExtractor.setHasMediaArtwork(hasMediaArtwork);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
index 17bf346..3b3b5a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
@@ -19,7 +19,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 
 /**
- * An abstraction of something that presents notifications, e.g. StatusBar. Contains methods
+ * An abstraction of something that presents notifications, e.g. CentralSurfaces. Contains methods
  * for both querying the state of the system (some modularised piece of functionality may
  * want to act differently based on e.g. whether the presenter is visible to the user or not) and
  * for affecting the state of the system (e.g. starting an intent, given that the presenter may
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 2b5453a..94a6d3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -55,7 +55,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.dagger.StatusBarDependenciesModule;
+import com.android.systemui.statusbar.dagger.CentralSurfacesDependenciesModule;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -64,7 +64,7 @@
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 import com.android.systemui.statusbar.policy.RemoteInputView;
 import com.android.systemui.util.DumpUtilsKt;
@@ -103,7 +103,7 @@
     private final Handler mMainHandler;
     private final ActionClickLogger mLogger;
 
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
 
     protected final Context mContext;
     protected final NotifPipelineFlags mNotifPipelineFlags;
@@ -125,8 +125,8 @@
         @Override
         public boolean onInteraction(
                 View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) {
-            mStatusBarOptionalLazy.get().ifPresent(
-                    statusBar -> statusBar.wakeUpIfDozing(
+            mCentralSurfacesOptionalLazy.get().ifPresent(
+                    centralSurfaces -> centralSurfaces.wakeUpIfDozing(
                             SystemClock.uptimeMillis(), view, "NOTIFICATION_CLICK"));
 
             final NotificationEntry entry = getNotificationForParent(view.getParent());
@@ -253,7 +253,7 @@
     };
 
     /**
-     * Injected constructor. See {@link StatusBarDependenciesModule}.
+     * Injected constructor. See {@link CentralSurfacesDependenciesModule}.
      */
     public NotificationRemoteInputManager(
             Context context,
@@ -263,7 +263,7 @@
             NotificationVisibilityProvider visibilityProvider,
             NotificationEntryManager notificationEntryManager,
             RemoteInputNotificationRebuilder rebuilder,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             StatusBarStateController statusBarStateController,
             @Main Handler mainHandler,
             RemoteInputUriController remoteInputUriController,
@@ -276,7 +276,7 @@
         mSmartReplyController = smartReplyController;
         mVisibilityProvider = visibilityProvider;
         mEntryManager = notificationEntryManager;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mMainHandler = mainHandler;
         mLogger = logger;
         mBarService = IStatusBarService.Stub.asInterface(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java
index 4f70fdb..3b1fa17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelfController.java
@@ -18,6 +18,7 @@
 
 import android.view.View;
 
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
@@ -25,7 +26,6 @@
 import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
-import com.android.systemui.statusbar.phone.StatusBarNotificationPresenter;
 
 import javax.inject.Inject;
 
@@ -114,8 +114,8 @@
         return mView.getIntrinsicHeight();
     }
 
-    public void setOnActivatedListener(StatusBarNotificationPresenter presenter) {
-        mView.setOnActivatedListener(presenter);
+    public void setOnActivatedListener(ActivatableNotificationView.OnActivatedListener listener) {
+        mView.setOnActivatedListener(listener);
     }
 
     public void setOnClickListener(View.OnClickListener onClickListener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 092e86d..054543c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -32,7 +32,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.dagger.StatusBarModule;
+import com.android.systemui.statusbar.dagger.CentralSurfacesModule;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
 import com.android.systemui.statusbar.notification.DynamicChildBindController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
@@ -45,7 +45,6 @@
 import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
 import com.android.systemui.statusbar.notification.collection.render.NotifStats;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -97,7 +96,6 @@
     private final Optional<Bubbles> mBubblesOptional;
     private final DynamicPrivacyController mDynamicPrivacyController;
     private final KeyguardBypassController mBypassController;
-    private final ForegroundServiceSectionController mFgsSectionController;
     private final NotifPipelineFlags mNotifPipelineFlags;
     private AssistantFeedbackController mAssistantFeedbackController;
     private final KeyguardStateController mKeyguardStateController;
@@ -115,7 +113,7 @@
     private boolean mIsHandleDynamicPrivacyChangeScheduled;
 
     /**
-     * Injected constructor. See {@link StatusBarModule}.
+     * Injected constructor. See {@link CentralSurfacesModule}.
      */
     public NotificationViewHierarchyManager(
             Context context,
@@ -129,7 +127,6 @@
             KeyguardBypassController bypassController,
             Optional<Bubbles> bubblesOptional,
             DynamicPrivacyController privacyController,
-            ForegroundServiceSectionController fgsSectionController,
             DynamicChildBindController dynamicChildBindController,
             LowPriorityInflationHelper lowPriorityInflationHelper,
             AssistantFeedbackController assistantFeedbackController,
@@ -145,7 +142,6 @@
         mVisualStabilityManager = visualStabilityManager;
         mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController;
         mEntryManager = notificationEntryManager;
-        mFgsSectionController = fgsSectionController;
         mNotifPipelineFlags = notifPipelineFlags;
         Resources res = context.getResources();
         mAlwaysExpandNonGroupedNotification =
@@ -417,8 +413,7 @@
                 && mBubblesOptional.get().isBubbleNotificationSuppressedFromShade(
                         ent.getKey(), ent.getSbn().getGroupKey());
         if (ent.isRowDismissed() || ent.isRowRemoved()
-                || isBubbleNotificationSuppressedFromShade
-                || mFgsSectionController.hasEntry(ent)) {
+                || isBubbleNotificationSuppressedFromShade) {
             // we want to suppress removed notifications because they could
             // temporarily become children if they were isolated before.
             return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateController.java
index 2e1762a..7807738 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateController.java
@@ -20,17 +20,17 @@
 
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 /**
  * Calculates and moves the QS frame vertically.
  */
 public abstract class QsFrameTranslateController {
 
-    protected StatusBar mStatusBar;
+    protected CentralSurfaces mCentralSurfaces;
 
-    public QsFrameTranslateController(StatusBar statusBar) {
-        mStatusBar = statusBar;
+    public QsFrameTranslateController(CentralSurfaces centralSurfaces) {
+        mCentralSurfaces = centralSurfaces;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateImpl.java
index c156797..33e2245 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/QsFrameTranslateImpl.java
@@ -21,7 +21,7 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import javax.inject.Inject;
 
@@ -32,8 +32,8 @@
 public class QsFrameTranslateImpl extends QsFrameTranslateController {
 
     @Inject
-    public QsFrameTranslateImpl(StatusBar statusBar) {
-        super(statusBar);
+    public QsFrameTranslateImpl(CentralSurfaces centralSurfaces) {
+        super(centralSurfaces);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
index 4ad01aa..058edda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SmartReplyController.java
@@ -25,7 +25,7 @@
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dumpable;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.statusbar.dagger.StatusBarModule;
+import com.android.systemui.statusbar.dagger.CentralSurfacesModule;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 
@@ -45,7 +45,7 @@
     private Callback mCallback;
 
     /**
-     * Injected constructor. See {@link StatusBarModule}.
+     * Injected constructor. See {@link CentralSurfacesModule}.
      */
     public SmartReplyController(
             DumpManager dumpManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 02870a3..2763bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -420,8 +420,9 @@
      * notified before unranked, and we will sort ranked listeners from low to high
      *
      * @deprecated This method exists only to solve latent inter-dependencies from refactoring
-     * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking
-     * (i.e., they are non-dependent on the order of operations of StatusBarState listeners).
+     * StatusBarState out of CentralSurfaces.java. Any new listeners should be built not to need
+     * ranking (i.e., they are non-dependent on the order of operations of StatusBarState
+     * listeners).
      */
     @Deprecated
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index f0b2c2d..2b31901 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -25,7 +25,7 @@
 import android.view.WindowInsetsController.Behavior;
 
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.lang.annotation.Retention;
 
@@ -51,8 +51,9 @@
      * notified before unranked, and we will sort ranked listeners from low to high
      *
      * @deprecated This method exists only to solve latent inter-dependencies from refactoring
-     * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking
-     * (i.e., they are non-dependent on the order of operations of StatusBarState listeners).
+     * StatusBarState out of CentralSurfaces.java. Any new listeners should be built not to need
+     * ranking (i.e., they are non-dependent on the order of operations of StatusBarState
+     * listeners).
      */
     @Deprecated
     void addCallback(StateListener listener, int rank);
@@ -91,7 +92,7 @@
     int getCurrentOrUpcomingState();
 
     /**
-     * Update the dozing state from {@link StatusBar}'s perspective
+     * Update the dozing state from {@link CentralSurfaces}'s perspective
      * @param isDozing well, are we dozing?
      * @return {@code true} if the state changed, else {@code false}
      */
@@ -116,7 +117,7 @@
     void setAndInstrumentDozeAmount(View view, float dozeAmount, boolean animated);
 
     /**
-     * Update the expanded state from {@link StatusBar}'s perspective
+     * Update the expanded state from {@link CentralSurfaces}'s perspective
      * @param expanded are we expanded?
      * @return {@code true} if the state changed, else {@code false}
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
index 48717e2..5df593b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
@@ -175,7 +175,7 @@
         val width = displayMetrics.widthPixels
         val height = displayMetrics.heightPixels
         rippleView.radius = Integer.max(width, height).toFloat()
-        rippleView.origin = when (RotationUtils.getRotation(context)) {
+        rippleView.origin = when (RotationUtils.getExactRotation(context)) {
             RotationUtils.ROTATION_LANDSCAPE -> {
                 PointF(width * normalizedPortPosY, height * (1 - normalizedPortPosX))
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
index fe5a699..41d2b65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java
@@ -843,7 +843,7 @@
         }
     }
 
-    /** Box for StatusBar icon info */
+    /** Box for status bar icon info */
     private static final class SbInfo {
         final boolean showTriangle;
         final int ratTypeIcon;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
index 300c3a2..4c11307 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java
@@ -251,10 +251,10 @@
                 broadcastDispatcher,
                 demoModeController,
                 carrierConfigTracker,
+                handler,
                 featureFlags,
                 dumpManager);
         mReceiverHandler.post(mRegisterListeners);
-        mMainHandler = handler;
         mInternetDialogFactory = internetDialogFactory;
     }
 
@@ -274,12 +274,14 @@
             BroadcastDispatcher broadcastDispatcher,
             DemoModeController demoModeController,
             CarrierConfigTracker carrierConfigTracker,
+            @Main Handler handler,
             FeatureFlags featureFlags,
             DumpManager dumpManager
     ) {
         mContext = context;
         mTelephonyListenerManager = telephonyListenerManager;
         mConfig = config;
+        mMainHandler = handler;
         mReceiverHandler = new Handler(bgLooper);
         mBgLooper = bgLooper;
         mBgExecutor = bgExecutor;
@@ -315,7 +317,8 @@
             }
         });
         mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
-                mCallbackHandler, this, mWifiManager, mConnectivityManager, networkScoreManager);
+                mCallbackHandler, this, mWifiManager, mConnectivityManager, networkScoreManager,
+                mMainHandler, mReceiverHandler);
 
         mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
index 2b924a4..b80df4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java
@@ -25,6 +25,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkScoreManager;
 import android.net.wifi.WifiManager;
+import android.os.Handler;
 import android.text.Html;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -34,6 +35,8 @@
 import com.android.settingslib.mobile.TelephonyIcons;
 import com.android.settingslib.wifi.WifiStatusTracker;
 import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.util.Assert;
 
 import java.io.PrintWriter;
@@ -53,12 +56,14 @@
             NetworkControllerImpl networkController,
             WifiManager wifiManager,
             ConnectivityManager connectivityManager,
-            NetworkScoreManager networkScoreManager) {
+            NetworkScoreManager networkScoreManager,
+            @Main Handler handler,
+            @Background Handler backgroundHandler) {
         super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
                 callbackHandler, networkController);
         mWifiManager = wifiManager;
         mWifiTracker = new WifiStatusTracker(mContext, wifiManager, networkScoreManager,
-                connectivityManager, this::handleStatusUpdated);
+                connectivityManager, this::handleStatusUpdated, handler, backgroundHandler);
         mWifiTracker.setListening(true);
         mHasMobileDataFeature = hasMobileDataFeature;
         if (wifiManager != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
index d65fa3a..a62a152 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
@@ -21,18 +21,18 @@
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions
 import com.android.systemui.statusbar.phone.PhoneStatusBarView
 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import java.lang.IllegalStateException
 import javax.inject.Inject
 
 /**
- * Responsible for creating the StatusBar window and initializing the root components of that window
- * (see [CollapsedStatusBarFragment])
+ * Responsible for creating the status bar window and initializing the root components of that
+ * window (see [CollapsedStatusBarFragment])
  */
-@StatusBarScope
+@CentralSurfacesScope
 class StatusBarInitializer @Inject constructor(
     private val windowController: StatusBarWindowController
 ) {
@@ -43,7 +43,7 @@
      * Creates the status bar window and root views, and initializes the component
      */
     fun initializeStatusBar(
-        sbComponent: StatusBarComponent
+        centralSurfacesComponent: CentralSurfacesComponent
     ) {
         windowController.fragmentHostManager.addTagListener(
                 CollapsedStatusBarFragment.TAG,
@@ -64,7 +64,7 @@
                 }).fragmentManager
                 .beginTransaction()
                 .replace(R.id.status_bar_container,
-                        sbComponent.createCollapsedStatusBarFragment(),
+                        centralSurfacesComponent.createCollapsedStatusBarFragment(),
                         CollapsedStatusBarFragment.TAG)
                 .commit()
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index c687e82..83290af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -60,11 +60,10 @@
 import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
-import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
 import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
@@ -88,12 +87,13 @@
 import dagger.Provides;
 
 /**
- * This module provides instances needed to construct {@link StatusBar}. These are moved to this
- * separate from {@link StatusBarModule} module so that components that wish to build their own
- * version of StatusBar can include just dependencies, without injecting StatusBar itself.
+ * This module provides instances needed to construct {@link CentralSurfaces}. These are moved to
+ * this separate from {@link CentralSurfacesModule} module so that components that wish to build
+ * their own version of CentralSurfaces can include just dependencies, without injecting
+ * CentralSurfaces itself.
  */
 @Module
-public interface StatusBarDependenciesModule {
+public interface CentralSurfacesDependenciesModule {
     /** */
     @SysUISingleton
     @Provides
@@ -105,7 +105,7 @@
             NotificationVisibilityProvider visibilityProvider,
             NotificationEntryManager notificationEntryManager,
             RemoteInputNotificationRebuilder rebuilder,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             StatusBarStateController statusBarStateController,
             Handler mainHandler,
             RemoteInputUriController remoteInputUriController,
@@ -120,7 +120,7 @@
                 visibilityProvider,
                 notificationEntryManager,
                 rebuilder,
-                statusBarOptionalLazy,
+                centralSurfacesOptionalLazy,
                 statusBarStateController,
                 mainHandler,
                 remoteInputUriController,
@@ -134,7 +134,7 @@
     @Provides
     static NotificationMediaManager provideNotificationMediaManager(
             Context context,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             Lazy<NotificationShadeWindowController> notificationShadeWindowController,
             NotificationVisibilityProvider visibilityProvider,
             NotificationEntryManager notificationEntryManager,
@@ -148,7 +148,7 @@
             DumpManager dumpManager) {
         return new NotificationMediaManager(
                 context,
-                statusBarOptionalLazy,
+                centralSurfacesOptionalLazy,
                 notificationShadeWindowController,
                 visibilityProvider,
                 notificationEntryManager,
@@ -198,7 +198,6 @@
             KeyguardBypassController bypassController,
             Optional<Bubbles> bubblesOptional,
             DynamicPrivacyController privacyController,
-            ForegroundServiceSectionController fgsSectionController,
             DynamicChildBindController dynamicChildBindController,
             LowPriorityInflationHelper lowPriorityInflationHelper,
             AssistantFeedbackController assistantFeedbackController,
@@ -217,7 +216,6 @@
                 bypassController,
                 bubblesOptional,
                 privacyController,
-                fgsSectionController,
                 dynamicChildBindController,
                 lowPriorityInflationHelper,
                 assistantFeedbackController,
@@ -261,6 +259,7 @@
     @Provides
     @SysUISingleton
     static OngoingCallController provideOngoingCallController(
+            Context context,
             CommonNotifCollection notifCollection,
             SystemClock systemClock,
             ActivityStarter activityStarter,
@@ -284,6 +283,7 @@
                         : Optional.empty();
         OngoingCallController ongoingCallController =
                 new OngoingCallController(
+                        context,
                         notifCollection,
                         ongoingCallFlags,
                         systemClock,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesModule.java
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesModule.java
index ad5ef20..99d4b2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesModule.java
@@ -23,7 +23,7 @@
 import dagger.Module;
 
 /** */
-@Module(includes = {StatusBarPhoneModule.class, StatusBarDependenciesModule.class,
+@Module(includes = {StatusBarPhoneModule.class, CentralSurfacesDependenciesModule.class,
         NotificationsModule.class, NotificationRowModule.class})
-public interface StatusBarModule {
+public interface CentralSurfacesModule {
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartStatusBarModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
similarity index 76%
rename from packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartStatusBarModule.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
index 46c1abb..fe55dea7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartStatusBarModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
@@ -17,17 +17,17 @@
 package com.android.systemui.statusbar.dagger
 
 import com.android.systemui.CoreStartable
-import com.android.systemui.statusbar.phone.StatusBar
+import com.android.systemui.statusbar.phone.CentralSurfaces
 import dagger.Binds
 import dagger.Module
 import dagger.multibindings.ClassKey
 import dagger.multibindings.IntoMap
 
 @Module
-interface StartStatusBarModule {
-    /** Start the StatusBar   */
+interface StartCentralSurfacesModule {
+    /** Start the CentralSurfaces   */
     @Binds
     @IntoMap
-    @ClassKey(StatusBar::class)
-    abstract fun bindsStatusBar(statusBar: StatusBar): CoreStartable
-}
\ No newline at end of file
+    @ClassKey(CentralSurfaces::class)
+    abstract fun bindsCentralSurfaces(centralSurfaces: CentralSurfaces): CoreStartable
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt
new file mode 100644
index 0000000..3a4731a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt
@@ -0,0 +1,110 @@
+/*
+ * 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.gesture
+
+import android.annotation.CallSuper
+import android.os.Looper
+import android.view.Choreographer
+import android.view.Display
+import android.view.InputEvent
+import android.view.MotionEvent
+import com.android.systemui.shared.system.InputChannelCompat
+import com.android.systemui.shared.system.InputMonitorCompat
+
+/**
+ * An abstract class to help detect gestures that occur anywhere on the display (not specific to a
+ * certain view).
+ *
+ * This class handles starting/stopping the gesture detection system as well as
+ * registering/unregistering callbacks for when gestures occur. Note that the class will only listen
+ * for gestures when there's at least one callback registered.
+ *
+ * Subclasses should implement [onInputEvent] to detect their specific gesture. Once a specific
+ * gesture is detected, they should call [onGestureDetected] (which will notify the callbacks).
+ */
+abstract class GenericGestureDetector(
+    private val tag: String
+) {
+    /**
+     * Active callbacks, each associated with a tag. Gestures will only be monitored if
+     * [callbacks.size] > 0.
+     */
+    private val callbacks: MutableMap<String, (MotionEvent) -> Unit> = mutableMapOf()
+
+    private var inputMonitor: InputMonitorCompat? = null
+    private var inputReceiver: InputChannelCompat.InputEventReceiver? = null
+
+    /**
+     * Adds a callback that will be triggered when the tap gesture is detected.
+     *
+     * The callback receive the last motion event in the gesture.
+     */
+    fun addOnGestureDetectedCallback(tag: String, callback: (MotionEvent) -> Unit) {
+        val callbacksWasEmpty = callbacks.isEmpty()
+        callbacks[tag] = callback
+        if (callbacksWasEmpty) {
+            startGestureListening()
+        }
+    }
+
+    /** Removes the callback. */
+    fun removeOnGestureDetectedCallback(tag: String) {
+        callbacks.remove(tag)
+        if (callbacks.isEmpty()) {
+            stopGestureListening()
+        }
+    }
+
+    /** Triggered each time a touch event occurs (and at least one callback is registered). */
+    abstract fun onInputEvent(ev: InputEvent)
+
+    /**
+     * Should be called by subclasses when their specific gesture is detected with the last motion
+     * event in the gesture.
+     */
+    internal fun onGestureDetected(e: MotionEvent) {
+        callbacks.values.forEach { it.invoke(e) }
+    }
+
+    /** Start listening to touch events. */
+    @CallSuper
+    internal open fun startGestureListening() {
+        stopGestureListening()
+
+        inputMonitor = InputMonitorCompat(tag, Display.DEFAULT_DISPLAY).also {
+            inputReceiver = it.getInputReceiver(
+                Looper.getMainLooper(),
+                Choreographer.getInstance(),
+                this::onInputEvent
+            )
+        }
+    }
+
+    /** Stop listening to touch events. */
+    @CallSuper
+    internal open fun stopGestureListening() {
+        inputMonitor?.let {
+            inputMonitor = null
+            it.dispose()
+        }
+        inputReceiver?.let {
+            inputReceiver = null
+            it.dispose()
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
index 7cdf69d..6115819 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
@@ -17,15 +17,13 @@
 package com.android.systemui.statusbar.gesture
 
 import android.content.Context
-import android.os.Looper
-import android.view.Choreographer
-import android.view.Display
 import android.view.InputEvent
 import android.view.MotionEvent
-import android.view.MotionEvent.*
+import android.view.MotionEvent.ACTION_CANCEL
+import android.view.MotionEvent.ACTION_DOWN
+import android.view.MotionEvent.ACTION_MOVE
+import android.view.MotionEvent.ACTION_UP
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.shared.system.InputChannelCompat
-import com.android.systemui.shared.system.InputMonitorCompat
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import javax.inject.Inject
 
@@ -38,43 +36,17 @@
     context: Context,
     private val statusBarWindowController: StatusBarWindowController,
     private val logger: SwipeStatusBarAwayGestureLogger
-) {
-
-    /**
-     * Active callbacks, each associated with a tag. Gestures will only be monitored if
-     * [callbacks.size] > 0.
-     */
-    private val callbacks: MutableMap<String, () -> Unit> = mutableMapOf()
+) : GenericGestureDetector(SwipeStatusBarAwayGestureHandler::class.simpleName!!) {
 
     private var startY: Float = 0f
     private var startTime: Long = 0L
     private var monitoringCurrentTouch: Boolean = false
 
-    private var inputMonitor: InputMonitorCompat? = null
-    private var inputReceiver: InputChannelCompat.InputEventReceiver? = null
-
     private var swipeDistanceThreshold: Int = context.resources.getDimensionPixelSize(
         com.android.internal.R.dimen.system_gestures_start_threshold
     )
 
-    /** Adds a callback that will be triggered when the swipe away gesture is detected. */
-    fun addOnGestureDetectedCallback(tag: String, callback: () -> Unit) {
-        val callbacksWasEmpty = callbacks.isEmpty()
-        callbacks[tag] = callback
-        if (callbacksWasEmpty) {
-            startGestureListening()
-        }
-    }
-
-    /** Removes the callback. */
-    fun removeOnGestureDetectedCallback(tag: String) {
-        callbacks.remove(tag)
-        if (callbacks.isEmpty()) {
-             stopGestureListening()
-        }
-    }
-
-    private fun onInputEvent(ev: InputEvent) {
+    override fun onInputEvent(ev: InputEvent) {
         if (ev !is MotionEvent) {
             return
         }
@@ -108,7 +80,7 @@
                 ) {
                     monitoringCurrentTouch = false
                     logger.logGestureDetected(ev.y.toInt())
-                    callbacks.values.forEach { it.invoke() }
+                    onGestureDetected(ev)
                 }
             }
             ACTION_CANCEL, ACTION_UP -> {
@@ -120,33 +92,15 @@
         }
     }
 
-    /** Start listening for the swipe gesture. */
-    private fun startGestureListening() {
-        stopGestureListening()
-
+    override fun startGestureListening() {
+        super.startGestureListening()
         logger.logInputListeningStarted()
-        inputMonitor = InputMonitorCompat(TAG, Display.DEFAULT_DISPLAY).also {
-            inputReceiver = it.getInputReceiver(
-                Looper.getMainLooper(),
-                Choreographer.getInstance(),
-                this::onInputEvent
-            )
-        }
     }
 
-    /** Stop listening for the swipe gesture. */
-    private fun stopGestureListening() {
-        inputMonitor?.let {
-            logger.logInputListeningStopped()
-            inputMonitor = null
-            it.dispose()
-        }
-        inputReceiver?.let {
-            inputReceiver = null
-            it.dispose()
-        }
+    override fun stopGestureListening() {
+        super.stopGestureListening()
+        logger.logInputListeningStopped()
     }
 }
 
 private const val SWIPE_TIMEOUT_MS: Long = 500
-private val TAG = SwipeStatusBarAwayGestureHandler::class.simpleName
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt
new file mode 100644
index 0000000..7ffb07a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt
@@ -0,0 +1,64 @@
+/*
+ * 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.gesture
+
+import android.content.Context
+import android.view.GestureDetector
+import android.view.InputEvent
+import android.view.MotionEvent
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/**
+ * A class to detect when a user taps the screen. To be notified when the tap is detected, add a
+ * callback via [addOnGestureDetectedCallback].
+ */
+@SysUISingleton
+class TapGestureDetector @Inject constructor(
+    private val context: Context
+) : GenericGestureDetector(TapGestureDetector::class.simpleName!!) {
+
+    private val gestureListener = object : GestureDetector.SimpleOnGestureListener() {
+        override fun onSingleTapUp(e: MotionEvent): Boolean {
+            onGestureDetected(e)
+            return true
+        }
+    }
+
+    private var gestureDetector: GestureDetector? = null
+
+    override fun onInputEvent(ev: InputEvent) {
+        if (ev !is MotionEvent) {
+            return
+        }
+        // Pass all events to [gestureDetector], which will then notify [gestureListener] when a tap
+        // is detected.
+        gestureDetector!!.onTouchEvent(ev)
+    }
+
+    /** Start listening for the tap gesture. */
+    override fun startGestureListening() {
+        super.startGestureListening()
+        gestureDetector = GestureDetector(context, gestureListener)
+    }
+
+    /** Stop listening for the swipe gesture. */
+    override fun stopGestureListening() {
+        super.stopGestureListening()
+        gestureDetector = null
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ForegroundServiceDismissalFeatureController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ForegroundServiceDismissalFeatureController.kt
deleted file mode 100644
index 314051c..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ForegroundServiceDismissalFeatureController.kt
+++ /dev/null
@@ -1,49 +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.statusbar.notification
-
-import android.content.Context
-import android.provider.DeviceConfig
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_ALLOW_FGS_DISMISSAL
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.util.DeviceConfigProxy
-import javax.inject.Inject
-
-private var sIsEnabled: Boolean? = null
-
-/**
- * Feature controller for NOTIFICATIONS_ALLOW_FGS_DISMISSAL config.
- */
-// TODO: this is really boilerplatey, make a base class that just wraps the device config
-@SysUISingleton
-class ForegroundServiceDismissalFeatureController @Inject constructor(
-    val proxy: DeviceConfigProxy,
-    val context: Context
-) {
-    fun isForegroundServiceDismissalEnabled(): Boolean {
-        return isEnabled(proxy)
-    }
-}
-
-private fun isEnabled(proxy: DeviceConfigProxy): Boolean {
-    if (sIsEnabled == null) {
-        sIsEnabled = proxy.getBoolean(
-                DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_ALLOW_FGS_DISMISSAL, false)
-    }
-
-    return sIsEnabled!!
-}
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 82b56cd..5b7d90b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -19,8 +19,8 @@
 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 static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -59,10 +59,8 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.NotificationChannels;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 
 import java.util.List;
-import java.util.Optional;
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
@@ -80,15 +78,12 @@
     private final Executor mUiBgExecutor;
     private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
     private final CommandQueue mCommandQueue;
-    private boolean mDockedStackExists;
     private KeyguardStateController mKeyguardStateController;
-    private final Optional<LegacySplitScreen> mSplitScreenOptional;
 
     @Inject
     public InstantAppNotifier(Context context, CommandQueue commandQueue,
-            @UiBackground Executor uiBgExecutor, Optional<LegacySplitScreen> splitScreenOptional) {
+            @UiBackground Executor uiBgExecutor) {
         super(context);
-        mSplitScreenOptional = splitScreenOptional;
         mCommandQueue = commandQueue;
         mUiBgExecutor = uiBgExecutor;
     }
@@ -107,12 +102,6 @@
         mCommandQueue.addCallback(this);
         mKeyguardStateController.addCallback(this);
 
-        mSplitScreenOptional.ifPresent(splitScreen ->
-                splitScreen.registerInSplitScreenListener(exists -> {
-                    mDockedStackExists = exists;
-                    updateForegroundInstantApps();
-                }));
-
         // Clear out all old notifications on startup (only present in the case where sysui dies)
         NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
         for (StatusBarNotification notification : noMan.getActiveNotifications()) {
@@ -169,14 +158,11 @@
                                     focusedTask.configuration.windowConfiguration
                                             .getWindowingMode();
                             if (windowingMode == WINDOWING_MODE_FULLSCREEN
-                                    || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
+                                    || windowingMode == WINDOWING_MODE_MULTI_WINDOW
                                     || windowingMode == WINDOWING_MODE_FREEFORM) {
                                 checkAndPostForStack(focusedTask, notifs, noMan, pm);
                             }
                         }
-                        if (mDockedStackExists) {
-                            checkAndPostForPrimaryScreen(notifs, noMan, pm);
-                        }
                     } catch (RemoteException e) {
                         e.rethrowFromSystemServer();
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index da70621..392145a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -24,7 +24,7 @@
 import com.android.systemui.DejankUtils;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.Optional;
@@ -39,7 +39,7 @@
     private static final String TAG = "NotificationClicker";
 
     private final NotificationClickerLogger mLogger;
-    private final Optional<StatusBar> mStatusBarOptional;
+    private final Optional<CentralSurfaces> mCentralSurfacesOptional;
     private final Optional<Bubbles> mBubblesOptional;
     private final NotificationActivityStarter mNotificationActivityStarter;
 
@@ -53,11 +53,11 @@
 
     private NotificationClicker(
             NotificationClickerLogger logger,
-            Optional<StatusBar> statusBarOptional,
+            Optional<CentralSurfaces> centralSurfacesOptional,
             Optional<Bubbles> bubblesOptional,
             NotificationActivityStarter notificationActivityStarter) {
         mLogger = logger;
-        mStatusBarOptional = statusBarOptional;
+        mCentralSurfacesOptional = centralSurfacesOptional;
         mBubblesOptional = bubblesOptional;
         mNotificationActivityStarter = notificationActivityStarter;
     }
@@ -69,7 +69,7 @@
             return;
         }
 
-        mStatusBarOptional.ifPresent(statusBar -> statusBar.wakeUpIfDozing(
+        mCentralSurfacesOptional.ifPresent(centralSurfaces -> centralSurfaces.wakeUpIfDozing(
                 SystemClock.uptimeMillis(), v, "NOTIFICATION_CLICK"));
 
         final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
@@ -137,13 +137,13 @@
 
         /** Builds an instance. */
         public NotificationClicker build(
-                Optional<StatusBar> statusBarOptional,
+                Optional<CentralSurfaces> centralSurfacesOptional,
                 Optional<Bubbles> bubblesOptional,
                 NotificationActivityStarter notificationActivityStarter
         ) {
             return new NotificationClicker(
                     mLogger,
-                    statusBarOptional,
+                    centralSurfacesOptional,
                     bubblesOptional,
                     notificationActivityStarter);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index f97b936..ac5beec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -111,7 +111,6 @@
     private final Lazy<NotificationRowBinder> mNotificationRowBinderLazy;
     private final Lazy<NotificationRemoteInputManager> mRemoteInputManagerLazy;
     private final LeakDetector mLeakDetector;
-    private final ForegroundServiceDismissalFeatureController mFgsFeatureController;
     private final IStatusBarService mStatusBarService;
     private final NotifLiveDataStoreImpl mNotifLiveDataStore;
     private final DumpManager mDumpManager;
@@ -159,7 +158,6 @@
             Lazy<NotificationRowBinder> notificationRowBinderLazy,
             Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
             LeakDetector leakDetector,
-            ForegroundServiceDismissalFeatureController fgsFeatureController,
             IStatusBarService statusBarService,
             NotifLiveDataStoreImpl notifLiveDataStore,
             DumpManager dumpManager
@@ -170,7 +168,6 @@
         mNotificationRowBinderLazy = notificationRowBinderLazy;
         mRemoteInputManagerLazy = notificationRemoteInputManagerLazy;
         mLeakDetector = leakDetector;
-        mFgsFeatureController = fgsFeatureController;
         mStatusBarService = statusBarService;
         mNotifLiveDataStore = notifLiveDataStore;
         mDumpManager = dumpManager;
@@ -958,7 +955,7 @@
         Trace.endSection();
     }
 
-    /** dump the current active notification list. Called from StatusBar */
+    /** dump the current active notification list. Called from CentralSurfaces */
     public void dump(PrintWriter pw, String indent) {
         pw.println("NotificationEntryManager (Legacy)");
         int filteredLen = mSortedAndFiltered.size();
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 9da7d21..2c1296f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -8,12 +8,15 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
 import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
 import com.android.systemui.statusbar.policy.HeadsUpUtil
+import javax.inject.Inject
 import kotlin.math.ceil
 import kotlin.math.max
 
 /** A provider of [NotificationLaunchAnimatorController]. */
-class NotificationLaunchAnimatorControllerProvider(
+@CentralSurfacesComponent.CentralSurfacesScope
+class NotificationLaunchAnimatorControllerProvider @Inject constructor(
     private val notificationShadeWindowViewController: NotificationShadeWindowViewController,
     private val notificationListContainer: NotificationListContainer,
     private val headsUpManager: HeadsUpManagerPhone,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt
index 5dc0dcc..c71eade 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt
@@ -23,7 +23,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
-import com.android.systemui.statusbar.phone.StatusBar
+import com.android.systemui.statusbar.phone.CentralSurfaces
 import javax.inject.Inject
 
 @SysUISingleton
@@ -39,7 +39,7 @@
     }
 
     private fun resolveNotificationSdk(sbn: StatusBarNotification): Int {
-        val pmUser = StatusBar.getPackageManagerForUser(context, sbn.user.identifier)
+        val pmUser = CentralSurfaces.getPackageManagerForUser(context, sbn.user.identifier)
         var targetSdk = 0
         // Extract target SDK version.
         try {
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..0df2162 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,9 @@
     private var mEndLifetimeExtension: OnEndLifetimeExtensionCallback? = null
     private lateinit var mNotifPipeline: NotifPipeline
     private var mNow: Long = -1
-
     // notifs we've extended the lifetime for
     private val mNotifsExtendingLifetime = ArraySet<NotificationEntry>()
+    private val mPostedEntries = LinkedHashMap<String, PostedEntry>()
 
     override fun attach(pipeline: NotifPipeline) {
         mNotifPipeline = pipeline
@@ -101,10 +101,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 +116,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 +140,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 +183,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 +197,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 +315,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 +329,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 +387,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 +404,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)
+                }
+            }
         }
 
         /**
@@ -543,3 +576,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/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/LegacyNotificationPresenterExtensions.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java
index 4ee08ed..bdbb0eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/LegacyNotificationPresenterExtensions.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.notification.collection.legacy;
 
-import static com.android.systemui.statusbar.phone.StatusBar.SPEW;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.SPEW;
 
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
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 607500e..c35b77c 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
@@ -22,6 +22,7 @@
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.util.Compile
 import com.android.systemui.util.traceSection
 
 /**
@@ -37,8 +38,11 @@
     private val mediaContainerController: MediaContainerController,
     private val sectionsFeatureManager: NotificationSectionsFeatureManager,
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
-    private val viewBarn: NotifViewBarn
+    private val viewBarn: NotifViewBarn,
+    private val logger: NodeSpecBuilderLogger
 ) {
+    private var lastSections = setOf<NotifSection?>()
+
     fun buildNodeSpec(
         rootController: NodeController,
         notifList: List<ListEntry>
@@ -54,6 +58,9 @@
         var currentSection: NotifSection? = null
         val prevSections = mutableSetOf<NotifSection?>()
         val showHeaders = sectionHeaderVisibilityProvider.sectionHeadersVisible
+        val sectionOrder = mutableListOf<NotifSection?>()
+        val sectionHeaders = mutableMapOf<NotifSection?, NodeController?>()
+        val sectionCounts = mutableMapOf<NotifSection?, Int>()
 
         for (entry in notifList) {
             val section = entry.section!!
@@ -67,14 +74,28 @@
                 if (section.headerController != currentSection?.headerController && showHeaders) {
                     section.headerController?.let { headerController ->
                         root.children.add(NodeSpecImpl(root, headerController))
+                        if (Compile.IS_DEBUG) {
+                            sectionHeaders[section] = headerController
+                        }
                     }
                 }
                 prevSections.add(currentSection)
                 currentSection = section
+                if (Compile.IS_DEBUG) {
+                    sectionOrder.add(section)
+                }
             }
 
             // Finally, add the actual notif node!
             root.children.add(buildNotifNode(root, entry))
+            if (Compile.IS_DEBUG) {
+                sectionCounts[section] = sectionCounts.getOrDefault(section, 0) + 1
+            }
+        }
+
+        if (Compile.IS_DEBUG) {
+            logger.logBuildNodeSpec(lastSections, sectionHeaders, sectionCounts, sectionOrder)
+            lastSections = sectionCounts.keys
         }
 
         return@traceSection root
@@ -87,4 +108,4 @@
                 .apply { entry.children.forEach { children.add(buildNotifNode(this, it)) } }
         else -> throw RuntimeException("Unexpected entry: $entry")
     }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
new file mode 100644
index 0000000..3501b44
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
@@ -0,0 +1,62 @@
+/*
+ * 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.log.LogBuffer
+import com.android.systemui.log.LogLevel
+import com.android.systemui.log.dagger.NotificationLog
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.util.Compile
+import javax.inject.Inject
+
+class NodeSpecBuilderLogger @Inject constructor(
+    @NotificationLog private val buffer: LogBuffer
+) {
+    fun logBuildNodeSpec(
+        oldSections: Set<NotifSection?>,
+        newHeaders: Map<NotifSection?, NodeController?>,
+        newCounts: Map<NotifSection?, Int>,
+        newSectionOrder: List<NotifSection?>
+    ) {
+        if (!Compile.IS_DEBUG)
+            return
+
+        buffer.log(TAG, LogLevel.DEBUG, {
+            int1 = newSectionOrder.size
+        }, { "buildNodeSpec finished with $int1 sections" })
+
+        for (section in newSectionOrder) {
+            buffer.log(TAG, LogLevel.DEBUG, {
+                str1 = section?.sectioner?.name ?: "(null)"
+                str2 = newHeaders[section]?.nodeLabel ?: "(none)"
+                int1 = newCounts[section] ?: -1
+            }, {
+                "  section $str1 has header $str2, $int1 entries"
+            })
+        }
+
+        for (section in oldSections - newSectionOrder.toSet()) {
+            buffer.log(TAG, LogLevel.DEBUG, {
+                str1 = section?.sectioner?.name ?: "(null)"
+            }, {
+                "  section $str1 was removed since last run"
+            })
+        }
+    }
+}
+
+private const val TAG = "NodeSpecBuilder"
\ No newline at end of file
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 920d3c4..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.StatusBarComponent
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
-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
-    @StatusBarScope
-    fun bindStartable(
-        manager: NotifPanelEventSourceManager,
-        notifPanelController: NotificationPanelViewController
-    ): StatusBarComponent.Startable =
-            EventSourceStatusBarStartableImpl(manager, notifPanelController)
-}
-
-/**
- * Management layer that bridges [SysUiSingleton] and [StatusBarScope]. Necessary because code that
- * wants to listen to [NotifPanelEventSource] lives in [SysUiSingleton], but the events themselves
- * come from [NotificationPanelViewController] in [StatusBarScope].
- */
-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
-) : StatusBarComponent.Startable {
-
-    override fun start() {
-        manager.eventSource = notifPanelController
-    }
-
-    override fun stop() {
-        manager.eventSource = null
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
index 4847072..6ed8107 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
@@ -40,15 +40,16 @@
     mediaContainerController: MediaContainerController,
     featureManager: NotificationSectionsFeatureManager,
     sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
-    logger: ShadeViewDifferLogger,
+    nodeSpecBuilderLogger: NodeSpecBuilderLogger,
+    shadeViewDifferLogger: ShadeViewDifferLogger,
     private val viewBarn: NotifViewBarn
 ) {
     // We pass a shim view here because the listContainer may not actually have a view associated
     // with it and the differ never actually cares about the root node's view.
     private val rootController = RootNodeController(listContainer, View(context))
     private val specBuilder = NodeSpecBuilder(mediaContainerController, featureManager,
-            sectionHeaderVisibilityProvider, viewBarn)
-    private val viewDiffer = ShadeViewDiffer(rootController, logger)
+            sectionHeaderVisibilityProvider, viewBarn, nodeSpecBuilderLogger)
+    private val viewDiffer = ShadeViewDiffer(rootController, shadeViewDifferLogger)
 
     /** Method for attaching this manager to the pipeline. */
     fun attach(renderStageManager: RenderStageManager) {
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 e3ebef9..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
@@ -38,7 +38,6 @@
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.notification.AssistantFeedbackController;
-import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
@@ -69,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;
@@ -85,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.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.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.util.leak.LeakDetector;
 import com.android.systemui.wmshell.BubblesManager;
@@ -95,6 +95,8 @@
 import java.util.Optional;
 import java.util.concurrent.Executor;
 
+import javax.inject.Provider;
+
 import dagger.Binds;
 import dagger.Lazy;
 import dagger.Module;
@@ -105,8 +107,9 @@
  */
 @Module(includes = {
         CoordinatorsModule.class,
+        NotifActivityLaunchEventsModule.class,
         NotifPipelineChoreographerModule.class,
-        NotifPanelEventSourceModule.class,
+        NotifPanelEventsModule.class,
         NotificationSectionHeadersModule.class,
 })
 public interface NotificationsModule {
@@ -128,7 +131,6 @@
             Lazy<NotificationRowBinder> notificationRowBinderLazy,
             Lazy<NotificationRemoteInputManager> notificationRemoteInputManagerLazy,
             LeakDetector leakDetector,
-            ForegroundServiceDismissalFeatureController fgsFeatureController,
             IStatusBarService statusBarService,
             NotifLiveDataStoreImpl notifLiveDataStore,
             DumpManager dumpManager) {
@@ -139,7 +141,6 @@
                 notificationRowBinderLazy,
                 notificationRemoteInputManagerLazy,
                 leakDetector,
-                fgsFeatureController,
                 statusBarService,
                 notifLiveDataStore,
                 dumpManager);
@@ -150,7 +151,7 @@
     @Provides
     static NotificationGutsManager provideNotificationGutsManager(
             Context context,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             @Main Handler mainHandler,
             @Background Handler bgHandler,
             AccessibilityManager accessibilityManager,
@@ -170,7 +171,7 @@
             DumpManager dumpManager) {
         return new NotificationGutsManager(
                 context,
-                statusBarOptionalLazy,
+                centralSurfacesOptionalLazy,
                 mainHandler,
                 bgHandler,
                 accessibilityManager,
@@ -279,8 +280,8 @@
     @Provides
     static NotificationsController provideNotificationsController(
             Context context,
-            Lazy<NotificationsControllerImpl> realController,
-            Lazy<NotificationsControllerStub> stubController) {
+            Provider<NotificationsControllerImpl> realController,
+            Provider<NotificationsControllerStub> stubController) {
         if (context.getResources().getBoolean(R.bool.config_renderNotifications)) {
             return realController.get();
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
index a59d421..18abfca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsController.kt
@@ -23,11 +23,8 @@
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl
 import com.android.systemui.statusbar.notification.collection.render.NotifStackController
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.StatusBar
-import com.android.wm.shell.bubbles.Bubbles
 import java.io.FileDescriptor
 import java.io.PrintWriter
-import java.util.Optional
 
 /**
  * The master controller for all notifications-related work
@@ -37,8 +34,6 @@
  */
 interface NotificationsController {
     fun initialize(
-        statusBar: StatusBar,
-        bubblesOptional: Optional<Bubbles>,
         presenter: NotificationPresenter,
         listContainer: NotificationListContainer,
         stackController: NotifStackController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 48f2daf..98f45fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -44,7 +44,7 @@
 import com.android.systemui.statusbar.notification.row.NotifBindPipelineInitializer
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper
-import com.android.systemui.statusbar.phone.StatusBar
+import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.policy.DeviceProvisionedController
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import com.android.systemui.statusbar.policy.RemoteInputUriController
@@ -64,6 +64,7 @@
  */
 @SysUISingleton
 class NotificationsControllerImpl @Inject constructor(
+    private val centralSurfaces: Lazy<CentralSurfaces>,
     private val notifPipelineFlags: NotifPipelineFlags,
     private val notificationListener: NotificationListener,
     private val entryManager: NotificationEntryManager,
@@ -86,12 +87,11 @@
     private val headsUpViewBinder: HeadsUpViewBinder,
     private val clickerBuilder: NotificationClicker.Builder,
     private val animatedImageNotificationManager: AnimatedImageNotificationManager,
-    private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager
+    private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager,
+    private val bubblesOptional: Optional<Bubbles>,
 ) : NotificationsController {
 
     override fun initialize(
-        statusBar: StatusBar,
-        bubblesOptional: Optional<Bubbles>,
         presenter: NotificationPresenter,
         listContainer: NotificationListContainer,
         stackController: NotifStackController,
@@ -109,7 +109,7 @@
 
         notificationRowBinder.setNotificationClicker(
                 clickerBuilder.build(
-                        Optional.of(statusBar), bubblesOptional, notificationActivityStarter))
+                        Optional.of(centralSurfaces.get()), bubblesOptional, notificationActivityStarter))
         notificationRowBinder.setUpWithPresenter(
                 presenter,
                 listContainer,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
index 1c9af11..66701d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
@@ -24,11 +24,8 @@
 import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl
 import com.android.systemui.statusbar.notification.collection.render.NotifStackController
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.StatusBar
-import com.android.wm.shell.bubbles.Bubbles
 import java.io.FileDescriptor
 import java.io.PrintWriter
-import java.util.Optional
 import javax.inject.Inject
 
 /**
@@ -39,8 +36,6 @@
 ) : NotificationsController {
 
     override fun initialize(
-        statusBar: StatusBar,
-        bubblesOptional: Optional<Bubbles>,
         presenter: NotificationPresenter,
         listContainer: NotificationListContainer,
         stackController: NotifStackController,
@@ -75,4 +70,4 @@
         pw.println("Notification handling disabled")
         pw.println()
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index dc39413..9fbd5c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -468,7 +468,7 @@
     }
 
     /**
-     * Called by StatusBar to notify the logger that the panel expansion has changed.
+     * Called by CentralSurfaces to notify the logger that the panel expansion has changed.
      * The panel may be showing any of the normal notification panel, the AOD, or the bouncer.
      * @param isExpanded True if the panel is expanded.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/DungeonRow.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/DungeonRow.kt
deleted file mode 100644
index dbfa27f..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/DungeonRow.kt
+++ /dev/null
@@ -1,43 +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.statusbar.notification.row
-
-import android.content.Context
-import android.util.AttributeSet
-import android.widget.LinearLayout
-import android.widget.TextView
-import com.android.systemui.R
-import com.android.systemui.statusbar.StatusBarIconView
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-
-class DungeonRow(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
-    var entry: NotificationEntry? = null
-        set(value) {
-            field = value
-            update()
-        }
-
-    private fun update() {
-        (findViewById(R.id.app_name) as TextView).apply {
-            text = entry?.row?.appName
-        }
-
-        (findViewById(R.id.icon) as StatusBarIconView).apply {
-            set(entry?.icons?.statusBarIcon?.statusBarIcon)
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 1f7d930..c237e1d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -112,7 +112,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.SwipeableView;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
@@ -388,7 +388,7 @@
             }
             return false;
         } else {
-            PackageManager packageManager = StatusBar.getPackageManagerForUser(
+            PackageManager packageManager = CentralSurfaces.getPackageManagerForUser(
                     context, sbn.getUser().getIdentifier());
             Boolean isSystemNotification = null;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ForegroundServiceDungeonView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ForegroundServiceDungeonView.kt
deleted file mode 100644
index 17396ad..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ForegroundServiceDungeonView.kt
+++ /dev/null
@@ -1,38 +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.statusbar.notification.row
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.View
-
-import com.android.systemui.R
-
-class ForegroundServiceDungeonView(context: Context, attrs: AttributeSet)
-    : StackScrollerDecorView(context, attrs) {
-    override fun findContentView(): View? {
-        return findViewById(R.id.foreground_service_dungeon)
-    }
-
-    override fun findSecondaryView(): View? {
-        return null
-    }
-
-    override fun setVisible(visible: Boolean, animate: Boolean) {
-        // Visibility is controlled by the ForegroundServiceSectionController
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 1530e523..4c69304 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -47,7 +47,7 @@
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
 import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
 import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
@@ -841,7 +841,7 @@
             StatusBarNotification sbn = mEntry.getSbn();
             final String ident = sbn.getPackageName() + "/0x"
                     + Integer.toHexString(sbn.getId());
-            Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
+            Log.e(CentralSurfaces.TAG, "couldn't inflate view for notification " + ident, e);
             if (mCallback != null) {
                 mCallback.handleInflationException(mRow.getEntry(),
                         new InflationException("Couldn't inflate contentViews" + e));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 6d13024..ebe6f03 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -70,8 +70,8 @@
 import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.wmshell.BubblesManager;
 
@@ -120,7 +120,7 @@
     @VisibleForTesting
     protected String mKeyToRemoveOnGutsClosed;
 
-    private final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    private final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final Handler mMainHandler;
     private final Handler mBgHandler;
     private final Optional<BubblesManager> mBubblesManagerOptional;
@@ -139,7 +139,7 @@
      * Injected constructor. See {@link NotificationsModule}.
      */
     public NotificationGutsManager(Context context,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
             @Main Handler mainHandler,
             @Background Handler bgHandler,
             AccessibilityManager accessibilityManager,
@@ -158,7 +158,7 @@
             ShadeController shadeController,
             DumpManager dumpManager) {
         mContext = context;
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mMainHandler = mainHandler;
         mBgHandler = bgHandler;
         mAccessibilityManager = accessibilityManager;
@@ -342,7 +342,7 @@
         }
         StatusBarNotification sbn = row.getEntry().getSbn();
         UserHandle userHandle = sbn.getUser();
-        PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
+        PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(mContext,
                 userHandle.getIdentifier());
 
         feedbackInfo.bindGuts(pmUser, sbn, row.getEntry(), row, mAssistantFeedbackController);
@@ -363,7 +363,7 @@
         // Settings link is only valid for notifications that specify a non-system user
         NotificationInfo.OnSettingsClickListener onSettingsClick = null;
         UserHandle userHandle = sbn.getUser();
-        PackageManager pmUser = StatusBar.getPackageManagerForUser(
+        PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
                 mContext, userHandle.getIdentifier());
         final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick =
                 (View v, Intent intent) -> {
@@ -416,7 +416,7 @@
         // Settings link is only valid for notifications that specify a non-system user
         NotificationInfo.OnSettingsClickListener onSettingsClick = null;
         UserHandle userHandle = sbn.getUser();
-        PackageManager pmUser = StatusBar.getPackageManagerForUser(
+        PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
                 mContext, userHandle.getIdentifier());
 
         if (!userHandle.equals(UserHandle.ALL)
@@ -458,7 +458,7 @@
         // Settings link is only valid for notifications that specify a non-system user
         NotificationConversationInfo.OnSettingsClickListener onSettingsClick = null;
         UserHandle userHandle = sbn.getUser();
-        PackageManager pmUser = StatusBar.getPackageManagerForUser(
+        PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
                 mContext, userHandle.getIdentifier());
         final NotificationConversationInfo.OnAppSettingsClickListener onAppSettingsClick =
                 (View v, Intent intent) -> {
@@ -571,11 +571,12 @@
                             .setLeaveOpenOnKeyguardHide(true);
                 }
 
-                Optional<StatusBar> statusBarOptional = mStatusBarOptionalLazy.get();
-                if (statusBarOptional.isPresent()) {
+                Optional<CentralSurfaces> centralSurfacesOptional =
+                        mCentralSurfacesOptionalLazy.get();
+                if (centralSurfacesOptional.isPresent()) {
                     Runnable r = () -> mMainHandler.post(
                             () -> openGutsInternal(view, x, y, menuItem));
-                    statusBarOptional.get().executeRunnableDismissingKeyguard(
+                    centralSurfacesOptional.get().executeRunnableDismissingKeyguard(
                             r,
                             null /* cancelAction */,
                             false /* dismissShade */,
@@ -584,7 +585,7 @@
                     return true;
                 }
                 /**
-                 * When {@link StatusBar} doesn't exist, falling through to call
+                 * When {@link CentralSurfaces} doesn't exist, falling through to call
                  * {@link #openGutsInternal(View,int,int,NotificationMenuRowPlugin.MenuItem)}.
                  */
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
index a12d0073..1a7417a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java
@@ -26,7 +26,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import dagger.Binds;
 import dagger.BindsInstance;
@@ -100,7 +100,7 @@
             // but since this field is used in the guts, it must be accurate.
             // Therefore we will only show the application label, or, failing that, the
             // package name. No substitutions.
-            PackageManager pmUser = StatusBar.getPackageManagerForUser(
+            PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(
                     context, statusBarNotification.getUser().getIdentifier());
             final String pkg = statusBarNotification.getPackageName();
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java
index 4555b83..fa14123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java
@@ -24,7 +24,7 @@
 import javax.inject.Scope;
 
 /**
- * Scope annotation for singleton items within the StatusBarComponent.
+ * Scope annotation for singleton items within the CentralSurfacesComponent.
  */
 @Documented
 @Retention(RUNTIME)
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/ForegroundServiceSectionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ForegroundServiceSectionController.kt
deleted file mode 100644
index 75ca337..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ForegroundServiceSectionController.kt
+++ /dev/null
@@ -1,168 +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.statusbar.notification.stack
-
-import android.content.Context
-import android.service.notification.NotificationListenerService.REASON_CANCEL
-import android.service.notification.NotificationListenerService.REASON_CANCEL_ALL
-import android.service.notification.NotificationListenerService.REASON_CLICK
-import android.service.notification.NotificationListenerService.REASON_GROUP_SUMMARY_CANCELED
-import android.view.LayoutInflater
-import android.view.View
-import android.widget.LinearLayout
-import com.android.systemui.R
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController
-import com.android.systemui.statusbar.notification.NotificationEntryListener
-import com.android.systemui.statusbar.notification.NotificationEntryManager
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.row.DungeonRow
-import com.android.systemui.util.Assert
-import javax.inject.Inject
-
-/**
- * Controller for the bottom area of NotificationStackScrollLayout. It owns swiped-away foreground
- * service notifications and can reinstantiate them when requested.
- */
-@SysUISingleton
-class ForegroundServiceSectionController @Inject constructor(
-    val entryManager: NotificationEntryManager,
-    val featureController: ForegroundServiceDismissalFeatureController
-) {
-    private val TAG = "FgsSectionController"
-    private var context: Context? = null
-
-    private val entries = mutableSetOf<NotificationEntry>()
-
-    private var entriesView: View? = null
-
-    init {
-        if (featureController.isForegroundServiceDismissalEnabled()) {
-            entryManager.addNotificationRemoveInterceptor(this::shouldInterceptRemoval)
-
-            entryManager.addNotificationEntryListener(object : NotificationEntryListener {
-                override fun onPostEntryUpdated(entry: NotificationEntry) {
-                    if (entries.contains(entry)) {
-                        removeEntry(entry)
-                        addEntry(entry)
-                        update()
-                    }
-                }
-            })
-        }
-    }
-
-    private fun shouldInterceptRemoval(
-        key: String,
-        entry: NotificationEntry?,
-        reason: Int
-    ): Boolean {
-        Assert.isMainThread()
-        val isClearAll = reason == REASON_CANCEL_ALL
-        val isUserDismiss = reason == REASON_CANCEL || reason == REASON_CLICK
-        // REASON_APP_CANCEL and REASON_APP_CANCEL_ALL are ignored, because the
-        // foreground service associated with it is gone.
-        val isSummaryCancel = reason == REASON_GROUP_SUMMARY_CANCELED
-
-        if (entry == null) return false
-
-        // We only want to retain notifications that the user dismissed
-        // TODO: centralize the entry.isClearable logic and this so that it's clear when a notif is
-        // clearable
-        if (isUserDismiss && !entry.sbn.isClearable) {
-            if (!hasEntry(entry)) {
-                addEntry(entry)
-                update()
-            }
-            // TODO: This isn't ideal. Slightly better would at least be to have NEM update the
-            // notif list when an entry gets intercepted
-            entryManager.updateNotifications(
-                    "FgsSectionController.onNotificationRemoveRequested")
-            return true
-        } else if ((isClearAll || isSummaryCancel) && !entry.sbn.isClearable) {
-            // In the case where a FGS notification is part of a group that is cleared or a clear
-            // all, we actually want to stop its removal but also not put it into the dungeon
-            return true
-        } else if (hasEntry(entry)) {
-            removeEntry(entry)
-            update()
-            return false
-        }
-
-        return false
-    }
-
-    private fun removeEntry(entry: NotificationEntry) {
-        Assert.isMainThread()
-        entries.remove(entry)
-    }
-
-    private fun addEntry(entry: NotificationEntry) {
-        Assert.isMainThread()
-        entries.add(entry)
-    }
-
-    fun hasEntry(entry: NotificationEntry): Boolean {
-        Assert.isMainThread()
-        return entries.contains(entry)
-    }
-
-    fun initialize(context: Context) {
-        this.context = context
-    }
-
-    fun createView(li: LayoutInflater): View {
-        entriesView = li.inflate(R.layout.foreground_service_dungeon, null)
-        // Start out gone
-        entriesView!!.visibility = View.GONE
-        return entriesView!!
-    }
-
-    private fun update() {
-        Assert.isMainThread()
-        if (entriesView == null) {
-            throw IllegalStateException("ForegroundServiceSectionController is trying to show " +
-                    "dismissed fgs notifications without having been initialized!")
-        }
-
-        // TODO: these views should be recycled and not inflating on the main thread
-        (entriesView!!.findViewById(R.id.entry_list) as LinearLayout).apply {
-            removeAllViews()
-            entries.sortedBy { it.ranking.rank }.forEach { entry ->
-                val child = LayoutInflater.from(context)
-                        .inflate(R.layout.foreground_service_dungeon_row, null) as DungeonRow
-
-                child.entry = entry
-                child.setOnClickListener {
-                    removeEntry(child.entry!!)
-                    update()
-                    entry.row.unDismiss()
-                    entry.row.resetTranslation()
-                    entryManager.updateNotifications("ForegroundServiceSectionController.onClick")
-                }
-
-                addView(child)
-            }
-        }
-
-        if (entries.isEmpty()) {
-            entriesView?.visibility = View.GONE
-        } else {
-            entriesView?.visibility = View.VISIBLE
-        }
-    }
-}
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 2c4db77..5b9dbd0 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
@@ -100,13 +100,12 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.row.FooterView;
-import com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 import com.android.systemui.util.Assert;
@@ -203,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
      */
@@ -309,7 +305,7 @@
         }
     };
     private NotificationStackScrollLogger mLogger;
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     private int[] mTempInt2 = new int[2];
     private boolean mGenerateChildOrderChangedEvent;
     private HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>();
@@ -408,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;
@@ -453,7 +454,6 @@
     private Interpolator mHideXInterpolator = Interpolators.FAST_OUT_SLOW_IN;
 
     private final NotificationSectionsManager mSectionsManager;
-    private ForegroundServiceDungeonView mFgsSectionView;
     private boolean mAnimateBottomOnLayout;
     private float mLastSentAppear;
     private float mLastSentExpandedHeight;
@@ -614,14 +614,6 @@
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
     }
 
-    void initializeForegroundServiceSection(ForegroundServiceDungeonView fgsSectionView) {
-        if (mFgsSectionView != null) {
-            return;
-        }
-        mFgsSectionView = fgsSectionView;
-        addView(mFgsSectionView, -1);
-    }
-
     /**
      * Set the overexpansion of the panel to be applied to the view.
      */
@@ -1143,7 +1135,7 @@
 
     @ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
     private void updateAlgorithmLayoutMinHeight() {
-        mAmbientState.setLayoutMinHeight(mQsExpanded || isHeadsUpTransition()
+        mAmbientState.setLayoutMinHeight(mQsFullScreen || isHeadsUpTransition()
                 ? getLayoutMinHeight() : 0);
     }
 
@@ -1273,13 +1265,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());
     }
 
     /**
@@ -1371,7 +1366,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) {
@@ -2328,7 +2323,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);
@@ -3969,7 +3964,7 @@
         mAmbientState.setExpansionChanging(false);
         if (!mIsExpanded) {
             resetScrollPosition();
-            mStatusBar.resetUserExpandedStates();
+            mCentralSurfaces.resetUserExpandedStates();
             clearTemporaryViews();
             clearUserLockedViews();
             if (mSwipeHelper.isSwiping()) {
@@ -4601,8 +4596,8 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setStatusBar(StatusBar statusBar) {
-        this.mStatusBar = statusBar;
+    public void setCentralSurfaces(CentralSurfaces centralSurfaces) {
+        this.mCentralSurfaces = centralSurfaces;
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4849,14 +4844,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)
@@ -5019,13 +5014,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;
@@ -5270,7 +5258,7 @@
             Intent intent = showHistory
                     ? new Intent(Settings.ACTION_NOTIFICATION_HISTORY)
                     : new Intent(Settings.ACTION_NOTIFICATION_SETTINGS);
-            mStatusBar.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
+            mCentralSurfaces.startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
         });
         setEmptyShadeView(view);
     }
@@ -5286,9 +5274,6 @@
         // incremented in the following "changeViewPosition" calls so that its value is correct for
         // subsequent calls.
         int offsetFromEnd = 1;
-        if (mFgsSectionView != null) {
-            changeViewPosition(mFgsSectionView, getChildCount() - offsetFromEnd++);
-        }
         changeViewPosition(mFooterView, getChildCount() - offsetFromEnd++);
         changeViewPosition(mEmptyShadeView, getChildCount() - offsetFromEnd++);
 
@@ -5827,10 +5812,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 d1c63e3..7df8e7d 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
@@ -86,7 +86,6 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
 import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
-import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -109,18 +108,17 @@
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView;
 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.StatusBar;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -143,7 +141,7 @@
 /**
  * Controller for {@link NotificationStackScrollLayout}.
  */
-@StatusBarComponent.StatusBarScope
+@CentralSurfacesComponent.CentralSurfacesScope
 public class NotificationStackScrollLayoutController {
     private static final String TAG = "StackScrollerController";
     private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
@@ -170,8 +168,6 @@
     private final NotificationEntryManager mNotificationEntryManager;
     private final IStatusBarService mIStatusBarService;
     private final UiEventLogger mUiEventLogger;
-    private final ForegroundServiceDismissalFeatureController mFgFeatureController;
-    private final ForegroundServiceSectionController mFgServicesSectionController;
     private final LayoutInflater mLayoutInflater;
     private final NotificationRemoteInputManager mRemoteInputManager;
     private final VisualStabilityManager mVisualStabilityManager;
@@ -180,8 +176,8 @@
     private final SysuiStatusBarStateController mStatusBarStateController;
     private final KeyguardBypassController mKeyguardBypassController;
     private final NotificationLockscreenUserManager mLockscreenUserManager;
-    // TODO: StatusBar should be encapsulated behind a Controller
-    private final StatusBar mStatusBar;
+    // TODO: CentralSurfaces should be encapsulated behind a Controller
+    private final CentralSurfaces mCentralSurfaces;
     private final SectionHeaderController mSilentHeaderController;
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     private final InteractionJankMonitor mJankMonitor;
@@ -334,7 +330,7 @@
                     mView.updateSensitiveness(mStatusBarStateController.goingToFullShade(),
                             mLockscreenUserManager.isAnyProfilePublicMode());
                     mView.onStatePostChange(mStatusBarStateController.fromShadeLocked());
-                    mNotificationEntryManager.updateNotifications("StatusBar state changed");
+                    mNotificationEntryManager.updateNotifications("CentralSurfaces state changed");
                 }
             };
 
@@ -435,7 +431,7 @@
                 @Override
                 public void onSnooze(StatusBarNotification sbn,
                         NotificationSwipeActionHelper.SnoozeOption snoozeOption) {
-                    mStatusBar.setNotificationSnoozed(sbn, snoozeOption);
+                    mCentralSurfaces.setNotificationSnoozed(sbn, snoozeOption);
                 }
 
                 @Override
@@ -488,7 +484,7 @@
                     mView.addSwipedOutView(view);
                     mFalsingCollector.onNotificationDismissed();
                     if (mFalsingCollector.shouldEnforceBouncer()) {
-                        mStatusBar.executeRunnableDismissingKeyguard(
+                        mCentralSurfaces.executeRunnableDismissingKeyguard(
                                 null,
                                 null /* cancelAction */,
                                 false /* dismissShade */,
@@ -561,7 +557,7 @@
 
                 @Override
                 public float getFalsingThresholdFactor() {
-                    return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+                    return mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
                 }
 
                 @Override
@@ -648,7 +644,7 @@
             FalsingManager falsingManager,
             @Main Resources resources,
             NotificationSwipeHelper.Builder notificationSwipeHelperBuilder,
-            StatusBar statusBar,
+            CentralSurfaces centralSurfaces,
             ScrimController scrimController,
             NotificationGroupManagerLegacy legacyGroupManager,
             GroupExpansionManager groupManager,
@@ -660,8 +656,6 @@
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             IStatusBarService iStatusBarService,
             UiEventLogger uiEventLogger,
-            ForegroundServiceDismissalFeatureController fgFeatureController,
-            ForegroundServiceSectionController fgServicesSectionController,
             LayoutInflater layoutInflater,
             NotificationRemoteInputManager remoteInputManager,
             VisualStabilityManager visualStabilityManager,
@@ -691,7 +685,7 @@
         mFalsingManager = falsingManager;
         mResources = resources;
         mNotificationSwipeHelperBuilder = notificationSwipeHelperBuilder;
-        mStatusBar = statusBar;
+        mCentralSurfaces = centralSurfaces;
         mScrimController = scrimController;
         mJankMonitor = jankMonitor;
         groupManager.registerGroupExpansionChangeListener(
@@ -699,7 +693,7 @@
         legacyGroupManager.registerGroupChangeListener(new OnGroupChangeListener() {
             @Override
             public void onGroupsChanged() {
-                mStatusBar.requestNotificationUpdate("onGroupsChanged");
+                mCentralSurfaces.requestNotificationUpdate("onGroupsChanged");
             }
         });
         mNotifPipelineFlags = notifPipelineFlags;
@@ -709,8 +703,6 @@
         mNotificationEntryManager = notificationEntryManager;
         mIStatusBarService = iStatusBarService;
         mUiEventLogger = uiEventLogger;
-        mFgFeatureController = fgFeatureController;
-        mFgServicesSectionController = fgServicesSectionController;
         mLayoutInflater = layoutInflater;
         mRemoteInputManager = remoteInputManager;
         mVisualStabilityManager = visualStabilityManager;
@@ -724,7 +716,7 @@
         mView.setController(this);
         mView.setLogger(mLogger);
         mView.setTouchHandler(new TouchHandler());
-        mView.setStatusBar(mStatusBar);
+        mView.setCentralSurfaces(mCentralSurfaces);
         mView.setClearAllAnimationListener(this::onAnimationEnd);
         mView.setClearAllListener((selection) -> mUiEventLogger.log(
                 NotificationPanelEvent.fromSelection(selection)));
@@ -744,12 +736,6 @@
         mNotificationRoundnessManager.setShouldRoundPulsingViews(
                 !mKeyguardBypassController.getBypassEnabled());
 
-        if (mFgFeatureController.isForegroundServiceDismissalEnabled()) {
-            mView.initializeForegroundServiceSection(
-                    (ForegroundServiceDungeonView) mFgServicesSectionController.createView(
-                            mLayoutInflater));
-        }
-
         mSwipeHelper = mNotificationSwipeHelperBuilder
                 .setSwipeDirection(SwipeHelper.X)
                 .setNotificationCallback(mNotificationCallback)
@@ -1100,8 +1086,8 @@
         }
     }
 
-    public void setQsExpanded(boolean expanded) {
-        mView.setQsExpanded(expanded);
+    public void setQsFullScreen(boolean fullScreen) {
+        mView.setQsFullScreen(fullScreen);
         updateShowEmptyShadeView();
     }
 
@@ -1195,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();
     }
@@ -1225,7 +1204,7 @@
     public void updateShowEmptyShadeView() {
         Trace.beginSection("NSSLC.updateShowEmptyShadeView");
         mShowEmptyShadeView = mBarState != KEYGUARD
-                && (!mView.isQsExpanded() || mView.isUsingSplitNotificationShade())
+                && !mView.isQsFullScreen()
                 && getVisibleNotificationCount() == 0;
 
         mView.updateEmptyShadeView(
@@ -1420,7 +1399,7 @@
         return mNotificationRoundnessManager;
     }
 
-    public NotificationListContainer getNotificationListContainer() {
+    NotificationListContainer getNotificationListContainer() {
         return mNotificationListContainer;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutListContainerModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutListContainerModule.java
new file mode 100644
index 0000000..3dcaae2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutListContainerModule.java
@@ -0,0 +1,32 @@
+/*
+ * 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.stack;
+
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+public abstract class NotificationStackScrollLayoutListContainerModule {
+    @Provides
+    @CentralSurfacesComponent.CentralSurfacesScope
+    static NotificationListContainer provideListContainer(
+            NotificationStackScrollLayoutController nsslController) {
+        return nsslController.getNotificationListContainer();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 244103c..ccb37ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -68,6 +68,7 @@
 
     private UserHandle mCurrentUser;
     private boolean mInitialized;
+    private final String mSafetySpec;
 
     protected final Context mContext;
     protected final QSTileHost mHost;
@@ -113,6 +114,13 @@
         mIsReduceBrightColorsAvailable = isReduceBrightColorsAvailable;
         mDeviceControlsController = deviceControlsController;
         mWalletController = walletController;
+        String safetySpecRes;
+        try {
+            safetySpecRes = context.getResources().getString(R.string.safety_quick_settings_tile);
+        } catch (Resources.NotFoundException | NullPointerException e) {
+            safetySpecRes = null;
+        }
+        mSafetySpec = safetySpecRes;
     }
 
     /**
@@ -155,6 +163,9 @@
         if (!mAutoTracker.isAdded(WALLET)) {
             initWalletController();
         }
+        if (mSafetySpec != null && !mAutoTracker.isAdded(mSafetySpec)) {
+            initSafetyTile();
+        }
 
         int settingsN = mAutoAddSettingList.size();
         for (int i = 0; i < settingsN; i++) {
@@ -315,6 +326,15 @@
         }
     }
 
+    private void initSafetyTile() {
+        if (mSafetySpec == null) {
+            return;
+        }
+        if (mAutoTracker.isAdded(mSafetySpec)) return;
+        mHost.addTile(CustomTile.getComponentFromSpec(mSafetySpec), true);
+        mAutoTracker.setTileAdded(mSafetySpec);
+    }
+
     @VisibleForTesting
     final NightDisplayListener.Callback mNightDisplayCallback =
             new NightDisplayListener.Callback() {
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 d5d1cea..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()) {
@@ -717,7 +727,7 @@
             public void run() {
                 mNotificationShadeWindowController.setForceDozeBrightness(false);
             }
-        }, StatusBar.FADE_KEYGUARD_DURATION_PULSING);
+        }, CentralSurfaces.FADE_KEYGUARD_DURATION_PULSING);
     }
 
     public void finishKeyguardFadingAway() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 82e0e67..a7f950e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -222,7 +222,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.dagger.StatusBarPhoneModule;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
@@ -245,7 +245,6 @@
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
@@ -261,8 +260,20 @@
 
 import dagger.Lazy;
 
-/** */
-public class StatusBar extends CoreStartable implements
+/**
+ * A class handling initialization and coordination between some of the key central surfaces in
+ * System UI: The notification shade, the keyguard (lockscreen), and the status bar.
+ *
+ * This class is not our ideal architecture because it doesn't enforce much isolation between these
+ * three mostly disparate surfaces. In an ideal world, this class would not exist. Instead, we would
+ * break it up into three modules -- one for each of those three surfaces -- and we would define any
+ * APIs that are needed for these surfaces to communicate with each other when necessary.
+ *
+ * <b>If at all possible, please avoid adding additional code to this monstrous class! Our goal is
+ * to break up this class into many small classes, and any code added here will slow down that goal.
+ * </b>
+ */
+public class CentralSurfaces extends CoreStartable implements
         ActivityStarter,
         LifecycleOwner {
     public static final boolean MULTIUSER_DEBUG = false;
@@ -270,6 +281,7 @@
     protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
 
     // Should match the values in PhoneWindowManager
+    public static final String SYSTEM_DIALOG_REASON_KEY = "reason";
     public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
     public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
     static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
@@ -278,7 +290,7 @@
             "com.android.systemui.statusbar.banner_action_cancel";
     private static final String BANNER_ACTION_SETUP =
             "com.android.systemui.statusbar.banner_action_setup";
-    public static final String TAG = "StatusBar";
+    public static final String TAG = "CentralSurfaces";
     public static final boolean DEBUG = false;
     public static final boolean SPEW = false;
     public static final boolean DUMPTRUCK = true; // extra dumpsys info
@@ -343,8 +355,9 @@
 
     private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
     private final DreamOverlayStateController mDreamOverlayStateController;
-    private StatusBarCommandQueueCallbacks mCommandQueueCallbacks;
+    private CentralSurfacesCommandQueueCallbacks mCommandQueueCallbacks;
     private float mTransitionToFullShadeProgress = 0f;
+    private NotificationListContainer mNotifListContainer;
 
     void onStatusBarWindowStateChanged(@WindowVisibleState int state) {
         updateBubblesVisibility();
@@ -468,7 +481,7 @@
     private PhoneStatusBarTransitions mStatusBarTransitions;
     private AuthRippleController mAuthRippleController;
     @WindowVisibleState private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
-    protected NotificationShadeWindowController mNotificationShadeWindowController;
+    protected final NotificationShadeWindowController mNotificationShadeWindowController;
     private final StatusBarWindowController mStatusBarWindowController;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @VisibleForTesting
@@ -494,11 +507,8 @@
     protected NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     private final DozeParameters mDozeParameters;
     private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
-    private final StatusBarComponent.Factory mStatusBarComponentFactory;
+    private final CentralSurfacesComponent.Factory mCentralSurfacesComponentFactory;
     private final PluginManager mPluginManager;
-    private final Optional<LegacySplitScreen> mSplitScreenOptional;
-    private final StatusBarNotificationActivityStarter.Builder
-            mStatusBarNotificationActivityStarterBuilder;
     private final ShadeController mShadeController;
     private final InitController mInitController;
 
@@ -544,7 +554,7 @@
     private final MessageRouter mMessageRouter;
     private final WallpaperManager mWallpaperManager;
 
-    private StatusBarComponent mStatusBarComponent;
+    private CentralSurfacesComponent mCentralSurfacesComponent;
 
     // Flags for disabling the status bar
     // Two variables becaseu the first one evidently ran out of room for new flags.
@@ -653,7 +663,6 @@
     protected final BatteryController mBatteryController;
     protected boolean mPanelExpanded;
     private UiModeManager mUiModeManager;
-    protected boolean mIsKeyguard;
     private LogMaker mStatusBarStateLog;
     protected final NotificationIconAreaController mNotificationIconAreaController;
     @Nullable private View mAmbientIndicationContainer;
@@ -666,7 +675,7 @@
 
     private final ActivityLaunchAnimator mActivityLaunchAnimator;
     private NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
-    protected StatusBarNotificationPresenter mPresenter;
+    protected NotificationPresenter mPresenter;
     private NotificationActivityStarter mNotificationActivityStarter;
     private final Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
     private final Optional<BubblesManager> mBubblesManagerOptional;
@@ -685,13 +694,13 @@
 
 
     /**
-     * Public constructor for StatusBar.
+     * Public constructor for CentralSurfaces.
      *
-     * StatusBar is considered optional, and therefore can not be marked as @Inject directly.
+     * CentralSurfaces is considered optional, and therefore can not be marked as @Inject directly.
      * Instead, an @Provide method is included. See {@link StatusBarPhoneModule}.
      */
     @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
-    public StatusBar(
+    public CentralSurfaces(
             Context context,
             NotificationsController notificationsController,
             FragmentService fragmentService,
@@ -751,11 +760,8 @@
             DozeScrimController dozeScrimController,
             VolumeComponent volumeComponent,
             CommandQueue commandQueue,
-            StatusBarComponent.Factory statusBarComponentFactory,
+            CentralSurfacesComponent.Factory centralSurfacesComponentFactory,
             PluginManager pluginManager,
-            Optional<LegacySplitScreen> splitScreenOptional,
-            StatusBarNotificationActivityStarter.Builder
-                    statusBarNotificationActivityStarterBuilder,
             ShadeController shadeController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             ViewMediatorCallback viewMediatorCallback,
@@ -850,10 +856,8 @@
         mNotificationShadeDepthControllerLazy = notificationShadeDepthControllerLazy;
         mVolumeComponent = volumeComponent;
         mCommandQueue = commandQueue;
-        mStatusBarComponentFactory = statusBarComponentFactory;
+        mCentralSurfacesComponentFactory = centralSurfacesComponentFactory;
         mPluginManager = pluginManager;
-        mSplitScreenOptional = splitScreenOptional;
-        mStatusBarNotificationActivityStarterBuilder = statusBarNotificationActivityStarterBuilder;
         mShadeController = shadeController;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mKeyguardViewMediatorCallback = viewMediatorCallback;
@@ -882,7 +886,7 @@
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         mStartingSurfaceOptional = startingSurfaceOptional;
         mNotifPipelineFlags = notifPipelineFlags;
-        lockscreenShadeTransitionController.setStatusbar(this);
+        lockscreenShadeTransitionController.setCentralSurfaces(this);
         statusBarWindowStateController.addListener(this::onStatusBarWindowStateChanged);
 
         mScreenOffAnimationController = screenOffAnimationController;
@@ -1114,7 +1118,7 @@
     }
 
     private void onFoldedStateChanged(boolean isFolded, boolean willGoToSleep) {
-        Trace.beginSection("StatusBar#onFoldedStateChanged");
+        Trace.beginSection("CentralSurfaces#onFoldedStateChanged");
         onFoldedStateChangedInternal(isFolded, willGoToSleep);
         Trace.endSection();
     }
@@ -1137,7 +1141,7 @@
         }
         if (leaveOpen) {
             mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
-            if (mIsKeyguard) {
+            if (mKeyguardStateController.isShowing()) {
                 // When device state changes on keyguard we don't want to keep the state of
                 // the shade and instead we open clean state of keyguard with shade closed.
                 // Normally some parts of QS state (like expanded/collapsed) are persisted and
@@ -1158,19 +1162,14 @@
         updateTheme();
 
         inflateStatusBarWindow();
-        mNotificationShadeWindowViewController.setService(this, mNotificationShadeWindowController);
         mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
         mWallpaperController.setRootView(mNotificationShadeWindowView);
 
-        // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
+        // TODO: Deal with the ugliness that comes from having some of the status bar broken out
         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
-        NotificationListContainer notifListContainer =
-                mStackScrollerController.getNotificationListContainer();
-        mNotificationLogger.setUpWithContainer(notifListContainer);
-
+        mNotificationLogger.setUpWithContainer(mNotifListContainer);
         mNotificationIconAreaController.setupShelf(mNotificationShelfController);
         mPanelExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
-
         mUserSwitcherController.init(mNotificationShadeWindowView);
 
         // Allow plugins to reference DarkIconDispatcher and StatusBarStateController
@@ -1178,7 +1177,7 @@
         mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
 
         // Set up CollapsedStatusBarFragment and PhoneStatusBarView
-        StatusBarInitializer initializer = mStatusBarComponent.getStatusBarInitializer();
+        StatusBarInitializer initializer = mCentralSurfacesComponent.getStatusBarInitializer();
         initializer.setStatusBarViewUpdatedListener(
                 (statusBarView, statusBarViewController, statusBarTransitions) -> {
                     mStatusBarView = statusBarView;
@@ -1195,7 +1194,7 @@
                     setBouncerShowingForStatusBarComponents(mBouncerShowing);
                     checkBarModes();
                 });
-        initializer.initializeStatusBar(mStatusBarComponent);
+        initializer.initializeStatusBar(mCentralSurfacesComponent);
 
         mStatusBarTouchableRegionManager.setup(this, mNotificationShadeWindowView);
         mHeadsUpManager.addListener(mNotificationPanelViewController.getOnHeadsUpChangedListener());
@@ -1445,65 +1444,19 @@
         mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
         mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
                 mNotificationShadeWindowViewController,
-                mStackScrollerController.getNotificationListContainer(),
+                mNotifListContainer,
                 mHeadsUpManager,
-                mJankMonitor
-        );
-
-        // TODO: inject this.
-        mPresenter = new StatusBarNotificationPresenter(
-                mContext,
-                mNotificationPanelViewController,
-                mHeadsUpManager,
-                mNotificationShadeWindowView,
-                mStackScrollerController,
-                mDozeScrimController,
-                mScrimController,
-                mNotificationShadeWindowController,
-                mDynamicPrivacyController,
-                mKeyguardStateController,
-                mKeyguardIndicationController,
-                this /* statusBar */,
-                mShadeController,
-                mLockscreenShadeTransitionController,
-                mCommandQueue,
-                mViewHierarchyManager,
-                mLockscreenUserManager,
-                mStatusBarStateController,
-                mNotifShadeEventSource,
-                mEntryManager,
-                mMediaManager,
-                mGutsManager,
-                mKeyguardUpdateMonitor,
-                mLockscreenGestureLogger,
-                mInitController,
-                mNotificationInterruptStateProvider,
-                mRemoteInputManager,
-                mConfigurationController,
-                mNotifPipelineFlags);
-
+                mJankMonitor);
         mNotificationShelfController.setOnActivatedListener(mPresenter);
         mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
-
-        mNotificationActivityStarter =
-                mStatusBarNotificationActivityStarterBuilder
-                        .setStatusBar(this)
-                        .setActivityLaunchAnimator(mActivityLaunchAnimator)
-                        .setNotificationAnimatorControllerProvider(mNotificationAnimationProvider)
-                        .setNotificationPresenter(mPresenter)
-                        .setNotificationPanelViewController(mNotificationPanelViewController)
-                        .build();
         mStackScrollerController.setNotificationActivityStarter(mNotificationActivityStarter);
         mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
-
         mNotificationsController.initialize(
-                this,
-                mBubblesOptional,
                 mPresenter,
-                mStackScrollerController.getNotificationListContainer(),
+                mNotifListContainer,
                 mStackScrollerController.getNotifStackController(),
                 mNotificationActivityStarter,
-                mPresenter);
+                mCentralSurfacesComponent.getBindRowCallback());
     }
 
     /**
@@ -1551,7 +1504,7 @@
         return (v, event) -> {
             mAutoHideController.checkUserAutoHide(event);
             mRemoteInputManager.checkRemoteInputOutside(event);
-            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+            if (event.getAction() == MotionEvent.ACTION_UP) {
                 if (mExpandedVisible) {
                     mShadeController.animateCollapsePanels();
                 }
@@ -1561,30 +1514,34 @@
     }
 
     private void inflateStatusBarWindow() {
-        if (mStatusBarComponent != null) {
+        if (mCentralSurfacesComponent != null) {
             // Tear down
-            for (StatusBarComponent.Startable startable : mStatusBarComponent.getStartables()) {
-                startable.stop();
+            for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
+                s.stop();
             }
         }
-        mStatusBarComponent = mStatusBarComponentFactory.create();
-        mFragmentService.addFragmentInstantiationProvider(mStatusBarComponent);
+        mCentralSurfacesComponent = mCentralSurfacesComponentFactory.create();
+        mFragmentService.addFragmentInstantiationProvider(mCentralSurfacesComponent);
 
-        mNotificationShadeWindowView = mStatusBarComponent.getNotificationShadeWindowView();
-        mNotificationShadeWindowViewController = mStatusBarComponent
+        mNotificationShadeWindowView = mCentralSurfacesComponent.getNotificationShadeWindowView();
+        mNotificationShadeWindowViewController = mCentralSurfacesComponent
                 .getNotificationShadeWindowViewController();
         mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
         mNotificationShadeWindowViewController.setupExpandedStatusBar();
-        mNotificationPanelViewController = mStatusBarComponent.getNotificationPanelViewController();
-        mStatusBarComponent.getLockIconViewController().init();
-        mStackScrollerController = mStatusBarComponent.getNotificationStackScrollLayoutController();
+        mNotificationPanelViewController =
+                mCentralSurfacesComponent.getNotificationPanelViewController();
+        mCentralSurfacesComponent.getLockIconViewController().init();
+        mStackScrollerController =
+                mCentralSurfacesComponent.getNotificationStackScrollLayoutController();
         mStackScroller = mStackScrollerController.getView();
-
-        mNotificationShelfController = mStatusBarComponent.getNotificationShelfController();
-        mAuthRippleController = mStatusBarComponent.getAuthRippleController();
+        mNotifListContainer = mCentralSurfacesComponent.getNotificationListContainer();
+        mPresenter = mCentralSurfacesComponent.getNotificationPresenter();
+        mNotificationActivityStarter = mCentralSurfacesComponent.getNotificationActivityStarter();
+        mNotificationShelfController = mCentralSurfacesComponent.getNotificationShelfController();
+        mAuthRippleController = mCentralSurfacesComponent.getAuthRippleController();
         mAuthRippleController.init();
 
-        mHeadsUpManager.addListener(mStatusBarComponent.getStatusBarHeadsUpChangeListener());
+        mHeadsUpManager.addListener(mCentralSurfacesComponent.getStatusBarHeadsUpChangeListener());
 
         // Listen for demo mode changes
         mDemoModeController.addCallback(mDemoModeCallback);
@@ -1592,18 +1549,19 @@
         if (mCommandQueueCallbacks != null) {
             mCommandQueue.removeCallback(mCommandQueueCallbacks);
         }
-        mCommandQueueCallbacks = mStatusBarComponent.getStatusBarCommandQueueCallbacks();
+        mCommandQueueCallbacks =
+                mCentralSurfacesComponent.getCentralSurfacesCommandQueueCallbacks();
         // Connect in to the status bar manager service
         mCommandQueue.addCallback(mCommandQueueCallbacks);
 
-        // Perform all other initialization for StatusBarScope
-        for (StatusBarComponent.Startable startable : mStatusBarComponent.getStartables()) {
-            startable.start();
+        // Perform all other initialization for CentralSurfacesScope
+        for (CentralSurfacesComponent.Startable s : mCentralSurfacesComponent.getStartables()) {
+            s.start();
         }
     }
 
     protected void startKeyguard() {
-        Trace.beginSection("StatusBar#startKeyguard");
+        Trace.beginSection("CentralSurfaces#startKeyguard");
         mBiometricUnlockController = mBiometricUnlockControllerLazy.get();
         mBiometricUnlockController.setBiometricModeListener(
                 new BiometricUnlockController.BiometricModeListener() {
@@ -1624,7 +1582,7 @@
 
                     @Override
                     public void notifyBiometricAuthModeChanged() {
-                        StatusBar.this.notifyBiometricAuthModeChanged();
+                        CentralSurfaces.this.notifyBiometricAuthModeChanged();
                     }
 
                     private void setWakeAndUnlocking(boolean wakeAndUnlocking) {
@@ -1633,7 +1591,7 @@
                         }
                     }
                 });
-        mStatusBarKeyguardViewManager.registerStatusBar(
+        mStatusBarKeyguardViewManager.registerCentralSurfaces(
                 /* statusBar= */ this,
                 mNotificationPanelViewController,
                 mPanelExpansionStateManager,
@@ -1672,35 +1630,6 @@
         return mStatusBarWindowController.getStatusBarHeight();
     }
 
-    public boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
-        if (!mSplitScreenOptional.isPresent()) {
-            return false;
-        }
-
-        final LegacySplitScreen legacySplitScreen = mSplitScreenOptional.get();
-        if (legacySplitScreen.isDividerVisible()) {
-            if (legacySplitScreen.isMinimized() && !legacySplitScreen.isHomeStackResizable()) {
-                // Undocking from the minimized state is not supported
-                return false;
-            }
-
-            legacySplitScreen.onUndockingTask();
-            if (metricsUndockAction != -1) {
-                mMetricsLogger.action(metricsUndockAction);
-            }
-            return true;
-        }
-
-        if (legacySplitScreen.splitPrimaryTask()) {
-            if (metricsDockAction != -1) {
-                mMetricsLogger.action(metricsDockAction);
-            }
-            return true;
-        }
-
-        return false;
-    }
-
     /**
      * Disable QS if device not provisioned.
      * If the user switcher is simple then disable QS during setup because
@@ -1791,7 +1720,7 @@
                     getDelegate().onIntentStarted(willAnimate);
 
                     if (willAnimate) {
-                        StatusBar.this.mIsLaunchingActivityOverLockscreen = true;
+                        CentralSurfaces.this.mIsLaunchingActivityOverLockscreen = true;
                     }
                 }
 
@@ -1801,7 +1730,7 @@
                     // animation so that we can assume that mIsLaunchingActivityOverLockscreen
                     // being true means that we will collapse the shade (or at least run the
                     // post collapse runnables) later on.
-                    StatusBar.this.mIsLaunchingActivityOverLockscreen = false;
+                    CentralSurfaces.this.mIsLaunchingActivityOverLockscreen = false;
                     getDelegate().onLaunchAnimationEnd(isExpandingFullyAbove);
                 }
 
@@ -1811,7 +1740,7 @@
                     // animation so that we can assume that mIsLaunchingActivityOverLockscreen
                     // being true means that we will collapse the shade (or at least run the
                     // post collapse runnables) later on.
-                    StatusBar.this.mIsLaunchingActivityOverLockscreen = false;
+                    CentralSurfaces.this.mIsLaunchingActivityOverLockscreen = false;
                     getDelegate().onLaunchAnimationCancelled();
                 }
             };
@@ -1940,7 +1869,13 @@
         if (!mPresenter.isCollapsing()) {
             onClosingFinished();
         }
-        if (launchIsFullScreen) {
+
+        // Collapse the panel if we're launching in fullscreen, over the lockscreen. Do not do this
+        // if the device has gone back to sleep - through a horrific chain of 15 or so function
+        // calls, instantCollapseNotificationPanel will eventually call through to
+        // StatusBar#wakeUpIfDozing, which will wake the device up even if it was put to sleep
+        // during the launch animation.
+        if (launchIsFullScreen && mPowerManager.isInteractive()) {
             instantCollapseNotificationPanel();
         }
     }
@@ -2635,7 +2570,7 @@
                         // ordering.
                         mMainExecutor.execute(mShadeController::runPostCollapseRunnables);
                     }
-                } else if (StatusBar.this.isInLaunchTransition()
+                } else if (CentralSurfaces.this.isInLaunchTransition()
                         && mNotificationPanelViewController.isLaunchTransitionFinished()) {
 
                     // We are not dismissing the shade, but the launch transition is already
@@ -2658,18 +2593,15 @@
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            Trace.beginSection("StatusBar#onReceive");
+            Trace.beginSection("CentralSurfaces#onReceive");
             if (DEBUG) Log.v(TAG, "onReceive: " + intent);
             String action = intent.getAction();
+            String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
                 KeyboardShortcuts.dismiss();
                 mRemoteInputManager.closeRemoteInputs();
-                if (mBubblesOptional.isPresent() && mBubblesOptional.get().isStackExpanded()) {
-                    mBubblesOptional.get().collapseStack();
-                }
                 if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
                     int flags = CommandQueue.FLAG_EXCLUDE_NONE;
-                    String reason = intent.getStringExtra("reason");
                     if (reason != null) {
                         if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                             flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
@@ -2684,19 +2616,13 @@
                     }
                     mShadeController.animateCollapsePanels(flags);
                 }
-            }
-            else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                 if (mNotificationShadeWindowController != null) {
                     mNotificationShadeWindowController.setNotTouchable(false);
                 }
-                if (mBubblesOptional.isPresent() && mBubblesOptional.get().isStackExpanded()) {
-                    // Post to main thread, since updating the UI.
-                    mMainExecutor.execute(() -> mBubblesOptional.get().collapseStack());
-                }
                 finishBarAnimations();
                 resetUserExpandedStates();
-            }
-            else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
+            } else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
                 mQSPanelController.showDeviceMonitoringDialog();
             }
             Trace.endSection();
@@ -2813,7 +2739,9 @@
     void handleVisibleToUserChangedImpl(boolean visibleToUser) {
         if (visibleToUser) {
             /* The LEDs are turned off when the notification panel is shown, even just a little bit.
-             * See also StatusBar.setPanelExpanded for another place where we attempt to do this. */
+             * See also CentralSurfaces.setPanelExpanded for another place where we attempt to do
+             * this.
+             */
             boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
             boolean clearNotificationEffects =
                     !mPresenter.isPresenterFullyCollapsed() &&
@@ -2961,9 +2889,12 @@
         // late in the transition, so we also allow the device to start dozing once the screen has
         // turned off fully.
         boolean keyguardForDozing = mDozeServiceHost.getDozingRequested()
-                && (!mDeviceInteractive || isGoingToSleep() && (isScreenFullyOff() || mIsKeyguard));
+                && (!mDeviceInteractive || (isGoingToSleep()
+                    && (isScreenFullyOff()
+                        || (mKeyguardStateController.isShowing() && !isOccluded()))));
+        boolean isWakingAndOccluded = isOccluded() && isWaking();
         boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
-                || keyguardForDozing) && !wakeAndUnlocking;
+                || keyguardForDozing) && !wakeAndUnlocking && !isWakingAndOccluded;
         if (keyguardForDozing) {
             updatePanelExpansionForKeyguard();
         }
@@ -2992,8 +2923,7 @@
     }
 
     public void showKeyguardImpl() {
-        Trace.beginSection("StatusBar#showKeyguard");
-        mIsKeyguard = true;
+        Trace.beginSection("CentralSurfaces#showKeyguard");
         // In case we're locking while a smartspace transition is in progress, reset it.
         mKeyguardUnlockAnimationController.resetSmartspaceTransition();
         if (mKeyguardStateController.isLaunchTransitionFadingAway()) {
@@ -3114,8 +3044,7 @@
      * @return true if we would like to stay in the shade, false if it should go away entirely
      */
     public boolean hideKeyguardImpl(boolean forceStateChange) {
-        mIsKeyguard = false;
-        Trace.beginSection("StatusBar#hideKeyguard");
+        Trace.beginSection("CentralSurfaces#hideKeyguard");
         boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
         int previousState = mStatusBarStateController.getState();
         if (!(mStatusBarStateController.setState(StatusBarState.SHADE, forceStateChange))) {
@@ -3232,7 +3161,7 @@
 
     private void updateDozingState() {
         Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
-        Trace.beginSection("StatusBar#updateDozingState");
+        Trace.beginSection("CentralSurfaces#updateDozingState");
 
         boolean visibleNotOccluded = mStatusBarKeyguardViewManager.isShowing()
                 && !mStatusBarKeyguardViewManager.isOccluded();
@@ -3587,7 +3516,7 @@
 
         @Override
         public void onStartedGoingToSleep() {
-            String tag = "StatusBar#onStartedGoingToSleep";
+            String tag = "CentralSurfaces#onStartedGoingToSleep";
             DejankUtils.startDetectingBlockingIpcs(tag);
             updateRevealEffect(false /* wakingUp */);
             updateNotificationPanelTouchState();
@@ -3607,7 +3536,7 @@
 
         @Override
         public void onStartedWakingUp() {
-            String tag = "StatusBar#onStartedWakingUp";
+            String tag = "CentralSurfaces#onStartedWakingUp";
             DejankUtils.startDetectingBlockingIpcs(tag);
             mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
                 mDeviceInteractive = true;
@@ -3682,7 +3611,7 @@
 
         @Override
         public void onScreenTurnedOff() {
-            Trace.beginSection("StatusBar#onScreenTurnedOff");
+            Trace.beginSection("CentralSurfaces#onScreenTurnedOff");
             mFalsingCollector.onScreenOff();
             mScrimController.onScreenTurnedOff();
             if (mCloseQsBeforeScreenOff) {
@@ -3773,6 +3702,10 @@
                 == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
     }
 
+    boolean isWaking() {
+        return mWakefulnessLifecycle.getWakefulness() == WakefulnessLifecycle.WAKEFULNESS_WAKING;
+    }
+
     public void notifyBiometricAuthModeChanged() {
         mDozeServiceHost.updateDozing();
         updateScrimController();
@@ -3789,7 +3722,7 @@
 
     @VisibleForTesting
     public void updateScrimController() {
-        Trace.beginSection("StatusBar#updateScrimController");
+        Trace.beginSection("CentralSurfaces#updateScrimController");
 
         boolean unlocking = mKeyguardStateController.isShowing() && (
                 mBiometricUnlockController.isWakeAndUnlock()
@@ -3837,7 +3770,7 @@
             });
         } else if (mDozing && !unlocking) {
             mScrimController.transitionTo(ScrimState.AOD);
-        } else if (mIsKeyguard && !unlocking) {
+        } else if (mKeyguardStateController.isShowing() && !isOccluded() && !unlocking) {
             mScrimController.transitionTo(ScrimState.KEYGUARD);
         } else {
             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
@@ -4044,8 +3977,14 @@
 
                 mActivityLaunchAnimator.startPendingIntentWithAnimation(
                         controller, animate, intent.getCreatorPackage(),
-                        (animationAdapter) -> intent.sendAndReturnResult(null, 0, null, null, null,
-                                null, getActivityOptions(mDisplayId, animationAdapter)));
+                        (animationAdapter) -> {
+                            ActivityOptions options = new ActivityOptions(
+                                    getActivityOptions(mDisplayId, animationAdapter));
+                            // TODO b/221255671: restrict this to only be set for notifications
+                            options.setEligibleForLegacyPermissionPrompt(true);
+                            return intent.sendAndReturnResult(null, 0, null, null, null,
+                                    null, options.toBundle());
+                        });
             } catch (PendingIntent.CanceledException e) {
                 // the stack trace isn't very helpful here.
                 // Just log the exception message.
@@ -4355,7 +4294,7 @@
             if (mBrightnessMirrorController != null) {
                 mBrightnessMirrorController.onDensityOrFontScaleChanged();
             }
-            // TODO: Bring these out of StatusBar.
+            // TODO: Bring these out of CentralSurfaces.
             mUserInfoControllerImpl.onDensityOrFontScaleChanged();
             mUserSwitcherController.onDensityOrFontScaleChanged();
             mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
@@ -4413,7 +4352,7 @@
                     mDozeServiceHost.updateDozing();
                     updateTheme();
                     mNavigationBarController.touchAutoDim(mDisplayId);
-                    Trace.beginSection("StatusBar#updateKeyguardState");
+                    Trace.beginSection("CentralSurfaces#updateKeyguardState");
                     if (mState == StatusBarState.KEYGUARD) {
                         mNotificationPanelViewController.cancelPendingPanelCollapse();
                     }
@@ -4436,7 +4375,7 @@
 
                 @Override
                 public void onDozingChanged(boolean isDozing) {
-                    Trace.beginSection("StatusBar#updateDozing");
+                    Trace.beginSection("CentralSurfaces#updateDozing");
                     mDozing = isDozing;
 
                     // Collapse the notification panel if open
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
similarity index 80%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 4081962..536be1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -59,26 +59,24 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 
 import java.util.Optional;
 
 import javax.inject.Inject;
 
 /** */
-@StatusBarComponent.StatusBarScope
-public class StatusBarCommandQueueCallbacks implements CommandQueue.Callbacks {
-    private final StatusBar mStatusBar;
+@CentralSurfacesComponent.CentralSurfacesScope
+public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callbacks {
+    private final CentralSurfaces mCentralSurfaces;
     private final Context mContext;
     private final ShadeController mShadeController;
     private final CommandQueue mCommandQueue;
     private final NotificationPanelViewController mNotificationPanelViewController;
-    private final Optional<LegacySplitScreen> mSplitScreenOptional;
     private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
     private final MetricsLogger mMetricsLogger;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -107,14 +105,13 @@
             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
 
     @Inject
-    StatusBarCommandQueueCallbacks(
-            StatusBar statusBar,
+    CentralSurfacesCommandQueueCallbacks(
+            CentralSurfaces centralSurfaces,
             Context context,
             @Main Resources resources,
             ShadeController shadeController,
             CommandQueue commandQueue,
             NotificationPanelViewController notificationPanelViewController,
-            Optional<LegacySplitScreen> splitScreenOptional,
             RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
             MetricsLogger metricsLogger,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -136,12 +133,11 @@
             DisableFlagsLogger disableFlagsLogger,
             @DisplayId int displayId) {
 
-        mStatusBar = statusBar;
+        mCentralSurfaces = centralSurfaces;
         mContext = context;
         mShadeController = shadeController;
         mCommandQueue = commandQueue;
         mNotificationPanelViewController = notificationPanelViewController;
-        mSplitScreenOptional = splitScreenOptional;
         mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler;
         mMetricsLogger = metricsLogger;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -176,12 +172,12 @@
         if (!containsType(types, ITYPE_STATUS_BAR)) {
             return;
         }
-        mStatusBar.clearTransient();
+        mCentralSurfaces.clearTransient();
     }
 
     @Override
     public void addQsTile(ComponentName tile) {
-        QSPanelController qsPanelController = mStatusBar.getQSPanelController();
+        QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
         if (qsPanelController != null && qsPanelController.getHost() != null) {
             qsPanelController.getHost().addTile(tile);
         }
@@ -189,7 +185,7 @@
 
     @Override
     public void remQsTile(ComponentName tile) {
-        QSPanelController qsPanelController = mStatusBar.getQSPanelController();
+        QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
         if (qsPanelController != null && qsPanelController.getHost() != null) {
             qsPanelController.getHost().removeTile(tile);
         }
@@ -197,7 +193,7 @@
 
     @Override
     public void clickTile(ComponentName tile) {
-        QSPanelController qsPanelController = mStatusBar.getQSPanelController();
+        QSPanelController qsPanelController = mCentralSurfaces.getQSPanelController();
         if (qsPanelController != null) {
             qsPanelController.clickTile(tile);
         }
@@ -211,9 +207,9 @@
 
     @Override
     public void animateExpandNotificationsPanel() {
-        if (StatusBar.SPEW) {
-            Log.d(StatusBar.TAG,
-                    "animateExpand: mExpandedVisible=" + mStatusBar.isExpandedVisible());
+        if (CentralSurfaces.SPEW) {
+            Log.d(CentralSurfaces.TAG,
+                    "animateExpand: mExpandedVisible=" + mCentralSurfaces.isExpandedVisible());
         }
         if (!mCommandQueue.panelsEnabled()) {
             return;
@@ -224,9 +220,9 @@
 
     @Override
     public void animateExpandSettingsPanel(@Nullable String subPanel) {
-        if (StatusBar.SPEW) {
-            Log.d(StatusBar.TAG,
-                    "animateExpand: mExpandedVisible=" + mStatusBar.isExpandedVisible());
+        if (CentralSurfaces.SPEW) {
+            Log.d(CentralSurfaces.TAG,
+                    "animateExpand: mExpandedVisible=" + mCentralSurfaces.isExpandedVisible());
         }
         if (!mCommandQueue.panelsEnabled()) {
             return;
@@ -240,21 +236,15 @@
 
     @Override
     public void appTransitionCancelled(int displayId) {
-        if (displayId == mDisplayId) {
-            mSplitScreenOptional.ifPresent(LegacySplitScreen::onAppTransitionFinished);
-        }
     }
 
     @Override
     public void appTransitionFinished(int displayId) {
-        if (displayId == mDisplayId) {
-            mSplitScreenOptional.ifPresent(LegacySplitScreen::onAppTransitionFinished);
-        }
     }
 
     @Override
     public void dismissKeyboardShortcutsMenu() {
-        mStatusBar.resendMessage(StatusBar.MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU);
+        mCentralSurfaces.resendMessage(CentralSurfaces.MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU);
     }
     /**
      * State is one or more of the DISABLE constants from StatusBarManager.
@@ -267,22 +257,22 @@
 
         int state2BeforeAdjustment = state2;
         state2 = mRemoteInputQuickSettingsDisabler.adjustDisableFlags(state2);
-        Log.d(StatusBar.TAG,
+        Log.d(CentralSurfaces.TAG,
                 mDisableFlagsLogger.getDisableFlagsString(
                         /* old= */ new DisableFlagsLogger.DisableState(
-                                mStatusBar.getDisabled1(), mStatusBar.getDisabled2()),
+                                mCentralSurfaces.getDisabled1(), mCentralSurfaces.getDisabled2()),
                         /* new= */ new DisableFlagsLogger.DisableState(
                                 state1, state2BeforeAdjustment),
                         /* newStateAfterLocalModification= */ new DisableFlagsLogger.DisableState(
                                 state1, state2)));
 
-        final int old1 = mStatusBar.getDisabled1();
+        final int old1 = mCentralSurfaces.getDisabled1();
         final int diff1 = state1 ^ old1;
-        mStatusBar.setDisabled1(state1);
+        mCentralSurfaces.setDisabled1(state1);
 
-        final int old2 = mStatusBar.getDisabled2();
+        final int old2 = mCentralSurfaces.getDisabled2();
         final int diff2 = state2 ^ old2;
-        mStatusBar.setDisabled2(state2);
+        mCentralSurfaces.setDisabled2(state2);
 
         if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
             if ((state1 & StatusBarManager.DISABLE_EXPAND) != 0) {
@@ -291,17 +281,17 @@
         }
 
         if ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
-            if (mStatusBar.areNotificationAlertsDisabled()) {
+            if (mCentralSurfaces.areNotificationAlertsDisabled()) {
                 mHeadsUpManager.releaseAllImmediately();
             }
         }
 
         if ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) {
-            mStatusBar.updateQsExpansionEnabled();
+            mCentralSurfaces.updateQsExpansionEnabled();
         }
 
         if ((diff2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0) {
-            mStatusBar.updateQsExpansionEnabled();
+            mCentralSurfaces.updateQsExpansionEnabled();
             if ((state2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0) {
                 mShadeController.animateCollapsePanels();
             }
@@ -314,8 +304,8 @@
      */
     @Override
     public void handleSystemKey(int key) {
-        if (StatusBar.SPEW) {
-            Log.d(StatusBar.TAG, "handleNavigationKey: " + key);
+        if (CentralSurfaces.SPEW) {
+            Log.d(CentralSurfaces.TAG, "handleNavigationKey: " + key);
         }
         if (!mCommandQueue.panelsEnabled() || !mKeyguardUpdateMonitor.isDeviceInteractive()
                 || mKeyguardStateController.isShowing() && !mKeyguardStateController.isOccluded()) {
@@ -351,81 +341,82 @@
 
     @Override
     public void onCameraLaunchGestureDetected(int source) {
-        mStatusBar.setLastCameraLaunchSource(source);
-        if (mStatusBar.isGoingToSleep()) {
-            if (StatusBar.DEBUG_CAMERA_LIFT) {
-                Slog.d(StatusBar.TAG, "Finish going to sleep before launching camera");
+        mCentralSurfaces.setLastCameraLaunchSource(source);
+        if (mCentralSurfaces.isGoingToSleep()) {
+            if (CentralSurfaces.DEBUG_CAMERA_LIFT) {
+                Slog.d(CentralSurfaces.TAG, "Finish going to sleep before launching camera");
             }
-            mStatusBar.setLaunchCameraOnFinishedGoingToSleep(true);
+            mCentralSurfaces.setLaunchCameraOnFinishedGoingToSleep(true);
             return;
         }
         if (!mNotificationPanelViewController.canCameraGestureBeLaunched()) {
-            if (StatusBar.DEBUG_CAMERA_LIFT) {
-                Slog.d(StatusBar.TAG, "Can't launch camera right now");
+            if (CentralSurfaces.DEBUG_CAMERA_LIFT) {
+                Slog.d(CentralSurfaces.TAG, "Can't launch camera right now");
             }
             return;
         }
-        if (!mStatusBar.isDeviceInteractive()) {
+        if (!mCentralSurfaces.isDeviceInteractive()) {
             mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
                     "com.android.systemui:CAMERA_GESTURE");
         }
         vibrateForCameraGesture();
 
         if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
-            Log.v(StatusBar.TAG, "Camera launch");
+            Log.v(CentralSurfaces.TAG, "Camera launch");
             mKeyguardUpdateMonitor.onCameraLaunched();
         }
 
         if (!mStatusBarKeyguardViewManager.isShowing()) {
             final Intent cameraIntent = CameraIntents.getInsecureCameraIntent(mContext);
-            mStatusBar.startActivityDismissingKeyguard(cameraIntent,
+            mCentralSurfaces.startActivityDismissingKeyguard(cameraIntent,
                     false /* onlyProvisioned */, true /* dismissShade */,
                     true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0,
                     null /* animationController */);
         } else {
-            if (!mStatusBar.isDeviceInteractive()) {
+            if (!mCentralSurfaces.isDeviceInteractive()) {
                 // Avoid flickering of the scrim when we instant launch the camera and the bouncer
                 // comes on.
-                mStatusBar.acquireGestureWakeLock(StatusBar.LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
+                mCentralSurfaces.acquireGestureWakeLock(
+                        CentralSurfaces.LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
             }
             if (isWakingUpOrAwake()) {
-                if (StatusBar.DEBUG_CAMERA_LIFT) {
-                    Slog.d(StatusBar.TAG, "Launching camera");
+                if (CentralSurfaces.DEBUG_CAMERA_LIFT) {
+                    Slog.d(CentralSurfaces.TAG, "Launching camera");
                 }
                 if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                     mStatusBarKeyguardViewManager.reset(true /* hide */);
                 }
                 mNotificationPanelViewController.launchCamera(
-                        mStatusBar.isDeviceInteractive() /* animate */, source);
-                mStatusBar.updateScrimController();
+                        mCentralSurfaces.isDeviceInteractive() /* animate */, source);
+                mCentralSurfaces.updateScrimController();
             } else {
                 // We need to defer the camera launch until the screen comes on, since otherwise
                 // we will dismiss us too early since we are waiting on an activity to be drawn and
                 // incorrectly get notified because of the screen on event (which resumes and pauses
                 // some activities)
-                if (StatusBar.DEBUG_CAMERA_LIFT) {
-                    Slog.d(StatusBar.TAG, "Deferring until screen turns on");
+                if (CentralSurfaces.DEBUG_CAMERA_LIFT) {
+                    Slog.d(CentralSurfaces.TAG, "Deferring until screen turns on");
                 }
-                mStatusBar.setLaunchCameraOnFinishedWaking(true);
+                mCentralSurfaces.setLaunchCameraOnFinishedWaking(true);
             }
         }
     }
 
     @Override
     public void onEmergencyActionLaunchGestureDetected() {
-        Intent emergencyIntent = mStatusBar.getEmergencyActionIntent();
+        Intent emergencyIntent = mCentralSurfaces.getEmergencyActionIntent();
 
         if (emergencyIntent == null) {
-            Log.wtf(StatusBar.TAG, "Couldn't find an app to process the emergency intent.");
+            Log.wtf(CentralSurfaces.TAG, "Couldn't find an app to process the emergency intent.");
             return;
         }
 
         if (isGoingToSleep()) {
-            mStatusBar.setLaunchEmergencyActionOnFinishedGoingToSleep(true);
+            mCentralSurfaces.setLaunchEmergencyActionOnFinishedGoingToSleep(true);
             return;
         }
 
-        if (!mStatusBar.isDeviceInteractive()) {
+        if (!mCentralSurfaces.isDeviceInteractive()) {
             mPowerManager.wakeUp(SystemClock.uptimeMillis(),
                     PowerManager.WAKE_REASON_GESTURE,
                     "com.android.systemui:EMERGENCY_GESTURE");
@@ -434,17 +425,18 @@
         // app-side haptic experimentation.
 
         if (!mStatusBarKeyguardViewManager.isShowing()) {
-            mStatusBar.startActivityDismissingKeyguard(emergencyIntent,
+            mCentralSurfaces.startActivityDismissingKeyguard(emergencyIntent,
                     false /* onlyProvisioned */, true /* dismissShade */,
                     true /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */, 0,
                     null /* animationController */);
             return;
         }
 
-        if (!mStatusBar.isDeviceInteractive()) {
+        if (!mCentralSurfaces.isDeviceInteractive()) {
             // Avoid flickering of the scrim when we instant launch the camera and the bouncer
             // comes on.
-            mStatusBar.acquireGestureWakeLock(StatusBar.LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
+            mCentralSurfaces.acquireGestureWakeLock(
+                    CentralSurfaces.LAUNCH_TRANSITION_TIMEOUT_MS + 1000L);
         }
 
         if (isWakingUpOrAwake()) {
@@ -458,12 +450,12 @@
         // we will dismiss us too early since we are waiting on an activity to be drawn and
         // incorrectly get notified because of the screen on event (which resumes and pauses
         // some activities)
-        mStatusBar.setLaunchEmergencyActionOnFinishedWaking(true);
+        mCentralSurfaces.setLaunchEmergencyActionOnFinishedWaking(true);
     }
 
     @Override
     public void onRecentsAnimationStateChanged(boolean running) {
-        mStatusBar.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, running);
+        mCentralSurfaces.setInteracting(StatusBarManager.WINDOW_NAVIGATION_BAR, running);
     }
 
 
@@ -474,12 +466,12 @@
         if (displayId != mDisplayId) {
             return;
         }
-        boolean barModeChanged = mStatusBar.setAppearance(appearance);
+        boolean barModeChanged = mCentralSurfaces.setAppearance(appearance);
 
         mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
-                mStatusBar.getBarMode(), navbarColorManagedByIme);
+                mCentralSurfaces.getBarMode(), navbarColorManagedByIme);
 
-        mStatusBar.updateBubblesVisibility();
+        mCentralSurfaces.updateBubblesVisibility();
         mStatusBarStateController.setSystemBarAttributes(
                 appearance, behavior, requestedVisibilities, packageName);
     }
@@ -493,12 +485,12 @@
         if (!containsType(types, ITYPE_STATUS_BAR)) {
             return;
         }
-        mStatusBar.showTransientUnchecked();
+        mCentralSurfaces.showTransientUnchecked();
     }
 
     @Override
     public void toggleKeyboardShortcutsMenu(int deviceId) {
-        mStatusBar.resendMessage(new StatusBar.KeyboardShortcutsMessage(deviceId));
+        mCentralSurfaces.resendMessage(new CentralSurfaces.KeyboardShortcutsMessage(deviceId));
     }
 
     @Override
@@ -514,12 +506,12 @@
 
     @Override
     public void showPinningEnterExitToast(boolean entering) {
-        mStatusBar.showPinningEnterExitToast(entering);
+        mCentralSurfaces.showPinningEnterExitToast(entering);
     }
 
     @Override
     public void showPinningEscapeToast() {
-        mStatusBar.showPinningEscapeToast();
+        mCentralSurfaces.showPinningEscapeToast();
     }
 
     @Override
@@ -529,12 +521,12 @@
             return;
         }
         // Show screen pinning request, since this comes from an app, show 'no thanks', button.
-        mStatusBar.showScreenPinningRequest(taskId, true);
+        mCentralSurfaces.showScreenPinningRequest(taskId, true);
     }
 
     @Override
     public void showWirelessChargingAnimation(int batteryLevel) {
-        mStatusBar.showWirelessChargingAnimation(batteryLevel);
+        mCentralSurfaces.showWirelessChargingAnimation(batteryLevel);
     }
 
     @Override
@@ -544,23 +536,18 @@
 
     @Override
     public void suppressAmbientDisplay(boolean suppressed) {
-        mDozeServiceHost.setDozeSuppressed(suppressed);
+        mDozeServiceHost.setAlwaysOnSuppressed(suppressed);
     }
 
     @Override
     public void togglePanel() {
-        if (mStatusBar.isPanelExpanded()) {
+        if (mCentralSurfaces.isPanelExpanded()) {
             mShadeController.animateCollapsePanels();
         } else {
             animateExpandNotificationsPanel();
         }
     }
 
-    @Override
-    public void toggleSplitScreen() {
-        mStatusBar.toggleSplitScreenMode(-1 /* metricsDockAction */, -1 /* metricsUndockAction */);
-    }
-
     private boolean isGoingToSleep() {
         return mWakefulnessLifecycle.getWakefulness()
                 == WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
@@ -591,8 +578,8 @@
             // Make sure to pass -1 for repeat so VibratorManagerService doesn't stop us when going
             // to sleep.
             return VibrationEffect.createWaveform(
-                    StatusBar.CAMERA_LAUNCH_GESTURE_VIBRATION_TIMINGS,
-                    StatusBar.CAMERA_LAUNCH_GESTURE_VIBRATION_AMPLITUDES,
+                    CentralSurfaces.CAMERA_LAUNCH_GESTURE_VIBRATION_TIMINGS,
+                    CentralSurfaces.CAMERA_LAUNCH_GESTURE_VIBRATION_AMPLITUDES,
                     /* repeat= */ -1);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index b141110..8b25c2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -16,9 +16,14 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.content.ContentResolver;
+import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.net.Uri;
+import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -34,6 +39,7 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
 import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.doze.AlwaysOnDisplayPolicy;
 import com.android.systemui.doze.DozeScreenState;
@@ -86,6 +92,7 @@
 
     private boolean mDozeAlwaysOn;
     private boolean mControlScreenOffAnimation;
+    private boolean mIsQuickPickupEnabled;
 
     private boolean mKeyguardShowing;
     @VisibleForTesting
@@ -101,10 +108,17 @@
                 public void onShadeExpandedChanged(boolean expanded) {
                     updateControlScreenOff();
                 }
+
+                @Override
+                public void onUserSwitchComplete(int newUserId) {
+                    updateQuickPickupEnabled();
+                }
             };
 
     @Inject
     protected DozeParameters(
+            Context context,
+            @Background Handler handler,
             @Main Resources resources,
             AmbientDisplayConfiguration ambientDisplayConfiguration,
             AlwaysOnDisplayPolicy alwaysOnDisplayPolicy,
@@ -146,6 +160,14 @@
         if (mFoldAodAnimationController != null) {
             mFoldAodAnimationController.addCallback(this);
         }
+
+        SettingsObserver quickPickupSettingsObserver = new SettingsObserver(context, handler);
+        quickPickupSettingsObserver.observe();
+    }
+
+    private void updateQuickPickupEnabled() {
+        mIsQuickPickupEnabled =
+                mAmbientDisplayConfiguration.quickPickupSensorEnabled(UserHandle.USER_CURRENT);
     }
 
     public boolean getDisplayStateSupported() {
@@ -239,8 +261,11 @@
         return mDozeAlwaysOn && !mBatteryController.isAodPowerSave();
     }
 
+    /**
+     * Whether the quick pickup gesture is supported and enabled for the device.
+     */
     public boolean isQuickPickupEnabled() {
-        return mAmbientDisplayConfiguration.quickPickupSensorEnabled(UserHandle.USER_CURRENT);
+        return mIsQuickPickupEnabled;
     }
 
     /**
@@ -436,6 +461,7 @@
         pw.print("getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
         pw.print("getSelectivelyRegisterSensorsUsingProx(): ");
         pw.println(getSelectivelyRegisterSensorsUsingProx());
+        pw.print("isQuickPickupEnabled(): "); pw.println(isQuickPickupEnabled());
     }
 
     private boolean getPostureSpecificBool(
@@ -458,4 +484,44 @@
          */
         void onAlwaysOnChange();
     }
+
+    private final class SettingsObserver extends ContentObserver {
+        private final Uri mQuickPickupGesture =
+                Settings.Secure.getUriFor(Settings.Secure.DOZE_QUICK_PICKUP_GESTURE);
+        private final Uri mPickupGesture =
+                Settings.Secure.getUriFor(Settings.Secure.DOZE_PICK_UP_GESTURE);
+        private final Uri mAlwaysOnEnabled =
+                Settings.Secure.getUriFor(Settings.Secure.DOZE_ALWAYS_ON);
+        private final Context mContext;
+
+        SettingsObserver(Context context, Handler handler) {
+            super(handler);
+            mContext = context;
+        }
+
+        void observe() {
+            ContentResolver resolver = mContext.getContentResolver();
+            resolver.registerContentObserver(mQuickPickupGesture, false, this,
+                    UserHandle.USER_ALL);
+            resolver.registerContentObserver(mPickupGesture, false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(mAlwaysOnEnabled, false, this, UserHandle.USER_ALL);
+            update(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            update(uri);
+        }
+
+        public void update(Uri uri) {
+            if (uri == null
+                    || mQuickPickupGesture.equals(uri)
+                    || mPickupGesture.equals(uri)
+                    || mAlwaysOnEnabled.equals(uri)) {
+                // the quick pickup gesture is dependent on alwaysOn being disabled and
+                // the pickup gesture being enabled
+                updateQuickPickupEnabled();
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 05fba54..55b310f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -97,8 +97,8 @@
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private NotificationPanelViewController mNotificationPanel;
     private View mAmbientIndicationContainer;
-    private StatusBar mStatusBar;
-    private boolean mSuppressed;
+    private CentralSurfaces mCentralSurfaces;
+    private boolean mAlwaysOnSuppressed;
 
     @Inject
     public DozeServiceHost(DozeLog dozeLog, PowerManager powerManager,
@@ -146,12 +146,12 @@
      * Initialize instance with objects only available later during execution.
      */
     public void initialize(
-            StatusBar statusBar,
+            CentralSurfaces centralSurfaces,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             NotificationShadeWindowViewController notificationShadeWindowViewController,
             NotificationPanelViewController notificationPanel,
             View ambientIndicationContainer) {
-        mStatusBar = statusBar;
+        mCentralSurfaces = centralSurfaces;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mNotificationPanel = notificationPanel;
         mNotificationShadeWindowViewController = notificationShadeWindowViewController;
@@ -205,7 +205,7 @@
             mDozingRequested = true;
             updateDozing();
             mDozeLog.traceDozing(mStatusBarStateController.isDozing());
-            mStatusBar.updateIsKeyguard();
+            mCentralSurfaces.updateIsKeyguard();
         }
     }
 
@@ -247,13 +247,13 @@
                         && mWakeLockScreenPerformsAuth;
         // Set the state to pulsing, so ScrimController will know what to do once we ask it to
         // execute the transition. The pulse callback will then be invoked when the scrims
-        // are black, indicating that StatusBar is ready to present the rest of the UI.
+        // are black, indicating that CentralSurfaces is ready to present the rest of the UI.
         mPulsing = true;
         mDozeScrimController.pulse(new PulseCallback() {
             @Override
             public void onPulseStarted() {
                 callback.onPulseStarted();
-                mStatusBar.updateNotificationPanelTouchState();
+                mCentralSurfaces.updateNotificationPanelTouchState();
                 setPulsing(true);
             }
 
@@ -261,7 +261,7 @@
             public void onPulseFinished() {
                 mPulsing = false;
                 callback.onPulseFinished();
-                mStatusBar.updateNotificationPanelTouchState();
+                mCentralSurfaces.updateNotificationPanelTouchState();
                 mScrimController.setWakeLockScreenSensorActive(false);
                 setPulsing(false);
             }
@@ -274,14 +274,14 @@
                 if (mKeyguardUpdateMonitor != null && passiveAuthInterrupt) {
                     mKeyguardUpdateMonitor.onAuthInterruptDetected(pulsing /* active */);
                 }
-                mStatusBar.updateScrimController();
+                mCentralSurfaces.updateScrimController();
                 mPulseExpansionHandler.setPulsing(pulsing);
                 mNotificationWakeUpCoordinator.setPulsing(pulsing);
             }
         }, reason);
         // DozeScrimController is in pulse state, now let's ask ScrimController to start
         // pulsing and draw the black frame, if necessary.
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
     }
 
     @Override
@@ -332,15 +332,6 @@
     }
 
     @Override
-    public boolean isBlockingDoze() {
-        if (mBiometricUnlockControllerLazy.get().hasPendingAuthentication()) {
-            Log.i(StatusBar.TAG, "Blocking AOD because fingerprint has authenticated");
-            return true;
-        }
-        return false;
-    }
-
-    @Override
     public void extendPulse(int reason) {
         if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH) {
             mScrimController.setWakeLockScreenSensorActive(true);
@@ -412,14 +403,14 @@
             Log.w(TAG, "Overlapping onDisplayOffCallback. Ignoring previous one.");
         }
         mPendingScreenOffCallback = onDisplayOffCallback;
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
     }
 
     @Override
     public void cancelGentleSleep() {
         mPendingScreenOffCallback = null;
         if (mScrimController.getState() == ScrimState.OFF) {
-            mStatusBar.updateScrimController();
+            mCentralSurfaces.updateScrimController();
         }
     }
 
@@ -452,18 +443,25 @@
         return mIgnoreTouchWhilePulsing;
     }
 
-    void setDozeSuppressed(boolean suppressed) {
-        if (suppressed == mSuppressed) {
+    /**
+     * Suppresses always-on-display and waking up the display for notifications.
+     * Does not disable wakeup gestures like pickup and tap.
+     */
+    void setAlwaysOnSuppressed(boolean suppressed) {
+        if (suppressed == mAlwaysOnSuppressed) {
             return;
         }
-        mSuppressed = suppressed;
-        mDozeLog.traceDozingSuppressed(mSuppressed);
+        mAlwaysOnSuppressed = suppressed;
         for (Callback callback : mCallbacks) {
-            callback.onDozeSuppressedChanged(suppressed);
+            callback.onAlwaysOnSuppressedChanged(suppressed);
         }
     }
 
-    public boolean isDozeSuppressed() {
-        return mSuppressed;
+    /**
+     * Whether always-on-display is being suppressed. This does not affect wakeup gestures like
+     * pickup and tap.
+     */
+    public boolean isAlwaysOnSuppressed() {
+        return mAlwaysOnSuppressed;
     }
 }
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 84103c0..dc1af36 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;
@@ -118,7 +117,7 @@
         KeyguardStateController.Callback,
         AccessibilityController.AccessibilityStateChangedCallback {
 
-    final static String TAG = "StatusBar/KeyguardBottomAreaView";
+    final static String TAG = "CentralSurfaces/KeyguardBottomAreaView";
 
     public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
     public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
@@ -169,7 +168,7 @@
     private FlashlightController mFlashlightController;
     private PreviewInflater mPreviewInflater;
     private AccessibilityController mAccessibilityController;
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     private KeyguardAffordanceHelper mAffordanceHelper;
     private FalsingManager mFalsingManager;
     private boolean mUserSetupComplete;
@@ -274,7 +273,7 @@
     };
 
     public void initFrom(KeyguardBottomAreaView oldBottomArea) {
-        setStatusBar(oldBottomArea.mStatusBar);
+        setCentralSurfaces(oldBottomArea.mCentralSurfaces);
 
         // if it exists, continue to use the original ambient indication container
         // instead of the newly inflated one
@@ -473,8 +472,8 @@
         mRightAffordanceView.setContentDescription(state.contentDescription);
     }
 
-    public void setStatusBar(StatusBar statusBar) {
-        mStatusBar = statusBar;
+    public void setCentralSurfaces(CentralSurfaces centralSurfaces) {
+        mCentralSurfaces = centralSurfaces;
         updateCameraVisibility(); // in case onFinishInflate() was called too early
     }
 
@@ -732,7 +731,7 @@
         } else {
             boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
                     && Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
-            mStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
+            mCentralSurfaces.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
                     dismissShade, false /* afterKeyguardGone */, true /* deferred */);
         }
     }
@@ -1019,7 +1018,8 @@
 
         @Override
         public IconState getIcon() {
-            boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
+            boolean isCameraDisabled = (mCentralSurfaces != null)
+                    && !mCentralSurfaces.isCameraAllowedByAdmin();
             mIconState.isVisible = !isCameraDisabled
                     && mShowCameraAffordance
                     && mUserSetupComplete
@@ -1108,8 +1108,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/KeyguardEnvironmentImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
index 9bdefcd..2c4fc6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
@@ -14,8 +14,8 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
-import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.MULTIUSER_DEBUG;
 
 import android.service.notification.StatusBarNotification;
 import android.util.Log;
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 a0f8d05..cc8a703 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -120,14 +120,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 +170,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;
@@ -184,11 +177,12 @@
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.notification.stack.MediaContainerView;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.phone.panelstate.PanelState;
@@ -208,7 +202,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;
@@ -221,9 +214,8 @@
 import javax.inject.Inject;
 import javax.inject.Provider;
 
-@StatusBarComponent.StatusBarScope
-public class NotificationPanelViewController extends PanelViewController
-        implements NotifPanelEventSource {
+@CentralSurfacesComponent.CentralSurfacesScope
+public class NotificationPanelViewController extends PanelViewController {
 
     private static final boolean DEBUG = false;
 
@@ -308,13 +300,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;
@@ -334,6 +323,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;
@@ -349,8 +339,6 @@
     @VisibleForTesting QS mQs;
     private FrameLayout mQsFrame;
     private QsFrameTranslateController mQsFrameTranslateController;
-    @Nullable
-    private CommunalHostViewController mCommunalViewController;
     private KeyguardStatusViewController mKeyguardStatusViewController;
     private LockIconViewController mLockIconViewController;
     private NotificationsQuickSettingsContainer mNotificationContainerParent;
@@ -363,8 +351,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.
@@ -372,6 +358,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;
@@ -412,16 +404,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;
@@ -522,10 +512,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;
@@ -663,7 +649,7 @@
     private Optional<NotificationPanelUnfoldAnimationController>
             mNotificationPanelUnfoldAnimationController;
 
-    private final ListenerSet<Callbacks> mNotifEventSourceCallbacks = new ListenerSet<>();
+    private final NotificationListContainer mNotificationListContainer;
 
     private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
         @Override
@@ -685,32 +671,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() {
@@ -736,7 +696,6 @@
             FalsingCollector falsingCollector,
             NotificationLockscreenUserManager notificationLockscreenUserManager,
             NotificationEntryManager notificationEntryManager,
-            CommunalStateController communalStateController,
             KeyguardStateController keyguardStateController,
             StatusBarStateController statusBarStateController,
             StatusBarWindowStateController statusBarWindowStateController,
@@ -746,7 +705,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,
@@ -760,7 +719,6 @@
             KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
             KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
             KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
-            CommunalViewComponent.Factory communalViewComponentFactory,
             LockscreenShadeTransitionController lockscreenShadeTransitionController,
             NotificationGroupManagerLegacy groupManager,
             NotificationIconAreaController notificationIconAreaController,
@@ -792,7 +750,9 @@
             InteractionJankMonitor interactionJankMonitor,
             QsFrameTranslateController qsFrameTranslateController,
             SysUiState sysUiState,
-            KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
+            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
+            NotificationListContainer notificationListContainer,
+            PanelEventsEmitter panelEventsEmitter) {
         super(view,
                 falsingManager,
                 dozeLog,
@@ -823,12 +783,11 @@
         mMediaHierarchyManager = mediaHierarchyManager;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mNotificationsQSContainerController = notificationsQSContainerController;
+        mNotificationListContainer = notificationListContainer;
         mNotificationsQSContainerController.init();
         mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
         mGroupManager = groupManager;
         mNotificationIconAreaController = notificationIconAreaController;
-        mCommunalStateController = communalStateController;
-        mCommunalViewComponentFactory = communalViewComponentFactory;
         mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
         mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
         mDepthController = notificationShadeDepthController;
@@ -863,6 +822,7 @@
         mSecureSettings = secureSettings;
         mInteractionJankMonitor = interactionJankMonitor;
         mSysUiState = sysUiState;
+        mPanelEventsEmitter = panelEventsEmitter;
         pulseExpansionHandler.setPulseExpandAbortListener(() -> {
             if (mQs != null) {
                 mQs.animateHeaderSlidingOut();
@@ -872,7 +832,6 @@
         mThemeResId = mView.getContext().getThemeResId();
         mKeyguardBypassController = bypassController;
         mUpdateMonitor = keyguardUpdateMonitor;
-        mCommunalSourceMonitor = communalSourceMonitor;
         mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
         lockscreenShadeTransitionController.setNotificationPanelController(this);
         DynamicPrivacyControlListener
@@ -919,9 +878,6 @@
         mNotificationPanelUnfoldAnimationController = unfoldComponent.map(
                 SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController);
 
-        mCommunalSourceMonitorCallback = (source) -> {
-            mUiExecutor.execute(() -> setCommunalSource(source));
-        };
         mQsFrameTranslateController = qsFrameTranslateController;
         updateUserSwitcherFlags();
         onFinishInflate();
@@ -957,7 +913,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;
@@ -979,20 +934,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);
@@ -1083,8 +1029,7 @@
 
     private void updateViewControllers(KeyguardStatusView keyguardStatusView,
             FrameLayout userAvatarView,
-            KeyguardUserSwitcherView keyguardUserSwitcherView,
-            CommunalHostView communalView) {
+            KeyguardUserSwitcherView keyguardUserSwitcherView) {
         // Re-associate the KeyguardStatusViewController
         KeyguardStatusViewComponent statusViewComponent =
                 mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
@@ -1127,10 +1072,10 @@
         return mKeyguardStatusViewController.hasCustomClock();
     }
 
-    private void setStatusBar(StatusBar bar) {
+    private void setCentralSurfaces(CentralSurfaces centralSurfaces) {
         // TODO: this can be injected.
-        mStatusBar = bar;
-        mKeyguardBottomArea.setStatusBar(mStatusBar);
+        mCentralSurfaces = centralSurfaces;
+        mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces);
     }
 
     public void updateResources() {
@@ -1139,10 +1084,16 @@
         mSplitShadeNotificationsScrimMarginBottom =
                 mResources.getDimensionPixelSize(
                         R.dimen.split_shade_notifications_scrim_margin_bottom);
-        int qsWidth = mResources.getDimensionPixelSize(R.dimen.qs_panel_width);
-        int panelWidth = mResources.getDimensionPixelSize(R.dimen.notification_panel_width);
-        mShouldUseSplitNotificationShade =
+
+        int panelMarginHorizontal = mResources.getDimensionPixelSize(
+                R.dimen.notification_panel_margin_horizontal);
+
+        final boolean newShouldUseSplitNotificationShade =
                 Utils.shouldUseSplitNotificationShade(mResources);
+        final boolean splitNotificationShadeChanged =
+                mShouldUseSplitNotificationShade != newShouldUseSplitNotificationShade;
+
+        mShouldUseSplitNotificationShade = newShouldUseSplitNotificationShade;
         if (mQs != null) {
             mQs.setInSplitShade(mShouldUseSplitNotificationShade);
         }
@@ -1157,11 +1108,12 @@
         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
-            qsWidth = 0;
-            panelWidth = 0;
             constraintSet.connect(R.id.qs_frame, END, R.id.qs_edge_guideline, END);
             constraintSet.connect(
                     R.id.notification_stack_scroller, START,
@@ -1174,11 +1126,15 @@
                 constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT);
             }
         }
-        constraintSet.getConstraint(R.id.notification_stack_scroller).layout.mWidth = panelWidth;
-        constraintSet.getConstraint(R.id.qs_frame).layout.mWidth = qsWidth;
+        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);
@@ -1188,6 +1144,10 @@
         updateKeyguardStatusViewAlignment(/* animate= */false);
 
         mKeyguardMediaController.refreshMediaPosition();
+
+        if (splitNotificationShadeChanged) {
+            updateClockAppearance();
+        }
     }
 
     private static void ensureAllViewsHaveIds(ViewGroup parentView) {
@@ -1262,7 +1222,7 @@
                         showKeyguardUserSwitcher /* enabled */);
 
         updateViewControllers(mView.findViewById(R.id.keyguard_status_view), userAvatarView,
-                keyguardUserSwitcherView, mCommunalView);
+                keyguardUserSwitcherView);
 
         // Update keyguard bottom area
         int index = mView.indexOfChild(mKeyguardBottomArea);
@@ -1311,7 +1271,7 @@
         mAffordanceHelper = new KeyguardAffordanceHelper(
                 mKeyguardAffordanceHelperCallback, mView.getContext(), mFalsingManager);
         mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
-        mKeyguardBottomArea.setStatusBar(mStatusBar);
+        mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces);
         mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
         mKeyguardBottomArea.setFalsingManager(mFalsingManager);
         mKeyguardBottomArea.initWallet(mQuickAccessWalletController);
@@ -1408,10 +1368,6 @@
         int stackScrollerPadding;
         boolean onKeyguard = isOnKeyguard();
 
-        if (onKeyguard) {
-            updateCommunalViewAppearance();
-        }
-
         if (onKeyguard || forceClockUpdate) {
             updateClockAppearance();
         }
@@ -1437,22 +1393,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();
@@ -1527,9 +1467,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();
@@ -1538,6 +1477,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);
@@ -1559,11 +1503,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));
@@ -1574,7 +1513,7 @@
 
         float lockIconPadding = 0;
         if (mLockIconViewController.getTop() != 0) {
-            lockIconPadding = mStatusBar.getDisplayHeight() - mLockIconViewController.getTop()
+            lockIconPadding = mCentralSurfaces.getDisplayHeight() - mLockIconViewController.getTop()
                 + mResources.getDimensionPixelSize(R.dimen.min_lock_icon_padding);
         }
 
@@ -1687,12 +1626,6 @@
         return true;
     }
 
-    private void updateCommunal() {
-        if (mCommunalViewController != null) {
-            mCommunalViewController.setAlpha(mKeyguardOnlyContentAlpha);
-        }
-    }
-
     private void updateClock() {
         float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
         mKeyguardStatusViewController.setAlpha(alpha);
@@ -1728,7 +1661,7 @@
             mAffordanceHelper.reset(false);
             mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
         }
-        mStatusBar.getGutsManager().closeAndSaveGuts(true /* leavebehind */, true /* force */,
+        mCentralSurfaces.getGutsManager().closeAndSaveGuts(true /* leavebehind */, true /* force */,
                 true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
         if (animate && !isFullyCollapsed()) {
             animateCloseQs(true /* animateAway */);
@@ -1766,11 +1699,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);
@@ -1807,7 +1745,7 @@
     public void expandWithQs() {
         if (isQsExpansionEnabled()) {
             mQsExpandImmediate = true;
-            mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
+            setShowShelfOnly(true);
         }
         if (isFullyCollapsed()) {
             expand(true /* animate */);
@@ -1827,7 +1765,7 @@
 
     @Override
     public void fling(float vel, boolean expand) {
-        GestureRecorder gr = mStatusBar.getGestureRecorder();
+        GestureRecorder gr = mCentralSurfaces.getGestureRecorder();
         if (gr != null) {
             gr.tag("fling " + ((vel > 0) ? "open" : "closed"), "notifications,v=" + vel);
         }
@@ -1840,14 +1778,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) {
@@ -2006,7 +1944,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) {
@@ -2016,8 +1962,8 @@
                 mBarState == KEYGUARD ? MetricsEvent.ACTION_LS_QS
                         : MetricsEvent.ACTION_SHADE_QS_PULL;
         mLockscreenGestureLogger.write(gesture,
-                (int) ((y - mInitialTouchY) / mStatusBar.getDisplayDensity()),
-                (int) (vel / mStatusBar.getDisplayDensity()));
+                (int) ((y - mInitialTouchY) / mCentralSurfaces.getDisplayDensity()),
+                (int) (vel / mCentralSurfaces.getDisplayDensity()));
     }
 
     private boolean flingExpandsQs(float vel) {
@@ -2071,8 +2017,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 */);
@@ -2087,7 +2035,7 @@
         }
         if (!mQsExpandImmediate && mQsTracking) {
             onQsTouch(event);
-            if (!mConflictingQsExpansionGesture) {
+            if (!mConflictingQsExpansionGesture && !mShouldUseSplitNotificationShade) {
                 return true;
             }
         }
@@ -2101,7 +2049,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
@@ -2172,6 +2120,9 @@
         if (!isFullyCollapsed()) {
             return;
         }
+        if (mShouldUseSplitNotificationShade) {
+            mQsExpandImmediate = true;
+        }
         mExpectingSynthesizedDown = true;
         onTrackingStarted();
         updatePanelExpanded();
@@ -2295,7 +2246,7 @@
     }
 
     private int getFalsingThreshold() {
-        float factor = mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+        float factor = mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
         return (int) (mQsFalsingThreshold * factor);
     }
 
@@ -2322,7 +2273,7 @@
         // When expanding QS, let's authenticate the user if possible,
         // this will speed up notification actions.
         if (height == 0) {
-            mStatusBar.requestFaceAuth(false);
+            mCentralSurfaces.requestFaceAuth(false);
         }
     }
 
@@ -2333,7 +2284,7 @@
             updateQsState();
             requestPanelHeightUpdate();
             mFalsingCollector.setQsExpanded(expanded);
-            mStatusBar.setQsExpanded(expanded);
+            mCentralSurfaces.setQsExpanded(expanded);
             mNotificationsQSContainerController.setQsExpanded(expanded);
             mPulseExpansionHandler.setQsExpanded(expanded);
             mKeyguardBypassController.setQSExpanded(expanded);
@@ -2378,12 +2329,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) {
@@ -2417,7 +2366,7 @@
 
         if (!mFalsingManager.isUnlockingDisabled() && mQsFullyExpanded
                 && mFalsingCollector.shouldEnforceBouncer()) {
-            mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
+            mCentralSurfaces.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
                     false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */);
         }
         if (DEBUG) {
@@ -2428,7 +2377,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();
@@ -2463,10 +2412,6 @@
         mSplitShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
         mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
         mSplitShadeHeaderController.setShadeExpanded(mQsVisible);
-
-        if (mCommunalViewController != null) {
-            mCommunalViewController.updateQsExpansion(qsExpansionFraction);
-        }
     }
 
     private void onStackYChanged(boolean shouldAnimate) {
@@ -2829,10 +2774,6 @@
         }
         mTransitionToFullShadeQSPosition = position;
         updateQsExpansion();
-
-        if (mCommunalViewController != null) {
-            mCommunalViewController.updateShadeExpansion(mTransitioningToFullShadeProgress);
-        }
     }
 
     /**
@@ -2856,7 +2797,6 @@
             updateKeyguardBottomAreaAlpha();
         }
         updateClock();
-        updateCommunal();
     }
 
     private void trackMovement(MotionEvent event) {
@@ -3105,7 +3045,7 @@
         if (mPanelExpanded != isExpanded) {
             mHeadsUpManager.setIsPanelExpanded(isExpanded);
             mStatusBarTouchableRegionManager.setPanelExpanded(isExpanded);
-            mStatusBar.setPanelExpanded(isExpanded);
+            mCentralSurfaces.setPanelExpanded(isExpanded);
             mPanelExpanded = isExpanded;
 
             if (!isExpanded && mQs != null && mQs.isCustomizing()) {
@@ -3230,7 +3170,7 @@
         mKeyguardBottomArea.setImportantForAccessibility(
                 alpha == 0f ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
                         : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
-        View ambientIndicationContainer = mStatusBar.getAmbientIndicationContainer();
+        View ambientIndicationContainer = mCentralSurfaces.getAmbientIndicationContainer();
         if (ambientIndicationContainer != null) {
             ambientIndicationContainer.setAlpha(alpha);
         }
@@ -3285,7 +3225,7 @@
             setListening(true);
         }
         mQsExpandImmediate = false;
-        mNotificationStackScrollLayoutController.setShouldShowShelfOnly(false);
+        setShowShelfOnly(false);
         mTwoFingerQsExpandPossible = false;
         updateTrackingHeadsUp(null);
         mExpandingFromHeadsUp = false;
@@ -3341,9 +3281,7 @@
         mScrimController.onTrackingStarted();
         if (mQsFullyExpanded) {
             mQsExpandImmediate = true;
-            if (!mShouldUseSplitNotificationShade) {
-                mNotificationStackScrollLayoutController.setShouldShowShelfOnly(true);
-            }
+            setShowShelfOnly(true);
         }
         if (mBarState == KEYGUARD || mBarState == StatusBarState.SHADE_LOCKED) {
             mAffordanceHelper.animateHideLeftRightIcon();
@@ -3446,9 +3384,7 @@
         boolean wasRunning = isLaunchTransitionRunning();
         super.setIsLaunchAnimationRunning(running);
         if (wasRunning != isLaunchTransitionRunning()) {
-            for (Callbacks cb : mNotifEventSourceCallbacks) {
-                cb.onLaunchingActivityChanged(running);
-            }
+            mPanelEventsEmitter.notifyLaunchingActivityChanged(running);
         }
     }
 
@@ -3457,9 +3393,7 @@
         boolean wasClosing = isClosing();
         super.setIsClosing(isClosing);
         if (wasClosing != isClosing) {
-            for (Callbacks cb : mNotifEventSourceCallbacks) {
-                cb.onPanelCollapsingChanged(isClosing);
-            }
+            mPanelEventsEmitter.notifyPanelCollapsingChanged(isClosing);
         }
     }
 
@@ -3569,7 +3503,7 @@
 
     @Override
     protected void onClosingFinished() {
-        mStatusBar.onClosingFinished();
+        mCentralSurfaces.onClosingFinished();
         setClosingWithAlphaFadeout(false);
         mMediaHierarchyManager.closeGuts();
     }
@@ -3631,7 +3565,7 @@
     }
 
     public void clearNotificationEffects() {
-        mStatusBar.clearNotificationEffects();
+        mCentralSurfaces.clearNotificationEffects();
     }
 
     @Override
@@ -3693,7 +3627,7 @@
      * Whether the camera application can be launched for the camera launch gesture.
      */
     public boolean canCameraGestureBeLaunched() {
-        if (!mStatusBar.isCameraAllowedByAdmin()) {
+        if (!mCentralSurfaces.isCameraAllowedByAdmin()) {
             return false;
         }
 
@@ -4037,8 +3971,7 @@
     }
 
     public boolean hasPulsingNotifications() {
-        return mNotificationStackScrollLayoutController
-                .getNotificationListContainer().hasPulsingNotifications();
+        return mNotificationListContainer.hasPulsingNotifications();
     }
 
     public ActivatableNotificationView getActivatedChild() {
@@ -4053,10 +3986,6 @@
         mNotificationStackScrollLayoutController.runAfterAnimationFinished(r);
     }
 
-    public void setScrollingEnabled(boolean b) {
-        mNotificationStackScrollLayoutController.setScrollingEnabled(b);
-    }
-
     private Runnable mHideExpandedRunnable;
     private final Runnable mMaybeHideExpandedRunnable = new Runnable() {
         @Override
@@ -4073,10 +4002,10 @@
      * @param hideExpandedRunnable a runnable to run when we need to hide the expanded panel.
      */
     public void initDependencies(
-            StatusBar statusBar,
+            CentralSurfaces centralSurfaces,
             Runnable hideExpandedRunnable,
             NotificationShelfController notificationShelfController) {
-        setStatusBar(statusBar);
+        setCentralSurfaces(centralSurfaces);
         mHideExpandedRunnable = hideExpandedRunnable;
         mNotificationStackScrollLayoutController.setShelfController(notificationShelfController);
         mNotificationShelfController = notificationShelfController;
@@ -4149,7 +4078,7 @@
                 initDownStates(event);
                 // Do not let touches go to shade or QS if the bouncer is visible,
                 // but still let user swipe down to expand the panel, dismissing the bouncer.
-                if (mStatusBar.isBouncerShowing()) {
+                if (mCentralSurfaces.isBouncerShowing()) {
                     return true;
                 }
                 if (mCommandQueue.panelsEnabled()
@@ -4192,8 +4121,8 @@
 
                 // Do not allow panel expansion if bouncer is scrimmed or showing over a dream,
                 // otherwise user would be able to pull down QS or expand the shade.
-                if (mStatusBar.isBouncerShowingScrimmed()
-                        || mStatusBar.isBouncerShowingOverDream()) {
+                if (mCentralSurfaces.isBouncerShowingScrimmed()
+                        || mCentralSurfaces.isBouncerShowingOverDream()) {
                     return false;
                 }
 
@@ -4257,15 +4186,15 @@
             new PhoneStatusBarView.TouchEventHandler() {
                 @Override
                 public void onInterceptTouchEvent(MotionEvent event) {
-                    mStatusBar.onTouchEvent(event);
+                    mCentralSurfaces.onTouchEvent(event);
                 }
 
                 @Override
                 public boolean handleTouchEvent(MotionEvent event) {
-                    mStatusBar.onTouchEvent(event);
+                    mCentralSurfaces.onTouchEvent(event);
 
                     // TODO(b/202981994): Move the touch debugging in this method to a central
-                    //  location. (Right now, it's split between StatusBar and here.)
+                    //  location. (Right now, it's split between CentralSurfaces and here.)
 
                     // If panels aren't enabled, ignore the gesture and don't pass it down to the
                     // panel view.
@@ -4362,16 +4291,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) {
@@ -4482,7 +4401,7 @@
                             : !rightPage;
             mIsLaunchTransitionRunning = true;
             mLaunchAnimationEndRunnable = null;
-            float displayDensity = mStatusBar.getDisplayDensity();
+            float displayDensity = mCentralSurfaces.getDisplayDensity();
             int lengthDp = Math.abs((int) (translation / displayDensity));
             int velocityDp = Math.abs((int) (vel / displayDensity));
             if (start) {
@@ -4490,7 +4409,7 @@
                 mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_DIALER);
                 mFalsingCollector.onLeftAffordanceOn();
                 if (mFalsingCollector.shouldEnforceBouncer()) {
-                    mStatusBar.executeRunnableDismissingKeyguard(
+                    mCentralSurfaces.executeRunnableDismissingKeyguard(
                             () -> mKeyguardBottomArea.launchLeftAffordance(), null,
                             true /* dismissShade */, false /* afterKeyguardGone */,
                             true /* deferred */);
@@ -4506,7 +4425,7 @@
                 }
                 mFalsingCollector.onCameraOn();
                 if (mFalsingCollector.shouldEnforceBouncer()) {
-                    mStatusBar.executeRunnableDismissingKeyguard(
+                    mCentralSurfaces.executeRunnableDismissingKeyguard(
                             () -> mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource), null,
                             true /* dismissShade */, false /* afterKeyguardGone */,
                             true /* deferred */);
@@ -4514,7 +4433,7 @@
                     mKeyguardBottomArea.launchCamera(mLastCameraLaunchSource);
                 }
             }
-            mStatusBar.startLaunchTransitionTimeout();
+            mCentralSurfaces.startLaunchTransitionTimeout();
             mBlockTouches = true;
         }
 
@@ -4526,7 +4445,7 @@
                 mLaunchAnimationEndRunnable.run();
                 mLaunchAnimationEndRunnable = null;
             }
-            mStatusBar.readyForKeyguardDone();
+            mCentralSurfaces.readyForKeyguardDone();
         }
 
         @Override
@@ -4563,18 +4482,18 @@
             mHintAnimationRunning = true;
             mAffordanceHelper.startHintAnimation(rightIcon, () -> {
                 mHintAnimationRunning = false;
-                mStatusBar.onHintFinished();
+                mCentralSurfaces.onHintFinished();
             });
             rightIcon =
                     mView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? !rightIcon
                             : rightIcon;
             if (rightIcon) {
-                mStatusBar.onCameraHintStarted();
+                mCentralSurfaces.onCameraHintStarted();
             } else {
                 if (mKeyguardBottomArea.isLeftVoiceAssist()) {
-                    mStatusBar.onVoiceAssistHintStarted();
+                    mCentralSurfaces.onVoiceAssistHintStarted();
                 } else {
-                    mStatusBar.onPhoneHintStarted();
+                    mCentralSurfaces.onPhoneHintStarted();
                 }
             }
         }
@@ -4605,7 +4524,7 @@
 
         @Override
         public float getAffordanceFalsingFactor() {
-            return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+            return mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
         }
 
         @Override
@@ -4751,14 +4670,6 @@
                     goingToFullShade,
                     mBarState);
 
-            if (mCommunalViewController != null) {
-                mCommunalViewController.setKeyguardStatusViewVisibility(
-                        statusBarState,
-                        keyguardFadingAway,
-                        goingToFullShade,
-                        mBarState);
-            }
-
             setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);
 
             mBarState = statusBarState;
@@ -4886,25 +4797,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.
      */
@@ -4922,7 +4814,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
@@ -4930,7 +4821,6 @@
             mFalsingManager.addTapListener(mFalsingTapListener);
             mKeyguardIndicationController.init();
             registerSettingsChangeListener();
-            mCommunalStateController.addCallback(mCommunalStateCallback);
         }
 
         @Override
@@ -4940,9 +4830,7 @@
                             .removeTagListener(QS.TAG, mFragmentListener);
             mStatusBarStateController.removeCallback(mStatusBarStateListener);
             mConfigurationController.removeCallback(mConfigurationListener);
-            mCommunalSourceMonitor.removeCallback(mCommunalSourceMonitorCallback);
             mFalsingManager.removeTapListener(mFalsingTapListener);
-            mCommunalStateController.removeCallback(mCommunalStateCallback);
         }
     }
 
@@ -5008,7 +4896,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;
         }
@@ -5121,7 +5013,7 @@
             mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
         }
         if (state == STATE_OPENING) {
-            mStatusBar.makeExpandedVisible(false);
+            mCentralSurfaces.makeExpandedVisible(false);
         }
         if (state == STATE_CLOSED) {
             // Close the status bar in the next frame so we can show the end of the
@@ -5145,4 +5037,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 9f9e7d9..0ff010a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -26,6 +26,7 @@
 import android.app.IActivityManager;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.graphics.PixelFormat;
 import android.graphics.Region;
 import android.os.Binder;
@@ -117,6 +118,7 @@
      * @see #batchApplyWindowLayoutParams(Runnable)
      */
     private int mDeferWindowLayoutParams;
+    private boolean mLastKeyguardRotationAllowed;
 
     @Inject
     public NotificationShadeWindowControllerImpl(Context context, WindowManager windowManager,
@@ -143,7 +145,7 @@
         mScreenOffAnimationController = screenOffAnimationController;
         dumpManager.registerDumpable(getClass().getName(), this);
         mAuthController = authController;
-
+        mLastKeyguardRotationAllowed = mKeyguardStateController.isKeyguardScreenRotationAllowed();
         mLockScreenDisplayTimeout = context.getResources()
                 .getInteger(R.integer.config_lockScreenDisplayTimeout);
         ((SysuiStatusBarStateController) statusBarStateController)
@@ -779,6 +781,17 @@
         setKeyguardDark(useDarkText);
     }
 
+    @Override
+    public void onConfigChanged(Configuration newConfig) {
+        final boolean newScreenRotationAllowed = mKeyguardStateController
+                .isKeyguardScreenRotationAllowed();
+
+        if (mLastKeyguardRotationAllowed != newScreenRotationAllowed) {
+            apply(mCurrentState);
+            mLastKeyguardRotationAllowed = newScreenRotationAllowed;
+        }
+    }
+
     /**
      * When keyguard will be dismissed but didn't start animation yet.
      */
@@ -827,7 +840,7 @@
         Set<String> mComponentsForcingTopUi = new HashSet<>();
 
         /**
-         * The {@link StatusBar} state from the status bar.
+         * The status bar state from {@link CentralSurfaces}.
          */
         int mStatusBarState;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
index fb0e306..1e3a02b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowView.java
@@ -58,7 +58,7 @@
  */
 public class NotificationShadeWindowView extends FrameLayout {
     public static final String TAG = "NotificationShadeWindowView";
-    public static final boolean DEBUG = StatusBar.DEBUG;
+    public static final boolean DEBUG = CentralSurfaces.DEBUG;
 
     private int mRightInset = 0;
     private int mLeftInset = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index 396703b..101c86f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -44,6 +44,7 @@
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.window.StatusBarWindowStateController;
 import com.android.systemui.tuner.TunerService;
@@ -57,6 +58,7 @@
 /**
  * Controller for {@link NotificationShadeWindowView}.
  */
+@CentralSurfacesComponent.CentralSurfacesScope
 public class NotificationShadeWindowViewController {
     private static final String TAG = "NotifShadeWindowVC";
     private final FalsingCollector mFalsingCollector;
@@ -77,8 +79,8 @@
     private boolean mExpandAnimationRunning;
     private NotificationStackScrollLayout mStackScrollLayout;
     private PhoneStatusBarViewController mStatusBarViewController;
-    private StatusBar mService;
-    private NotificationShadeWindowController mNotificationShadeWindowController;
+    private final CentralSurfaces mService;
+    private final NotificationShadeWindowController mNotificationShadeWindowController;
     private DragDownHelper mDragDownHelper;
     private boolean mDoubleTapEnabled;
     private boolean mSingleTapEnabled;
@@ -105,7 +107,9 @@
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             StatusBarWindowStateController statusBarWindowStateController,
             LockIconViewController lockIconViewController,
-            Optional<LowLightClockController> lowLightClockController) {
+            Optional<LowLightClockController> lowLightClockController,
+            CentralSurfaces centralSurfaces,
+            NotificationShadeWindowController controller) {
         mLockscreenShadeTransitionController = transitionController;
         mFalsingCollector = falsingCollector;
         mTunerService = tunerService;
@@ -120,6 +124,8 @@
         mStatusBarWindowStateController = statusBarWindowStateController;
         mLockIconViewController = lockIconViewController;
         mLowLightClockController = lowLightClockController;
+        mService = centralSurfaces;
+        mNotificationShadeWindowController = controller;
 
         // This view is not part of the newly inflated expanded status bar.
         mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -452,11 +458,6 @@
         mStatusBarViewController = statusBarViewController;
     }
 
-    public void setService(StatusBar statusBar, NotificationShadeWindowController controller) {
-        mService = statusBar;
-        mNotificationShadeWindowController = controller;
-    }
-
     /**
      * Tell the controller that dozing has begun or ended.
      * @param dozing True if dozing has begun.
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..ebb09b1 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,7 @@
 package com.android.systemui.statusbar.phone
 
 import android.view.WindowInsets
+import com.android.systemui.R
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.navigationbar.NavigationModeController
@@ -41,6 +42,7 @@
     private var isQSCustomizerAnimating = false
 
     private var notificationsBottomMargin = 0
+    private var scrimShadeBottomMargin = 0
     private var bottomStableInsets = 0
     private var bottomCutoutInsets = 0
 
@@ -67,17 +69,36 @@
 
     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)
     }
 
+    private fun updateResources() {
+        val previousScrimShadeBottomMargin = scrimShadeBottomMargin
+        scrimShadeBottomMargin = resources.getDimensionPixelSize(
+            R.dimen.split_shade_notifications_scrim_margin_bottom
+        )
+
+        if (previousScrimShadeBottomMargin != scrimShadeBottomMargin) {
+            updateBottomSpacing()
+        }
+    }
+
+    /**
+     * Update the notification bottom margin.
+     *
+     * Will not call updateBottomSpacing
+     */
     fun updateMargins() {
         notificationsBottomMargin = mView.defaultNotificationsMarginBottom
     }
@@ -111,7 +132,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)
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..c2b5f56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -18,11 +18,13 @@
 
 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 com.android.systemui.R;
@@ -54,6 +56,9 @@
     private View mQSScrollView;
     private View mQSContainer;
 
+    @Nullable
+    private Consumer<Configuration> mConfigurationChangedListener;
+
     public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -79,6 +84,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;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 249f988..45dc943 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -27,7 +27,7 @@
     public static final String TAG = PanelView.class.getSimpleName();
     private PanelViewController.TouchHandler mTouchHandler;
 
-    protected StatusBar mStatusBar;
+    protected CentralSurfaces mCentralSurfaces;
     protected HeadsUpManagerPhone mHeadsUpManager;
 
     protected KeyguardBottomAreaView mKeyguardBottomArea;
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 85e8042..1d560c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -113,7 +113,7 @@
         Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
     }
 
-    protected StatusBar mStatusBar;
+    protected CentralSurfaces mCentralSurfaces;
     protected HeadsUpManagerPhone mHeadsUpManager;
     protected final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
 
@@ -349,9 +349,9 @@
         //TODO: keyguard opens QS a different way; log that too?
 
         // Log the position of the swipe that opened the panel
-        float width = mStatusBar.getDisplayWidth();
-        float height = mStatusBar.getDisplayHeight();
-        int rot = mStatusBar.getRotation();
+        float width = mCentralSurfaces.getDisplayWidth();
+        float height = mCentralSurfaces.getDisplayHeight();
+        int rot = mCentralSurfaces.getRotation();
 
         mLockscreenGestureLogger.writeAtFractionalPosition(MetricsEvent.ACTION_PANEL_VIEW_EXPAND,
                 (int) (event.getX() / width * 100), (int) (event.getY() / height * 100), rot);
@@ -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) {
@@ -433,10 +434,11 @@
             }
 
             mDozeLog.traceFling(expand, mTouchAboveFalsingThreshold,
-                    mStatusBar.isFalsingThresholdNeeded(), mStatusBar.isWakeUpComingFromTouch());
+                    mCentralSurfaces.isFalsingThresholdNeeded(),
+                    mCentralSurfaces.isWakeUpComingFromTouch());
             // Log collapse gesture if on lock screen.
             if (!expand && onKeyguard) {
-                float displayDensity = mStatusBar.getDisplayDensity();
+                float displayDensity = mCentralSurfaces.getDisplayDensity();
                 int heightDp = (int) Math.abs((y - mInitialTouchY) / displayDensity);
                 int velocityDp = (int) Math.abs(vel / displayDensity);
                 mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_UNLOCK, heightDp, velocityDp);
@@ -453,13 +455,12 @@
             if (mUpdateFlingOnLayout) {
                 mUpdateFlingVelocity = vel;
             }
-        } else if (!mStatusBar.isBouncerShowing()
+        } else if (!mCentralSurfaces.isBouncerShowing()
                 && !mStatusBarKeyguardViewManager.isShowingAlternateAuthOrAnimating()
                 && !mKeyguardStateController.isKeyguardGoingAway()) {
             boolean expands = onEmptySpaceClick(mInitialTouchX);
             onTrackingStopped(expands);
         }
-        mAmbientState.setSwipingUp(false);
         mVelocityTracker.clear();
     }
 
@@ -469,7 +470,7 @@
     }
 
     private int getFalsingThreshold() {
-        float factor = mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+        float factor = mCentralSurfaces.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
         return (int) (mUnlockFalsingThreshold * factor);
     }
 
@@ -479,14 +480,14 @@
 
     protected void onTrackingStopped(boolean expand) {
         mTracking = false;
-        mStatusBar.onTrackingStopped(expand);
+        mCentralSurfaces.onTrackingStopped(expand);
         updatePanelExpansionAndVisibility();
     }
 
     protected void onTrackingStarted() {
         endClosing();
         mTracking = true;
-        mStatusBar.onTrackingStarted();
+        mCentralSurfaces.onTrackingStarted();
         notifyExpandingStarted();
         updatePanelExpansionAndVisibility();
     }
@@ -556,7 +557,7 @@
      */
     private boolean isFalseTouch(float x, float y,
             @Classifier.InteractionType int interactionType) {
-        if (!mStatusBar.isFalsingThresholdNeeded()) {
+        if (!mCentralSurfaces.isFalsingThresholdNeeded()) {
             return false;
         }
         if (mFalsingManager.isClassifierEnabled()) {
@@ -921,7 +922,7 @@
                             mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                             return;
                         }
-                        if (mStatusBar.getNotificationShadeWindowView().isVisibleToUser()) {
+                        if (mCentralSurfaces.getNotificationShadeWindowView().isVisibleToUser()) {
                             mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                             if (mAnimateAfterExpanding) {
                                 notifyExpandingStarted();
@@ -976,11 +977,11 @@
     }
 
     protected void onUnlockHintFinished() {
-        mStatusBar.onHintFinished();
+        mCentralSurfaces.onHintFinished();
     }
 
     protected void onUnlockHintStarted() {
-        mStatusBar.onUnlockHintStarted();
+        mCentralSurfaces.onUnlockHintStarted();
     }
 
     public boolean isUnlockHintRunning() {
@@ -1018,7 +1019,7 @@
 
         View[] viewsToAnimate = {
                 mKeyguardBottomArea.getIndicationArea(),
-                mStatusBar.getAmbientIndicationContainer()};
+                mCentralSurfaces.getAmbientIndicationContainer()};
         for (View v : viewsToAnimate) {
             if (v == null) {
                 continue;
@@ -1210,7 +1211,7 @@
 
             switch (event.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN:
-                    mStatusBar.userActivity();
+                    mCentralSurfaces.userActivity();
                     mAnimatingOnDown = mHeightAnimator != null && !mIsSpringBackAnimation;
                     mMinExpandHeight = 0.0f;
                     mDownTime = SystemClock.uptimeMillis();
@@ -1340,7 +1341,7 @@
                         onTrackingStarted();
                     }
                     if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()
-                            && !mStatusBar.isBouncerShowing()) {
+                            && !mCentralSurfaces.isBouncerShowing()) {
                         startOpening(event);
                     }
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index 224b2e4..9da2ef73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
 import com.android.systemui.util.ViewController
 import com.android.systemui.util.kotlin.getOrNull
+import com.android.systemui.util.view.ViewUtil
 
 import java.util.Optional
 
@@ -43,6 +44,7 @@
     @Named(UNFOLD_STATUS_BAR) private val progressProvider: ScopedUnfoldTransitionProgressProvider?,
     private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
     private val userSwitcherController: StatusBarUserSwitcherController,
+    private val viewUtil: ViewUtil,
     touchEventHandler: PhoneStatusBarView.TouchEventHandler,
     private val configurationController: ConfigurationController
 ) : ViewController<PhoneStatusBarView>(view) {
@@ -118,12 +120,7 @@
      * view's range and false otherwise.
      */
     fun touchIsWithinView(x: Float, y: Float): Boolean {
-        val left = mView.locationOnScreen[0]
-        val top = mView.locationOnScreen[1]
-        return left <= x &&
-                x <= left + mView.width &&
-                top <= y &&
-                y <= top + mView.height
+        return viewUtil.touchIsWithinView(mView, x, y)
     }
 
     class StatusBarViewsCenterProvider : UnfoldMoveFromCenterAnimator.ViewCenterProvider {
@@ -163,6 +160,7 @@
         @Named(UNFOLD_STATUS_BAR)
         private val progressProvider: Optional<ScopedUnfoldTransitionProgressProvider>,
         private val userSwitcherController: StatusBarUserSwitcherController,
+        private val viewUtil: ViewUtil,
         private val configurationController: ConfigurationController
     ) {
         fun create(
@@ -174,6 +172,7 @@
                 progressProvider.getOrNull(),
                 unfoldComponent.getOrNull()?.getStatusBarMoveFromCenterAnimationController(),
                 userSwitcherController,
+                viewUtil,
                 touchEventHandler,
                 configurationController
             )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt
index ea61a8b..c817466 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt
@@ -37,8 +37,8 @@
     private val animations: List<ScreenOffAnimation> =
         listOfNotNull(foldToAodAnimation, unlockedScreenOffAnimation)
 
-    fun initialize(statusBar: StatusBar, lightRevealScrim: LightRevealScrim) {
-        animations.forEach { it.initialize(statusBar, lightRevealScrim) }
+    fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {
+        animations.forEach { it.initialize(centralSurfaces, lightRevealScrim) }
         wakefulnessLifecycle.addObserver(this)
     }
 
@@ -131,7 +131,7 @@
         animations.any { it.isKeyguardHideDelayed() }
 
     /**
-     * Return true to make the StatusBar expanded so we can animate [LightRevealScrim]
+     * Return true to make the status bar expanded so we can animate [LightRevealScrim]
      */
     fun shouldShowLightRevealScrim(): Boolean =
         animations.any { it.shouldPlayAnimation() }
@@ -197,7 +197,7 @@
 }
 
 interface ScreenOffAnimation {
-    fun initialize(statusBar: StatusBar, lightRevealScrim: LightRevealScrim) {}
+    fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {}
 
     /**
      * Called when started going to sleep, should return true if the animation will be played
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 8d64041..419661b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -413,7 +413,7 @@
         }
 
         if (mKeyguardUpdateMonitor.needsSlowUnlockTransition() && mState == ScrimState.UNLOCKED) {
-            mAnimationDelay = StatusBar.FADE_KEYGUARD_START_DELAY;
+            mAnimationDelay = CentralSurfaces.FADE_KEYGUARD_START_DELAY;
             scheduleUpdate();
         } else if (((oldState == ScrimState.AOD || oldState == ScrimState.PULSING)  // leaving doze
                 && (!mDozeParameters.getAlwaysOn() || mState == ScrimState.UNLOCKED))
@@ -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();
             }
         }
@@ -1255,7 +1255,7 @@
 
     public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
         // TODO: remove this. This is necessary because of an order-of-operations limitation.
-        // The fix is to move more of these class into @StatusBarScope
+        // The fix is to move more of these class into @CentralSurfacesScope
         if (mScrimBehind == null) {
             mScrimBehindChangeRunnable = changeRunnable;
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index bfd625b..9028870 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -238,7 +238,7 @@
 
             mAnimationDuration = mKeyguardFadingAway
                     ? mKeyguardFadingAwayDuration
-                    : StatusBar.FADE_KEYGUARD_DURATION;
+                    : CentralSurfaces.FADE_KEYGUARD_DURATION;
 
             boolean fromAod = previousState == AOD || previousState == PULSING;
             mAnimateChange = !mLaunchingAffordanceWithPreview && !fromAod;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
index 24bb7f2..83ee125 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
@@ -18,9 +18,9 @@
 
 /**
  * {@link ShadeController} is an abstraction of the work that used to be hard-coded in
- * {@link StatusBar}. The shade itself represents the concept of the status bar window state, and
- * can be in multiple states: dozing, locked, showing the bouncer, occluded, etc. All/some of these
- * are coordinated with {@link StatusBarKeyguardViewManager} via
+ * {@link CentralSurfaces}. The shade itself represents the concept of the status bar window state,
+ * and can be in multiple states: dozing, locked, showing the bouncer, occluded, etc. All/some of
+ * these are coordinated with {@link StatusBarKeyguardViewManager} via
  * {@link com.android.systemui.keyguard.KeyguardViewMediator} and others.
  */
 public interface ShadeController {
@@ -38,7 +38,7 @@
 
     /**
      * Collapse the shade animated, showing the bouncer when on {@link StatusBarState#KEYGUARD} or
-     * dismissing {@link StatusBar} when on {@link StatusBarState#SHADE}.
+     * dismissing {@link CentralSurfaces} when on {@link StatusBarState#SHADE}.
      */
     void animateCollapsePanels(int flags, boolean force);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
index 72237b1..cee8b33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeControllerImpl.java
@@ -27,7 +27,6 @@
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.wm.shell.bubbles.Bubbles;
 
 import java.util.ArrayList;
 import java.util.Optional;
@@ -48,9 +47,8 @@
     protected final NotificationShadeWindowController mNotificationShadeWindowController;
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     private final int mDisplayId;
-    protected final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
+    protected final Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
     private final Lazy<AssistManager> mAssistManagerLazy;
-    private final Optional<Bubbles> mBubblesOptional;
 
     private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
 
@@ -61,25 +59,23 @@
             NotificationShadeWindowController notificationShadeWindowController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             WindowManager windowManager,
-            Lazy<Optional<StatusBar>> statusBarOptionalLazy,
-            Lazy<AssistManager> assistManagerLazy,
-            Optional<Bubbles> bubblesOptional
+            Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
+            Lazy<AssistManager> assistManagerLazy
     ) {
         mCommandQueue = commandQueue;
         mStatusBarStateController = statusBarStateController;
         mNotificationShadeWindowController = notificationShadeWindowController;
         mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
         mDisplayId = windowManager.getDefaultDisplay().getDisplayId();
-        // TODO: Remove circular reference to StatusBar when possible.
-        mStatusBarOptionalLazy = statusBarOptionalLazy;
+        // TODO: Remove circular reference to CentralSurfaces when possible.
+        mCentralSurfacesOptionalLazy = centralSurfacesOptionalLazy;
         mAssistManagerLazy = assistManagerLazy;
-        mBubblesOptional = bubblesOptional;
     }
 
     @Override
     public void instantExpandNotificationsPanel() {
         // Make our window larger and the panel expanded.
-        getStatusBar().makeExpandedVisible(true /* force */);
+        getCentralSurfaces().makeExpandedVisible(true /* force */);
         getNotificationPanelViewController().expand(false /* animate */);
         mCommandQueue.recomputeDisableFlags(mDisplayId, false /* animate */);
     }
@@ -114,7 +110,7 @@
         }
         if (SPEW) {
             Log.d(TAG, "animateCollapse():"
-                    + " mExpandedVisible=" + getStatusBar().isExpandedVisible()
+                    + " mExpandedVisible=" + getCentralSurfaces().isExpandedVisible()
                     + " flags=" + flags);
         }
 
@@ -128,11 +124,9 @@
             // release focus immediately to kick off focus change transition
             mNotificationShadeWindowController.setNotificationShadeFocusable(false);
 
-            getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();
+            getCentralSurfaces().getNotificationShadeWindowViewController().cancelExpandHelper();
             getNotificationPanelViewController()
                     .collapsePanel(true /* animate */, delayed, speedUpFactor);
-        } else if (mBubblesOptional.isPresent()) {
-            mBubblesOptional.get().collapseStack();
         }
     }
 
@@ -142,7 +136,7 @@
         if (!getNotificationPanelViewController().isFullyCollapsed()) {
             mCommandQueue.animateCollapsePanels(
                     CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
-            getStatusBar().visibilityChanged(false);
+            getCentralSurfaces().visibilityChanged(false);
             mAssistManagerLazy.get().hideAssist();
         }
         return false;
@@ -161,7 +155,7 @@
                 new ViewTreeObserver.OnGlobalLayoutListener() {
                     @Override
                     public void onGlobalLayout() {
-                        if (getStatusBar().getNotificationShadeWindowView().isVisibleToUser()) {
+                        if (getCentralSurfaces().getNotificationShadeWindowView().isVisibleToUser()) {
                             getNotificationPanelViewController().removeOnGlobalLayoutListener(this);
                             getNotificationPanelViewController().getView().post(executable);
                         }
@@ -191,7 +185,7 @@
             // close the shade if it was open
             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
                     true /* force */, true /* delayed */);
-            getStatusBar().visibilityChanged(false);
+            getCentralSurfaces().visibilityChanged(false);
 
             return true;
         } else {
@@ -207,26 +201,26 @@
                 runPostCollapseRunnables();
             }
         } else if (!getPresenter().isPresenterFullyCollapsed()) {
-            getStatusBar().instantCollapseNotificationPanel();
-            getStatusBar().visibilityChanged(false);
+            getCentralSurfaces().instantCollapseNotificationPanel();
+            getCentralSurfaces().visibilityChanged(false);
         } else {
             runPostCollapseRunnables();
         }
     }
 
-    private StatusBar getStatusBar() {
-        return mStatusBarOptionalLazy.get().get();
+    private CentralSurfaces getCentralSurfaces() {
+        return mCentralSurfacesOptionalLazy.get().get();
     }
 
     private NotificationPresenter getPresenter() {
-        return getStatusBar().getPresenter();
+        return getCentralSurfaces().getPresenter();
     }
 
     protected NotificationShadeWindowView getNotificationShadeWindowView() {
-        return getStatusBar().getNotificationShadeWindowView();
+        return getCentralSurfaces().getNotificationShadeWindowView();
     }
 
     private NotificationPanelViewController getNotificationPanelViewController() {
-        return getStatusBar().getPanelController();
+        return getCentralSurfaces().getPanelController();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
index a1be5ac..7555356 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
@@ -30,7 +30,7 @@
 import com.android.systemui.qs.ChipVisibilityListener
 import com.android.systemui.qs.HeaderPrivacyIconsController
 import com.android.systemui.qs.carrier.QSCarrierGroupController
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
 import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SPLIT_SHADE_BATTERY_CONTROLLER
 import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SPLIT_SHADE_HEADER
 import java.io.FileDescriptor
@@ -38,7 +38,7 @@
 import javax.inject.Inject
 import javax.inject.Named
 
-@StatusBarScope
+@CentralSurfacesScope
 class SplitShadeHeaderController @Inject constructor(
     @Named(SPLIT_SHADE_HEADER) private val statusBar: View,
     private val statusBarIconController: StatusBarIconController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
index 6eeae7f..50f2169 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
@@ -22,14 +22,16 @@
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.window.StatusBarWindowController;
 
 import javax.inject.Inject;
 
-/** Ties the {@link StatusBar} to {@link com.android.systemui.statusbar.policy.HeadsUpManager}. */
-@StatusBarComponent.StatusBarScope
+/**
+ * Ties the {@link CentralSurfaces} to {@link com.android.systemui.statusbar.policy.HeadsUpManager}.
+ */
+@CentralSurfacesComponent.CentralSurfacesScope
 public class StatusBarHeadsUpChangeListener implements OnHeadsUpChangedListener {
     private final NotificationShadeWindowController mNotificationShadeWindowController;
     private final StatusBarWindowController mStatusBarWindowController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 81fb903..31d9266 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -48,6 +48,7 @@
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorIconState;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
+import com.android.systemui.util.Assert;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -66,6 +67,8 @@
     void addIconGroup(IconManager iconManager);
     /** */
     void removeIconGroup(IconManager iconManager);
+    /** Refresh the state of an IconManager by recreating the views */
+    void refreshIconGroup(IconManager iconManager);
     /** */
     void setExternalIcon(String slot);
     /** */
@@ -243,6 +246,7 @@
         protected final int mIconSize;
         // Whether or not these icons show up in dumpsys
         protected boolean mShouldLog = false;
+        private StatusBarIconController mController;
 
         // Enables SystemUI demo mode to take effect in this group
         protected boolean mDemoable = true;
@@ -267,13 +271,17 @@
             mDemoable = demoable;
         }
 
-        public void setBlockList(@Nullable List<String> blockList) {
-            mBlockList.clear();
-            if (blockList == null || blockList.isEmpty()) {
-                return;
-            }
+        void setController(StatusBarIconController controller) {
+            mController = controller;
+        }
 
+        public void setBlockList(@Nullable List<String> blockList) {
+            Assert.isMainThread();
+            mBlockList.clear();
             mBlockList.addAll(blockList);
+            if (mController != null) {
+                mController.refreshIconGroup(this);
+            }
         }
 
         public void setShouldLog(boolean should) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index c5d3937..623ec5e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -100,6 +100,7 @@
             }
         }
 
+        group.setController(this);
         mIconGroups.add(group);
         List<Slot> allSlots = getSlots();
         for (int i = 0; i < allSlots.size(); i++) {
@@ -115,6 +116,12 @@
         }
     }
 
+    @Override
+    public void refreshIconGroup(IconManager iconManager) {
+        removeIconGroup(iconManager);
+        addIconGroup(iconManager);
+    }
+
     private void refreshIconGroups() {
         for (int i = mIconGroups.size() - 1; i >= 0; --i) {
             IconManager group = mIconGroups.get(i);
@@ -245,7 +252,7 @@
 
     /**
      * Accept a list of CallIndicatorIconStates, and show the call strength icons.
-     * @param slot StatusBar slot for the call strength icons
+     * @param slot statusbar slot for the call strength icons
      * @param states All of the no Calling & SMS icon states
      */
     @Override
@@ -272,7 +279,7 @@
 
     /**
      * Accept a list of CallIndicatorIconStates, and show the no calling icons.
-     * @param slot StatusBar slot for the no calling icons
+     * @param slot statusbar slot for the no calling icons
      * @param states All of the no Calling & SMS icon states
      */
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 11d9c31..c160c22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -124,8 +124,8 @@
         @Override
         public void onFullyShown() {
             updateStates();
-            mStatusBar.wakeUpIfDozing(SystemClock.uptimeMillis(),
-                    mStatusBar.getBouncerContainer(), "BOUNCER_VISIBLE");
+            mCentralSurfaces.wakeUpIfDozing(SystemClock.uptimeMillis(),
+                    mCentralSurfaces.getBouncerContainer(), "BOUNCER_VISIBLE");
         }
 
         @Override
@@ -175,7 +175,7 @@
 
     protected LockPatternUtils mLockPatternUtils;
     protected ViewMediatorCallback mViewMediatorCallback;
-    protected StatusBar mStatusBar;
+    protected CentralSurfaces mCentralSurfaces;
     private NotificationPanelViewController mNotificationPanelViewController;
     private BiometricUnlockController mBiometricUnlockController;
 
@@ -277,16 +277,16 @@
     }
 
     @Override
-    public void registerStatusBar(StatusBar statusBar,
+    public void registerCentralSurfaces(CentralSurfaces centralSurfaces,
             NotificationPanelViewController notificationPanelViewController,
             PanelExpansionStateManager panelExpansionStateManager,
             BiometricUnlockController biometricUnlockController,
             View notificationContainer,
             KeyguardBypassController bypassController) {
-        mStatusBar = statusBar;
+        mCentralSurfaces = centralSurfaces;
         mBiometricUnlockController = biometricUnlockController;
 
-        ViewGroup container = mStatusBar.getBouncerContainer();
+        ViewGroup container = mCentralSurfaces.getBouncerContainer();
         mBouncer = mKeyguardBouncerFactory.create(container, mExpansionCallback);
         mNotificationPanelViewController = notificationPanelViewController;
         if (panelExpansionStateManager != null) {
@@ -354,13 +354,13 @@
         } else if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
                 && mKeyguardUpdateManager.isUdfpsEnrolled()) {
             // Don't expand to the bouncer. Instead transition back to the lock screen (see
-            // StatusBar#showBouncerOrLockScreenIfKeyguard) where the user can use the UDFPS
+            // CentralSurfaces#showBouncerOrLockScreenIfKeyguard) where the user can use the UDFPS
             // affordance to enter the device (or swipe up to the input bouncer)
             return;
         } else if (bouncerNeedsScrimming()) {
             mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
         } else if (mShowing) {
-            if (!isWakeAndUnlocking() && !mStatusBar.isInLaunchTransition()) {
+            if (!isWakeAndUnlocking() && !mCentralSurfaces.isInLaunchTransition()) {
                 mBouncer.setExpansion(fraction);
             }
             if (fraction != KeyguardBouncer.EXPANSION_HIDDEN && tracking
@@ -371,7 +371,9 @@
         } else if (mPulsing && fraction == KeyguardBouncer.EXPANSION_VISIBLE) {
             // Panel expanded while pulsing but didn't translate the bouncer (because we are
             // unlocked.) Let's simply wake-up to dismiss the lock screen.
-            mStatusBar.wakeUpIfDozing(SystemClock.uptimeMillis(), mStatusBar.getBouncerContainer(),
+            mCentralSurfaces.wakeUpIfDozing(
+                    SystemClock.uptimeMillis(),
+                    mCentralSurfaces.getBouncerContainer(),
                     "BOUNCER_VISIBLE");
         }
     }
@@ -408,10 +410,10 @@
     protected void showBouncerOrKeyguard(boolean hideBouncerWhenShowing) {
         if (mBouncer.needsFullscreenBouncer() && !mDozing) {
             // The keyguard might be showing (already). So we need to hide it.
-            mStatusBar.hideKeyguard();
+            mCentralSurfaces.hideKeyguard();
             mBouncer.show(true /* resetSecuritySelection */);
         } else {
-            mStatusBar.showKeyguard();
+            mCentralSurfaces.showKeyguard();
             if (hideBouncerWhenShowing) {
                 hideBouncer(false /* destroyView */);
                 mBouncer.prepare();
@@ -540,7 +542,7 @@
             mNotificationPanelViewController.resetViews(/* animate= */ true);
             // Hide bouncer and quick-quick settings.
             if (mOccluded && !mDozing) {
-                mStatusBar.hideKeyguard();
+                mCentralSurfaces.hideKeyguard();
                 if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
                     hideBouncer(false /* destroyView */);
                 }
@@ -570,15 +572,15 @@
         mBypassController.setAltBouncerShowing(isShowingAlternateAuth());
 
         if (updateScrim) {
-            mStatusBar.updateScrimController();
+            mCentralSurfaces.updateScrimController();
         }
     }
 
     @Override
     public void onStartedWakingUp() {
-        mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+        mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
                 .setAnimationsDisabled(false);
-        NavigationBarView navBarView = mStatusBar.getNavigationBarView();
+        NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView();
         if (navBarView != null) {
             navBarView.forEachView(view ->
                     view.animate()
@@ -590,9 +592,9 @@
 
     @Override
     public void onStartedGoingToSleep() {
-        mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+        mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
                 .setAnimationsDisabled(true);
-        NavigationBarView navBarView = mStatusBar.getNavigationBarView();
+        NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView();
         if (navBarView != null) {
             navBarView.forEachView(view ->
                     view.animate()
@@ -628,7 +630,7 @@
     }
 
     /**
-     * If {@link StatusBar} is pulsing.
+     * If {@link CentralSurfaces} is pulsing.
      */
     public void setPulsing(boolean pulsing) {
         if (mPulsing != pulsing) {
@@ -649,13 +651,13 @@
 
     @Override
     public void setOccluded(boolean occluded, boolean animate) {
-        mStatusBar.setOccluded(occluded);
+        mCentralSurfaces.setOccluded(occluded);
         if (occluded && !mOccluded && mShowing) {
             SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
                     SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__OCCLUDED);
-            if (mStatusBar.isInLaunchTransition()) {
+            if (mCentralSurfaces.isInLaunchTransition()) {
                 setOccludedAndUpdateStates(true);
-                mStatusBar.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
+                mCentralSurfaces.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
                         new Runnable() {
                             @Override
                             public void run() {
@@ -666,7 +668,7 @@
                 return;
             }
 
-            if (mStatusBar.isLaunchingActivityOverLockscreen()) {
+            if (mCentralSurfaces.isLaunchingActivityOverLockscreen()) {
                 setOccludedAndUpdateStates(true);
 
                 // When isLaunchingActivityOverLockscreen() is true, we know for sure that the post
@@ -695,7 +697,7 @@
             reset(isOccluding /* hideBouncerWhenShowing*/);
         }
         if (animate && !occluded && mShowing && !mBouncer.isShowing()) {
-            mStatusBar.animateKeyguardUnoccluding();
+            mCentralSurfaces.animateKeyguardUnoccluding();
         }
     }
 
@@ -712,7 +714,7 @@
     public void startPreHideAnimation(Runnable finishRunnable) {
         if (mBouncer.isShowing()) {
             mBouncer.startPreHideAnimation(finishRunnable);
-            mStatusBar.onBouncerPreHideAnimation();
+            mCentralSurfaces.onBouncerPreHideAnimation();
 
             // We update the state (which will show the keyguard) only if an animation will run on
             // the keyguard. If there is no animation, we wait before updating the state so that we
@@ -745,11 +747,11 @@
         long uptimeMillis = SystemClock.uptimeMillis();
         long delay = Math.max(0, startTime + HIDE_TIMING_CORRECTION_MS - uptimeMillis);
 
-        if (mStatusBar.isInLaunchTransition()
+        if (mCentralSurfaces.isInLaunchTransition()
                 || mKeyguardStateController.isFlingingToDismissKeyguard()) {
             final boolean wasFlingingToDismissKeyguard =
                     mKeyguardStateController.isFlingingToDismissKeyguard();
-            mStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
+            mCentralSurfaces.fadeKeyguardAfterLaunchTransition(new Runnable() {
                 @Override
                 public void run() {
                     mNotificationShadeWindowController.setKeyguardShowing(false);
@@ -760,11 +762,11 @@
             }, new Runnable() {
                 @Override
                 public void run() {
-                    mStatusBar.hideKeyguard();
+                    mCentralSurfaces.hideKeyguard();
                     mNotificationShadeWindowController.setKeyguardFadingAway(false);
 
                     if (wasFlingingToDismissKeyguard) {
-                        mStatusBar.finishKeyguardFadingAway();
+                        mCentralSurfaces.finishKeyguardFadingAway();
                     }
 
                     mViewMediatorCallback.keyguardGone();
@@ -783,7 +785,7 @@
                 delay = 0;
                 fadeoutDuration = 240;
             }
-            mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration, needsFading);
+            mCentralSurfaces.setKeyguardFadingAway(startTime, delay, fadeoutDuration, needsFading);
             mBiometricUnlockController.startKeyguardFadingAway();
             hideBouncer(true /* destroyView */);
             if (wakeUnlockPulsing) {
@@ -793,11 +795,11 @@
                             mNotificationContainer,
                             fadeoutDuration,
                                     () -> {
-                        mStatusBar.hideKeyguard();
+                        mCentralSurfaces.hideKeyguard();
                         onKeyguardFadedAway();
                     });
                 } else {
-                    mStatusBar.fadeKeyguardWhilePulsing();
+                    mCentralSurfaces.fadeKeyguardWhilePulsing();
                 }
                 wakeAndUnlockDejank();
             } else {
@@ -810,20 +812,20 @@
                                 mNotificationContainer,
                                 fadeoutDuration,
                                 () -> {
-                                    mStatusBar.hideKeyguard();
+                                    mCentralSurfaces.hideKeyguard();
                                 });
                     } else {
-                        mStatusBar.hideKeyguard();
+                        mCentralSurfaces.hideKeyguard();
                     }
                     // hide() will happen asynchronously and might arrive after the scrims
                     // were already hidden, this means that the transition callback won't
                     // be triggered anymore and StatusBarWindowController will be forever in
                     // the fadingAway state.
-                    mStatusBar.updateScrimController();
+                    mCentralSurfaces.updateScrimController();
                     wakeAndUnlockDejank();
                 } else {
-                    mStatusBar.hideKeyguard();
-                    mStatusBar.finishKeyguardFadingAway();
+                    mCentralSurfaces.hideKeyguard();
+                    mCentralSurfaces.finishKeyguardFadingAway();
                     mBiometricUnlockController.finishKeyguardFadingAway();
                 }
             }
@@ -866,7 +868,7 @@
         mNotificationContainer.postDelayed(() -> mNotificationShadeWindowController
                         .setKeyguardFadingAway(false), 100);
         ViewGroupFadeHelper.reset(mNotificationPanelViewController.getView());
-        mStatusBar.finishKeyguardFadingAway();
+        mCentralSurfaces.finishKeyguardFadingAway();
         mBiometricUnlockController.finishKeyguardFadingAway();
         WindowManagerGlobal.getInstance().trimMemory(
                 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
@@ -897,7 +899,7 @@
 
     @Override
     public void dismissAndCollapse() {
-        mStatusBar.executeRunnableDismissingKeyguard(null, null, true, false, true);
+        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, true, false, true);
     }
 
     /**
@@ -922,7 +924,7 @@
      */
     public boolean onBackPressed(boolean hideImmediately) {
         if (mBouncer.isShowing()) {
-            mStatusBar.endAffordanceLaunch();
+            mCentralSurfaces.endAffordanceLaunch();
             // The second condition is for SIM card locked bouncer
             if (mBouncer.isScrimmed() && !mBouncer.needsFullscreenBouncer()) {
                 hideBouncer(false);
@@ -978,11 +980,11 @@
     private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() {
         @Override
         public void run() {
-            NavigationBarView view = mStatusBar.getNavigationBarView();
+            NavigationBarView view = mCentralSurfaces.getNavigationBarView();
             if (view != null) {
                 view.setVisibility(View.VISIBLE);
             }
-            mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+            mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
                     .show(navigationBars());
         }
     };
@@ -1013,7 +1015,7 @@
 
         if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
             mNotificationShadeWindowController.setBouncerShowing(bouncerShowing);
-            mStatusBar.setBouncerShowing(bouncerShowing);
+            mCentralSurfaces.setBouncerShowing(bouncerShowing);
         }
 
         if (occluded != mLastOccluded || mFirstUpdate) {
@@ -1040,11 +1042,11 @@
         mLastBiometricMode = mBiometricUnlockController.getMode();
         mLastGesturalNav = mGesturalNav;
         mLastIsDocked = mIsDocked;
-        mStatusBar.onKeyguardViewManagerStatesUpdated();
+        mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
     }
 
     private View getCurrentNavBarView() {
-        final NavigationBarView navBarView = mStatusBar.getNavigationBarView();
+        final NavigationBarView navBarView = mCentralSurfaces.getNavigationBarView();
         return navBarView != null ? navBarView.getCurrentView() : null;
     }
 
@@ -1052,7 +1054,7 @@
      * Updates the visibility of the nav bar window (which will cause insets changes).
      */
     protected void updateNavigationBarVisibility(boolean navBarVisible) {
-        if (mStatusBar.getNavigationBarView() != null) {
+        if (mCentralSurfaces.getNavigationBarView() != null) {
             if (navBarVisible) {
                 long delay = getNavBarShowDelay();
                 if (delay == 0) {
@@ -1063,7 +1065,7 @@
                 }
             } else {
                 mNotificationContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
-                mStatusBar.getNotificationShadeWindowView().getWindowInsetsController()
+                mCentralSurfaces.getNotificationShadeWindowView().getWindowInsetsController()
                         .hide(navigationBars());
             }
         }
@@ -1077,7 +1079,8 @@
                 && mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK_PULSING;
         boolean keyguardShowing = mShowing && !mOccluded;
         boolean hideWhileDozing = mDozing && !isWakeAndUnlockPulsing;
-        boolean keyguardWithGestureNav = (keyguardShowing && !mDozing || mPulsing && !mIsDocked)
+        boolean keyguardWithGestureNav = (keyguardShowing && !mDozing && !mScreenOffAnimationPlaying
+                || mPulsing && !mIsDocked)
                 && mGesturalNav;
         return (!keyguardShowing && !hideWhileDozing && !mScreenOffAnimationPlaying
                 || mBouncer.isShowing() || mRemoteInputActive || keyguardWithGestureNav
@@ -1091,7 +1094,8 @@
         boolean keyguardShowing = mLastShowing && !mLastOccluded;
         boolean hideWhileDozing = mLastDozing && mLastBiometricMode != MODE_WAKE_AND_UNLOCK_PULSING;
         boolean keyguardWithGestureNav = (keyguardShowing && !mLastDozing
-                || mLastPulsing && !mLastIsDocked) && mLastGesturalNav;
+                && !mLastScreenOffAnimationPlaying || mLastPulsing && !mLastIsDocked)
+                && mLastGesturalNav;
         return (!keyguardShowing && !hideWhileDozing && !mLastScreenOffAnimationPlaying
                 || mLastBouncerShowing || mLastRemoteInputActive || keyguardWithGestureNav
                 || mLastGlobalActionsVisible);
@@ -1118,7 +1122,7 @@
 
     @Override
     public boolean shouldDisableWindowAnimationsForUnlock() {
-        return mStatusBar.isInLaunchTransition();
+        return mCentralSurfaces.isInLaunchTransition();
     }
 
     @Override
@@ -1137,7 +1141,7 @@
 
     @Override
     public void keyguardGoingAway() {
-        mStatusBar.keyguardGoingAway();
+        mCentralSurfaces.keyguardGoingAway();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
index 09fca100..56b6dfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
@@ -10,34 +10,34 @@
  */
 class StatusBarLaunchAnimatorController(
     private val delegate: ActivityLaunchAnimator.Controller,
-    private val statusBar: StatusBar,
+    private val centralSurfaces: CentralSurfaces,
     private val isLaunchForActivity: Boolean = true
 ) : ActivityLaunchAnimator.Controller by delegate {
     // Always sync the opening window with the shade, given that we draw a hole punch in the shade
     // of the same size and position as the opening app to make it visible.
     override val openingWindowSyncView: View?
-        get() = statusBar.notificationShadeWindowView
+        get() = centralSurfaces.notificationShadeWindowView
 
     override fun onIntentStarted(willAnimate: Boolean) {
         delegate.onIntentStarted(willAnimate)
         if (!willAnimate) {
-            statusBar.collapsePanelOnMainThread()
+            centralSurfaces.collapsePanelOnMainThread()
         }
     }
 
     override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
         delegate.onLaunchAnimationStart(isExpandingFullyAbove)
-        statusBar.notificationPanelViewController.setIsLaunchAnimationRunning(true)
+        centralSurfaces.notificationPanelViewController.setIsLaunchAnimationRunning(true)
         if (!isExpandingFullyAbove) {
-            statusBar.collapsePanelWithDuration(
+            centralSurfaces.collapsePanelWithDuration(
                 ActivityLaunchAnimator.TIMINGS.totalDuration.toInt())
         }
     }
 
     override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
         delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
-        statusBar.notificationPanelViewController.setIsLaunchAnimationRunning(false)
-        statusBar.onLaunchAnimationEnd(isExpandingFullyAbove)
+        centralSurfaces.notificationPanelViewController.setIsLaunchAnimationRunning(false)
+        centralSurfaces.onLaunchAnimationEnd(isExpandingFullyAbove)
     }
 
     override fun onLaunchAnimationProgress(
@@ -46,11 +46,11 @@
         linearProgress: Float
     ) {
         delegate.onLaunchAnimationProgress(state, progress, linearProgress)
-        statusBar.notificationPanelViewController.applyLaunchAnimationProgress(linearProgress)
+        centralSurfaces.notificationPanelViewController.applyLaunchAnimationProgress(linearProgress)
     }
 
     override fun onLaunchAnimationCancelled() {
         delegate.onLaunchAnimationCancelled()
-        statusBar.onLaunchAnimationCancelled(isLaunchForActivity)
+        centralSurfaces.onLaunchAnimationCancelled(isLaunchForActivity)
     }
 }
\ No newline at end of file
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 ff86d74..108d98a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -18,7 +18,7 @@
 
 import static android.service.notification.NotificationListenerService.REASON_CLICK;
 
-import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.getActivityOptions;
 
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
@@ -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;
@@ -52,8 +53,6 @@
 import com.android.systemui.animation.ActivityLaunchAnimator;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -75,8 +74,10 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowDragController;
 import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
+import com.android.systemui.statusbar.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;
@@ -89,7 +90,8 @@
 /**
  * Status bar implementation of {@link NotificationActivityStarter}.
  */
-public class StatusBarNotificationActivityStarter implements NotificationActivityStarter {
+@CentralSurfacesComponent.CentralSurfacesScope
+class StatusBarNotificationActivityStarter implements NotificationActivityStarter {
 
     private final Context mContext;
 
@@ -123,16 +125,18 @@
     private final MetricsLogger mMetricsLogger;
     private final StatusBarNotificationActivityStarterLogger mLogger;
 
-    private final StatusBar mStatusBar;
+    private final CentralSurfaces mCentralSurfaces;
     private final NotificationPresenter mPresenter;
     private final NotificationPanelViewController mNotificationPanel;
     private final ActivityLaunchAnimator mActivityLaunchAnimator;
     private final NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
     private final OnUserInteractionCallback mOnUserInteractionCallback;
+    private final LaunchEventsEmitter mLaunchEventsEmitter;
 
     private boolean mIsCollapsingToShowActivityOverLockscreen;
 
-    private StatusBarNotificationActivityStarter(
+    @Inject
+    StatusBarNotificationActivityStarter(
             Context context,
             CommandQueue commandQueue,
             Handler mainThreadHandler,
@@ -162,11 +166,12 @@
             MetricsLogger metricsLogger,
             StatusBarNotificationActivityStarterLogger logger,
             OnUserInteractionCallback onUserInteractionCallback,
-            StatusBar statusBar,
+            CentralSurfaces centralSurfaces,
             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
-        mStatusBar = statusBar;
+        mCentralSurfaces = centralSurfaces;
         mPresenter = presenter;
         mNotificationPanel = panel;
         mActivityLaunchAnimator = activityLaunchAnimator;
         mNotificationAnimationProvider = notificationAnimationProvider;
+        mLaunchEventsEmitter = launchEventsEmitter;
 
         if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
             mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@@ -254,12 +258,14 @@
             return;
         }
 
+        mLaunchEventsEmitter.notifyStartLaunchNotifActivity(entry);
+
         boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
         final boolean willLaunchResolverActivity = isActivityIntent
                 && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
         final boolean animate = !willLaunchResolverActivity
-                && mStatusBar.shouldAnimateLaunch(isActivityIntent);
+                && mCentralSurfaces.shouldAnimateLaunch(isActivityIntent);
         boolean showOverLockscreen = mKeyguardStateController.isShowing() && intent != null
                 && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
                 mLockscreenUserManager.getCurrentUserId());
@@ -280,7 +286,9 @@
             postKeyguardAction.onDismiss();
         } else {
             mActivityStarter.dismissKeyguardThenExecute(
-                    postKeyguardAction, null /* cancel */, willLaunchResolverActivity);
+                    postKeyguardAction,
+                    () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry),
+                    willLaunchResolverActivity);
         }
     }
 
@@ -300,7 +308,7 @@
             mShadeController.addPostCollapseAction(runnable);
             mShadeController.collapsePanel(true /* animate */);
         } else if (mKeyguardStateController.isShowing()
-                && mStatusBar.isOccluded()) {
+                && mCentralSurfaces.isOccluded()) {
             mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
             mShadeController.collapsePanel();
         } else {
@@ -380,24 +388,26 @@
         // 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);
+                    mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry);
+                };
+                if (mPresenter.isCollapsing()) {
+                    // To avoid lags we're only performing the remove
+                    // after the shade is collapsed
+                    mShadeController.addPostCollapseAction(removeNotification);
+                } else {
+                    removeNotification.run();
+                }
+            });
+        } else {
+            mMainThreadHandler.post(
+                    () -> mLaunchEventsEmitter.notifyFinishLaunchNotifActivity(entry));
         }
 
         mIsCollapsingToShowActivityOverLockscreen = false;
@@ -475,7 +485,8 @@
         try {
             ActivityLaunchAnimator.Controller animationController =
                     new StatusBarLaunchAnimatorController(
-                            mNotificationAnimationProvider.getAnimatorController(row), mStatusBar,
+                            mNotificationAnimationProvider.getAnimatorController(row),
+                            mCentralSurfaces,
                             isActivityIntent);
 
             mActivityLaunchAnimator.startPendingIntentWithAnimation(animationController,
@@ -483,11 +494,11 @@
                         long eventTime = row.getAndResetLastActionUpTime();
                         Bundle options = eventTime > 0
                                 ? getActivityOptions(
-                                mStatusBar.getDisplayId(),
+                                mCentralSurfaces.getDisplayId(),
                                 adapter,
                                 mKeyguardStateController.isShowing(),
                                 eventTime)
-                                : getActivityOptions(mStatusBar.getDisplayId(), adapter);
+                                : getActivityOptions(mCentralSurfaces.getDisplayId(), adapter);
                         return intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
                                 null, null, options);
                     });
@@ -502,7 +513,7 @@
     @Override
     public void startNotificationGutsIntent(final Intent intent, final int appUid,
             ExpandableNotificationRow row) {
-        boolean animate = mStatusBar.shouldAnimateLaunch(true /* isActivityIntent */);
+        boolean animate = mCentralSurfaces.shouldAnimateLaunch(true /* isActivityIntent */);
         ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
             @Override
             public boolean onDismiss() {
@@ -510,14 +521,14 @@
                     ActivityLaunchAnimator.Controller animationController =
                             new StatusBarLaunchAnimatorController(
                                     mNotificationAnimationProvider.getAnimatorController(row),
-                                    mStatusBar, true /* isActivityIntent */);
+                                    mCentralSurfaces, true /* isActivityIntent */);
 
                     mActivityLaunchAnimator.startIntentWithAnimation(
                             animationController, animate, intent.getPackage(),
                             (adapter) -> TaskStackBuilder.create(mContext)
                                     .addNextIntentWithParentStack(intent)
                                     .startActivities(getActivityOptions(
-                                            mStatusBar.getDisplayId(),
+                                            mCentralSurfaces.getDisplayId(),
                                             adapter),
                                             new UserHandle(UserHandle.getUserId(appUid))));
                 });
@@ -535,7 +546,7 @@
 
     @Override
     public void startHistoryIntent(View view, boolean showHistory) {
-        boolean animate = mStatusBar.shouldAnimateLaunch(true /* isActivityIntent */);
+        boolean animate = mCentralSurfaces.shouldAnimateLaunch(true /* isActivityIntent */);
         ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
             @Override
             public boolean onDismiss() {
@@ -555,13 +566,14 @@
                             );
                     ActivityLaunchAnimator.Controller animationController =
                             viewController == null ? null
-                                : new StatusBarLaunchAnimatorController(viewController, mStatusBar,
+                                : new StatusBarLaunchAnimatorController(viewController,
+                                        mCentralSurfaces,
                                     true /* isActivityIntent */);
 
                     mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
                             intent.getPackage(),
                             (adapter) -> tsb.startActivities(
-                                    getActivityOptions(mStatusBar.getDisplayId(), adapter),
+                                    getActivityOptions(mCentralSurfaces.getDisplayId(), adapter),
                                     UserHandle.CURRENT));
                 });
                 return true;
@@ -615,7 +627,7 @@
                 try {
                     EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
                             entry.getKey());
-                    mStatusBar.wakeUpForFullScreenIntent();
+                    mCentralSurfaces.wakeUpForFullScreenIntent();
                     fullscreenIntent.send();
                     entry.notifyFullScreenIntentLaunched();
                     mMetricsLogger.count("note_fullscreen", 1);
@@ -658,179 +670,34 @@
         return entry.shouldSuppressFullScreenIntent();
     }
 
-    // --------------------- NotificationEntryManager/NotifPipeline methods ------------------------
-
-    /**
-     * Public builder for {@link StatusBarNotificationActivityStarter}.
-     */
     @SysUISingleton
-    public static class Builder {
-        private final Context mContext;
-        private final CommandQueue mCommandQueue;
-        private final Handler mMainThreadHandler;
+    static class LaunchEventsEmitter implements NotifActivityLaunchEvents {
 
-        private final Executor mUiBgExecutor;
-        private final NotificationEntryManager mEntryManager;
-        private final NotifPipeline mNotifPipeline;
-        private final NotificationVisibilityProvider mVisibilityProvider;
-        private final HeadsUpManagerPhone mHeadsUpManager;
-        private final ActivityStarter mActivityStarter;
-        private final NotificationClickNotifier mClickNotifier;
-        private final StatusBarStateController mStatusBarStateController;
-        private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-        private final KeyguardManager mKeyguardManager;
-        private final IDreamManager mDreamManager;
-        private final Optional<BubblesManager> mBubblesManagerOptional;
-        private final Lazy<AssistManager> mAssistManagerLazy;
-        private final NotificationRemoteInputManager mRemoteInputManager;
-        private final GroupMembershipManager mGroupMembershipManager;
-        private final NotificationLockscreenUserManager mLockscreenUserManager;
-        private final ShadeController mShadeController;
-        private final KeyguardStateController mKeyguardStateController;
-        private final NotificationInterruptStateProvider mNotificationInterruptStateProvider;
-        private final LockPatternUtils mLockPatternUtils;
-        private final StatusBarRemoteInputCallback mRemoteInputCallback;
-        private final ActivityIntentHelper mActivityIntentHelper;;
-        private final MetricsLogger mMetricsLogger;
-        private final StatusBarNotificationActivityStarterLogger mLogger;
-        private final OnUserInteractionCallback mOnUserInteractionCallback;
-        private final NotifPipelineFlags mNotifPipelineFlags;
-        private StatusBar mStatusBar;
-        private NotificationPresenter mNotificationPresenter;
-        private NotificationPanelViewController mNotificationPanelViewController;
-        private ActivityLaunchAnimator mActivityLaunchAnimator;
-        private NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
+        private final ListenerSet<Listener> mListeners = new ListenerSet<>();
 
         @Inject
-        public Builder(
-                Context context,
-                CommandQueue commandQueue,
-                @Main Handler mainThreadHandler,
-                @UiBackground Executor uiBgExecutor,
-                NotificationEntryManager entryManager,
-                NotifPipeline notifPipeline,
-                NotificationVisibilityProvider visibilityProvider,
-                HeadsUpManagerPhone headsUpManager,
-                ActivityStarter activityStarter,
-                NotificationClickNotifier clickNotifier,
-                StatusBarStateController statusBarStateController,
-                StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-                KeyguardManager keyguardManager,
-                IDreamManager dreamManager,
-                Optional<BubblesManager> bubblesManager,
-                Lazy<AssistManager> assistManagerLazy,
-                NotificationRemoteInputManager remoteInputManager,
-                GroupMembershipManager groupMembershipManager,
-                NotificationLockscreenUserManager lockscreenUserManager,
-                ShadeController shadeController,
-                KeyguardStateController keyguardStateController,
-                NotificationInterruptStateProvider notificationInterruptStateProvider,
-                LockPatternUtils lockPatternUtils,
-                StatusBarRemoteInputCallback remoteInputCallback,
-                ActivityIntentHelper activityIntentHelper,
-                NotifPipelineFlags notifPipelineFlags,
-                MetricsLogger metricsLogger,
-                StatusBarNotificationActivityStarterLogger logger,
-                OnUserInteractionCallback onUserInteractionCallback) {
+        LaunchEventsEmitter() {}
 
-            mContext = context;
-            mCommandQueue = commandQueue;
-            mMainThreadHandler = mainThreadHandler;
-            mUiBgExecutor = uiBgExecutor;
-            mEntryManager = entryManager;
-            mNotifPipeline = notifPipeline;
-            mVisibilityProvider = visibilityProvider;
-            mHeadsUpManager = headsUpManager;
-            mActivityStarter = activityStarter;
-            mClickNotifier = clickNotifier;
-            mStatusBarStateController = statusBarStateController;
-            mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
-            mKeyguardManager = keyguardManager;
-            mDreamManager = dreamManager;
-            mBubblesManagerOptional = bubblesManager;
-            mAssistManagerLazy = assistManagerLazy;
-            mRemoteInputManager = remoteInputManager;
-            mGroupMembershipManager = groupMembershipManager;
-            mLockscreenUserManager = lockscreenUserManager;
-            mShadeController = shadeController;
-            mKeyguardStateController = keyguardStateController;
-            mNotificationInterruptStateProvider = notificationInterruptStateProvider;
-            mLockPatternUtils = lockPatternUtils;
-            mRemoteInputCallback = remoteInputCallback;
-            mActivityIntentHelper = activityIntentHelper;
-            mNotifPipelineFlags = notifPipelineFlags;
-            mMetricsLogger = metricsLogger;
-            mLogger = logger;
-            mOnUserInteractionCallback = onUserInteractionCallback;
+        @Override
+        public void registerListener(@NonNull Listener listener) {
+            mListeners.addIfAbsent(listener);
         }
 
-        /** Sets the status bar to use as {@link StatusBar}. */
-        public Builder setStatusBar(StatusBar statusBar) {
-            mStatusBar = statusBar;
-            return this;
+        @Override
+        public void unregisterListener(@NonNull Listener listener) {
+            mListeners.remove(listener);
         }
 
-        public Builder setNotificationPresenter(NotificationPresenter notificationPresenter) {
-            mNotificationPresenter = notificationPresenter;
-            return this;
+        private void notifyStartLaunchNotifActivity(NotificationEntry entry) {
+            for (Listener listener : mListeners) {
+                listener.onStartLaunchNotifActivity(entry);
+            }
         }
 
-        /** Set the ActivityLaunchAnimator. */
-        public Builder setActivityLaunchAnimator(ActivityLaunchAnimator activityLaunchAnimator) {
-            mActivityLaunchAnimator = activityLaunchAnimator;
-            return this;
-        }
-
-        /** Set the NotificationLaunchAnimatorControllerProvider. */
-        public Builder setNotificationAnimatorControllerProvider(
-                NotificationLaunchAnimatorControllerProvider notificationAnimationProvider) {
-            mNotificationAnimationProvider = notificationAnimationProvider;
-            return this;
-        }
-
-        /** Set the NotificationPanelViewController. */
-        public Builder setNotificationPanelViewController(
-                NotificationPanelViewController notificationPanelViewController) {
-            mNotificationPanelViewController = notificationPanelViewController;
-            return this;
-        }
-
-        public StatusBarNotificationActivityStarter build() {
-            return new StatusBarNotificationActivityStarter(
-                    mContext,
-                    mCommandQueue,
-                    mMainThreadHandler,
-                    mUiBgExecutor,
-                    mEntryManager,
-                    mNotifPipeline,
-                    mVisibilityProvider,
-                    mHeadsUpManager,
-                    mActivityStarter,
-                    mClickNotifier,
-                    mStatusBarStateController,
-                    mStatusBarKeyguardViewManager,
-                    mKeyguardManager,
-                    mDreamManager,
-                    mBubblesManagerOptional,
-                    mAssistManagerLazy,
-                    mRemoteInputManager,
-                    mGroupMembershipManager,
-                    mLockscreenUserManager,
-                    mShadeController,
-                    mKeyguardStateController,
-                    mNotificationInterruptStateProvider,
-                    mLockPatternUtils,
-                    mRemoteInputCallback,
-                    mActivityIntentHelper,
-                    mNotifPipelineFlags,
-                    mMetricsLogger,
-                    mLogger,
-                    mOnUserInteractionCallback,
-                    mStatusBar,
-                    mNotificationPresenter,
-                    mNotificationPanelViewController,
-                    mActivityLaunchAnimator,
-                    mNotificationAnimationProvider);
+        private void notifyFinishLaunchNotifActivity(NotificationEntry entry) {
+            for (Listener listener : mListeners) {
+                listener.onFinishLaunchNotifActivity(entry);
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterModule.java
new file mode 100644
index 0000000..caa149e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterModule.java
@@ -0,0 +1,29 @@
+/*
+ * 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.NotificationActivityStarter;
+
+import dagger.Binds;
+import dagger.Module;
+
+@Module
+public abstract class StatusBarNotificationActivityStarterModule {
+    @Binds
+    abstract NotificationActivityStarter bindActivityStarter(
+            StatusBarNotificationActivityStarter impl);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index c8e1cdc..aa061d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -14,9 +14,9 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.systemui.statusbar.phone.StatusBar.CLOSE_PANEL_WHEN_EMPTIED;
-import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
-import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.CLOSE_PANEL_WHEN_EMPTIED;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.DEBUG;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.MULTIUSER_DEBUG;
 
 import android.app.KeyguardManager;
 import android.content.Context;
@@ -68,20 +68,25 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.util.List;
 
-public class StatusBarNotificationPresenter implements NotificationPresenter,
+import javax.inject.Inject;
+
+@CentralSurfacesComponent.CentralSurfacesScope
+class StatusBarNotificationPresenter implements NotificationPresenter,
         ConfigurationController.ConfigurationListener,
         NotificationRowBinderImpl.BindRowCallback,
         CommandQueue.Callbacks {
     private static final String TAG = "StatusBarNotificationPresenter";
 
-    private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
+    private final ActivityStarter mActivityStarter;
     private final KeyguardStateController mKeyguardStateController;
     private final NotificationViewHierarchyManager mViewHierarchyManager;
     private final NotificationLockscreenUserManager mLockscreenUserManager;
@@ -99,7 +104,7 @@
     private final DozeScrimController mDozeScrimController;
     private final ScrimController mScrimController;
     private final KeyguardIndicationController mKeyguardIndicationController;
-    private final StatusBar mStatusBar;
+    private final CentralSurfaces mCentralSurfaces;
     private final ShadeController mShadeController;
     private final LockscreenShadeTransitionController mShadeTransitionController;
     private final CommandQueue mCommandQueue;
@@ -110,16 +115,19 @@
     private final NotifPipelineFlags mNotifPipelineFlags;
     private final IStatusBarService mBarService;
     private final DynamicPrivacyController mDynamicPrivacyController;
+    private final NotificationListContainer mNotifListContainer;
     private boolean mReinflateNotificationsOnUserSwitched;
     private boolean mDispatchUiModeChangeOnUserSwitched;
     private TextView mNotificationPanelDebugText;
 
     protected boolean mVrMode;
 
-    public StatusBarNotificationPresenter(Context context,
+    @Inject
+    StatusBarNotificationPresenter(Context context,
             NotificationPanelViewController panel,
             HeadsUpManagerPhone headsUp,
             NotificationShadeWindowView statusBarWindow,
+            ActivityStarter activityStarter,
             NotificationStackScrollLayoutController stackScrollerController,
             DozeScrimController dozeScrimController,
             ScrimController scrimController,
@@ -127,7 +135,7 @@
             DynamicPrivacyController dynamicPrivacyController,
             KeyguardStateController keyguardStateController,
             KeyguardIndicationController keyguardIndicationController,
-            StatusBar statusBar,
+            CentralSurfaces centralSurfaces,
             ShadeController shadeController,
             LockscreenShadeTransitionController shadeTransitionController,
             CommandQueue commandQueue,
@@ -144,14 +152,17 @@
             NotificationInterruptStateProvider notificationInterruptStateProvider,
             NotificationRemoteInputManager remoteInputManager,
             ConfigurationController configurationController,
-            NotifPipelineFlags notifPipelineFlags) {
+            NotifPipelineFlags notifPipelineFlags,
+            NotificationRemoteInputManager.Callback remoteInputManagerCallback,
+            NotificationListContainer notificationListContainer) {
+        mActivityStarter = activityStarter;
         mKeyguardStateController = keyguardStateController;
         mNotificationPanel = panel;
         mHeadsUpManager = headsUp;
         mDynamicPrivacyController = dynamicPrivacyController;
         mKeyguardIndicationController = keyguardIndicationController;
         // TODO: use KeyguardStateController#isOccluded to remove this dependency
-        mStatusBar = statusBar;
+        mCentralSurfaces = centralSurfaces;
         mShadeController = shadeController;
         mShadeTransitionController = shadeTransitionController;
         mCommandQueue = commandQueue;
@@ -175,6 +186,7 @@
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        mNotifListContainer = notificationListContainer;
 
         IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
                 Context.VR_SERVICE));
@@ -186,14 +198,14 @@
             }
         }
         remoteInputManager.setUpWithCallback(
-                Dependency.get(NotificationRemoteInputManager.Callback.class),
+                remoteInputManagerCallback,
                 mNotificationPanel.createRemoteInputDelegate());
 
         initController.addPostInitTask(() -> {
             mKeyguardIndicationController.init();
             mViewHierarchyManager.setUpWithPresenter(this,
                     stackScrollerController.getNotifStackController(),
-                    stackScrollerController.getNotificationListContainer());
+                    mNotifListContainer);
             mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied);
             mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse);
             if (!mNotifPipelineFlags.isNewPipelineEnabled()) {
@@ -206,9 +218,8 @@
             notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
             mLockscreenUserManager.setUpWithPresenter(this);
             mMediaManager.setUpWithPresenter(this);
-            mGutsManager.setUpWithPresenter(this,
-                    stackScrollerController.getNotificationListContainer(), mCheckSaveListener,
-                    mOnSettingsClickListener);
+            mGutsManager.setUpWithPresenter(
+                    this, mNotifListContainer, mCheckSaveListener, mOnSettingsClickListener);
             // ForegroundServiceNotificationListener adds its listener in its constructor
             // but we need to request it here in order for it to be instantiated.
             // TODO: figure out how to do this correctly once Dependency.get() is gone.
@@ -341,7 +352,7 @@
             updateNotificationViews("user switched");
         }
         mMediaManager.clearCurrentMediaNotification();
-        mStatusBar.setLockscreenUser(newUserId);
+        mCentralSurfaces.setLockscreenUser(newUserId);
         updateMediaMetaData(true, false);
     }
 
@@ -395,7 +406,8 @@
     public void onExpandClicked(NotificationEntry clickedEntry, View clickedView,
             boolean nowExpanded) {
         mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
-        mStatusBar.wakeUpIfDozing(SystemClock.uptimeMillis(), clickedView, "NOTIFICATION_CLICK");
+        mCentralSurfaces.wakeUpIfDozing(
+                SystemClock.uptimeMillis(), clickedView, "NOTIFICATION_CLICK");
         if (nowExpanded) {
             if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
                 mShadeTransitionController.goToLockedShade(clickedEntry.getRow());
@@ -463,7 +475,7 @@
         @Override
         public boolean suppressAwakeHeadsUp(NotificationEntry entry) {
             final StatusBarNotification sbn = entry.getSbn();
-            if (mStatusBar.isOccluded()) {
+            if (mCentralSurfaces.isOccluded()) {
                 boolean devicePublic = mLockscreenUserManager
                         .isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
                 boolean userPublic = devicePublic
@@ -486,7 +498,7 @@
                 // we don't allow head-up on the lockscreen (unless there's a
                 // "showWhenLocked" activity currently showing)  if
                 // the potential HUN has a fullscreen intent
-                if (mKeyguardStateController.isShowing() && !mStatusBar.isOccluded()) {
+                if (mKeyguardStateController.isShowing() && !mCentralSurfaces.isOccluded()) {
                     if (DEBUG) {
                         Log.d(TAG, "No heads up: entry has fullscreen intent on lockscreen "
                                 + sbn.getKey());
@@ -511,7 +523,7 @@
 
         @Override
         public boolean suppressInterruptions(NotificationEntry entry) {
-            return mStatusBar.areNotificationAlertsDisabled();
+            return mCentralSurfaces.areNotificationAlertsDisabled();
         }
     };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterModule.java
new file mode 100644
index 0000000..26c483c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterModule.java
@@ -0,0 +1,33 @@
+/*
+ * 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.NotificationPresenter;
+import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
+
+import dagger.Binds;
+import dagger.Module;
+
+@Module
+public abstract class StatusBarNotificationPresenterModule {
+    @Binds
+    abstract NotificationPresenter bindPresenter(StatusBarNotificationPresenter impl);
+
+    @Binds
+    abstract NotificationRowBinderImpl.BindRowCallback bindBindRowCallback(
+            StatusBarNotificationPresenter impl);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index b0206f0..ee242a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -44,7 +44,7 @@
 
 import javax.inject.Inject;
 
-/** Controls the signal policies for icons shown in the StatusBar. **/
+/** Controls the signal policies for icons shown in the statusbar. **/
 @SysUISingleton
 public class StatusBarSignalPolicy implements SignalCallback,
         SecurityController.SecurityControllerCallback, Tunable {
@@ -449,7 +449,7 @@
     }
 
     /**
-     * Stores the StatusBar state for no Calling & SMS.
+     * Stores the statusbar state for no Calling & SMS.
      */
     public static class CallIndicatorIconState {
         public boolean isNoCalling;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index b742394..95667cc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -59,7 +59,7 @@
 
     private boolean mIsStatusBarExpanded = false;
     private boolean mShouldAdjustInsets = false;
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     private View mNotificationShadeWindowView;
     private View mNotificationPanelView;
     private boolean mForceCollapsedUntilLayout = false;
@@ -119,9 +119,9 @@
     }
 
     protected void setup(
-            @NonNull StatusBar statusBar,
+            @NonNull CentralSurfaces centralSurfaces,
             @NonNull View notificationShadeWindowView) {
-        mStatusBar = statusBar;
+        mCentralSurfaces = centralSurfaces;
         mNotificationShadeWindowView = notificationShadeWindowView;
         mNotificationPanelView = mNotificationShadeWindowView.findViewById(R.id.notification_panel);
     }
@@ -246,7 +246,7 @@
             new OnComputeInternalInsetsListener() {
         @Override
         public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
-            if (mIsStatusBarExpanded || mStatusBar.isBouncerShowing()) {
+            if (mIsStatusBarExpanded || mCentralSurfaces.isBouncerShowing()) {
                 // The touchable region is always the full area when expanded
                 return;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
index 26ba31c..582afb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
@@ -20,7 +20,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.util.ViewController;
@@ -32,7 +32,7 @@
 /**
  * Controller for {@link TapAgainView}.
  */
-@StatusBarComponent.StatusBarScope
+@CentralSurfacesComponent.CentralSurfacesScope
 public class TapAgainViewController extends ViewController<TapAgainView> {
     private final DelayableExecutor mDelayableExecutor;
     private final ConfigurationController mConfigurationController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 0abe8e4..c11d450 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -60,14 +60,13 @@
     private val handler: Handler = Handler()
 ) : WakefulnessLifecycle.Observer, ScreenOffAnimation {
 
-    private lateinit var statusBar: StatusBar
+    private lateinit var mCentralSurfaces: CentralSurfaces
     private lateinit var lightRevealScrim: LightRevealScrim
 
     private var animatorDurationScale = 1f
     private var shouldAnimateInKeyguard = false
     private var lightRevealAnimationPlaying = false
     private var aodUiAnimationPlaying = false
-    private var callbacks = HashSet<Callback>()
 
     /**
      * The result of our decision whether to play the screen off animation in
@@ -81,9 +80,6 @@
         interpolator = Interpolators.LINEAR
         addUpdateListener {
             lightRevealScrim.revealAmount = it.animatedValue as Float
-            sendUnlockedScreenOffProgressUpdate(
-                    1f - (it.animatedFraction as Float),
-                    1f - (it.animatedValue as Float))
             if (lightRevealScrim.isScrimAlmostOccludes &&
                     interactionJankMonitor.isInstrumenting(CUJ_SCREEN_OFF)) {
                 // ends the instrument when the scrim almost occludes the screen.
@@ -95,7 +91,6 @@
             override fun onAnimationCancel(animation: Animator?) {
                 lightRevealScrim.revealAmount = 1f
                 lightRevealAnimationPlaying = false
-                sendUnlockedScreenOffProgressUpdate(0f, 0f)
                 interactionJankMonitor.cancel(CUJ_SCREEN_OFF)
             }
 
@@ -105,7 +100,8 @@
             }
 
             override fun onAnimationStart(animation: Animator?) {
-                interactionJankMonitor.begin(statusBar.notificationShadeWindowView, CUJ_SCREEN_OFF)
+                interactionJankMonitor.begin(
+                    mCentralSurfaces.notificationShadeWindowView, CUJ_SCREEN_OFF)
             }
         })
     }
@@ -117,11 +113,11 @@
     }
 
     override fun initialize(
-        statusBar: StatusBar,
+        centralSurfaces: CentralSurfaces,
         lightRevealScrim: LightRevealScrim
     ) {
         this.lightRevealScrim = lightRevealScrim
-        this.statusBar = statusBar
+        this.mCentralSurfaces = centralSurfaces
 
         updateAnimatorDurationScale()
         globalSettings.registerContentObserver(
@@ -176,9 +172,9 @@
                         // Lock the keyguard if it was waiting for the screen off animation to end.
                         keyguardViewMediatorLazy.get().maybeHandlePendingLock()
 
-                        // Tell the StatusBar to become keyguard for real - we waited on that since
-                        // it is slow and would have caused the animation to jank.
-                        statusBar.updateIsKeyguard()
+                        // Tell the CentralSurfaces to become keyguard for real - we waited on that
+                        // since it is slow and would have caused the animation to jank.
+                        mCentralSurfaces.updateIsKeyguard()
 
                         // Run the callback given to us by the KeyguardVisibilityHelper.
                         after.run()
@@ -196,7 +192,8 @@
 
                     override fun onAnimationStart(animation: Animator?) {
                         interactionJankMonitor.begin(
-                                statusBar.notificationShadeWindowView, CUJ_SCREEN_OFF_SHOW_AOD)
+                                mCentralSurfaces.notificationShadeWindowView,
+                                CUJ_SCREEN_OFF_SHOW_AOD)
                     }
                 })
                 .start()
@@ -213,12 +210,12 @@
 
     override fun onFinishedWakingUp() {
         // Set this to false in onFinishedWakingUp rather than onStartedWakingUp so that other
-        // observers (such as StatusBar) can ask us whether we were playing the screen off animation
-        // and reset accordingly.
+        // observers (such as CentralSurfaces) can ask us whether we were playing the screen off
+        // animation and reset accordingly.
         aodUiAnimationPlaying = false
 
-        // If we can't control the screen off animation, we shouldn't mess with the StatusBar's
-        // keyguard state unnecessarily.
+        // If we can't control the screen off animation, we shouldn't mess with the
+        // CentralSurfaces's keyguard state unnecessarily.
         if (dozeParameters.get().canControlUnlockedScreenOff()) {
             // Make sure the status bar is in the correct keyguard state, forcing it if necessary.
             // This is required if the screen off animation is cancelled, since it might be
@@ -227,7 +224,7 @@
             // even if we're going from SHADE to SHADE or KEYGUARD to KEYGUARD, since we might have
             // changed parts of the UI (such as showing AOD in the shade) without actually changing
             // the StatusBarState. This ensures that the UI definitely reflects the desired state.
-            statusBar.updateIsKeyguard(true /* forceStateChange */)
+            mCentralSurfaces.updateIsKeyguard(true /* forceStateChange */)
         }
     }
 
@@ -249,7 +246,7 @@
 
                     // Show AOD. That'll cause the KeyguardVisibilityHelper to call
                     // #animateInKeyguard.
-                    statusBar.notificationPanelViewController.showAodUi()
+                    mCentralSurfaces.notificationPanelViewController.showAodUi()
                 }
             }, (ANIMATE_IN_KEYGUARD_DELAY * animatorDurationScale).toLong())
 
@@ -285,8 +282,8 @@
         // We currently draw both the light reveal scrim, and the AOD UI, in the shade. If it's
         // already expanded and showing notifications/QS, the animation looks really messy. For now,
         // disable it if the notification panel is not fully collapsed.
-        if ((!this::statusBar.isInitialized ||
-                !statusBar.notificationPanelViewController.isFullyCollapsed) &&
+        if ((!this::mCentralSurfaces.isInitialized ||
+                !mCentralSurfaces.notificationPanelViewController.isFullyCollapsed) &&
                 // Status bar might be expanded because we have started
                 // playing the animation already
                 !isAnimationPlaying()
@@ -309,20 +306,6 @@
     override fun shouldDelayDisplayDozeTransition(): Boolean =
         dozeParameters.get().shouldControlUnlockedScreenOff()
 
-    fun addCallback(callback: Callback) {
-        callbacks.add(callback)
-    }
-
-    fun removeCallback(callback: Callback) {
-        callbacks.remove(callback)
-    }
-
-    private fun sendUnlockedScreenOffProgressUpdate(linear: Float, eased: Float) {
-        callbacks.forEach {
-            it.onUnlockedScreenOffProgressUpdate(linear, eased)
-        }
-    }
-
     /**
      * Whether we're doing the light reveal animation or we're done with that and animating in the
      * AOD UI.
@@ -356,8 +339,4 @@
     fun isScreenOffLightRevealAnimationPlaying(): Boolean {
         return lightRevealAnimationPlaying
     }
-
-    interface Callback {
-        fun onUnlockedScreenOffProgressUpdate(linear: Float, eased: Float)
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
similarity index 68%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
index ad8e79e..a86ad6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java
@@ -22,16 +22,22 @@
 
 import com.android.keyguard.LockIconViewController;
 import com.android.systemui.biometrics.AuthRippleController;
+import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationShelfController;
 import com.android.systemui.statusbar.core.StatusBarInitializer;
-import com.android.systemui.statusbar.notification.collection.render.StatusBarNotifPanelEventSourceModule;
+import com.android.systemui.statusbar.notification.NotificationActivityStarter;
+import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutListContainerModule;
+import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks;
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController;
 import com.android.systemui.statusbar.phone.SplitShadeHeaderController;
-import com.android.systemui.statusbar.phone.StatusBarCommandQueueCallbacks;
 import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener;
+import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarterModule;
+import com.android.systemui.statusbar.phone.StatusBarNotificationPresenterModule;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 
 import java.lang.annotation.Documented;
@@ -45,7 +51,7 @@
 
 /**
  * Dagger subcomponent for classes (semi-)related to the status bar. The component is created once
- * inside {@link com.android.systemui.statusbar.phone.StatusBar} and never re-created.
+ * inside {@link com.android.systemui.statusbar.phone.CentralSurfaces} and never re-created.
  *
  * TODO(b/197137564): This should likely be re-factored a bit. It includes classes that aren't
  * directly related to status bar functionality, like multiple notification classes. And, the fact
@@ -53,81 +59,82 @@
  * outside the component. Should more items be moved *into* this component to avoid so many getters?
  */
 @Subcomponent(modules = {
-        StatusBarNotifPanelEventSourceModule.class,
-        StatusBarViewModule.class
+        CentralSurfacesStartableModule.class,
+        NotificationStackScrollLayoutListContainerModule.class,
+        StatusBarViewModule.class,
+        StatusBarNotificationActivityStarterModule.class,
+        StatusBarNotificationPresenterModule.class,
 })
-@StatusBarComponent.StatusBarScope
-public interface StatusBarComponent {
+@CentralSurfacesComponent.CentralSurfacesScope
+public interface CentralSurfacesComponent {
     /**
-     * Builder for {@link StatusBarComponent}.
+     * Builder for {@link CentralSurfacesComponent}.
      */
     @Subcomponent.Factory
     interface Factory {
-        StatusBarComponent create();
+        CentralSurfacesComponent create();
     }
 
     /**
-     * Scope annotation for singleton items within the StatusBarComponent.
+     * Scope annotation for singleton items within the CentralSurfacesComponent.
      */
     @Documented
     @Retention(RUNTIME)
     @Scope
-    @interface StatusBarScope {}
+    @interface CentralSurfacesScope {}
+
+    /**
+     * Performs initialization logic after {@link CentralSurfacesComponent} has been constructed.
+     */
+    interface Startable {
+        void start();
+        void stop();
+    }
 
     /**
      * Creates a {@link NotificationShadeWindowView}.
      */
-    @StatusBarScope
     NotificationShadeWindowView getNotificationShadeWindowView();
 
     /** */
-    @StatusBarScope
     NotificationShelfController getNotificationShelfController();
 
     /** */
-    @StatusBarScope
     NotificationStackScrollLayoutController getNotificationStackScrollLayoutController();
 
     /**
      * Creates a NotificationShadeWindowViewController.
      */
-    @StatusBarScope
     NotificationShadeWindowViewController getNotificationShadeWindowViewController();
 
     /**
      * Creates a NotificationPanelViewController.
      */
-    @StatusBarScope
     NotificationPanelViewController getNotificationPanelViewController();
 
     /**
      * Creates a LockIconViewController. Must be init after creation.
      */
-    @StatusBarScope
     LockIconViewController getLockIconViewController();
 
     /**
      * Creates an AuthRippleViewController. Must be init after creation.
      */
-    @StatusBarScope
     AuthRippleController getAuthRippleController();
 
     /**
      * Creates a StatusBarHeadsUpChangeListener.
      */
-    @StatusBarScope
     StatusBarHeadsUpChangeListener getStatusBarHeadsUpChangeListener();
 
     /**
-     * Creates a StatusBarCommandQueueCallbacks.
+     * Creates a CentralSurfacesCommandQueueCallbacks.
      */
-    @StatusBarScope
-    StatusBarCommandQueueCallbacks getStatusBarCommandQueueCallbacks();
+    CentralSurfacesCommandQueueCallbacks getCentralSurfacesCommandQueueCallbacks();
 
     /**
      * Creates a SplitShadeHeaderController.
      */
-    @StatusBarScope
     SplitShadeHeaderController getSplitShadeHeaderController();
 
     /**
@@ -140,20 +147,18 @@
     /**
      * Creates a StatusBarInitializer
      */
-    @StatusBarScope
     StatusBarInitializer getStatusBarInitializer();
 
     /**
-     * Set of startables to be run after a StatusBarComponent has been constructed.
+     * Set of startables to be run after a CentralSurfacesComponent has been constructed.
      */
-    @StatusBarScope
     Set<Startable> getStartables();
 
-    /**
-     * Performs initialization logic after {@link StatusBarComponent} has been constructed.
-     */
-    interface Startable {
-        void start();
-        void stop();
-    }
+    NotificationActivityStarter getNotificationActivityStarter();
+
+    NotificationPresenter getNotificationPresenter();
+
+    NotificationRowBinderImpl.BindRowCallback getBindRowCallback();
+
+    NotificationListContainer getNotificationListContainer();
 }
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%
copy from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
copy 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/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index c6b5b1d..c024c72 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -92,10 +92,9 @@
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
 import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
 import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
@@ -115,7 +114,6 @@
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
 import java.util.Optional;
@@ -128,16 +126,16 @@
 import dagger.Provides;
 
 /**
- * Dagger Module providing {@link StatusBar}.
+ * Dagger Module providing {@link CentralSurfaces}.
  */
 @Module
 public interface StatusBarPhoneModule {
     /**
-     * Provides our instance of StatusBar which is considered optional.
+     * Provides our instance of CentralSurfaces which is considered optional.
      */
     @Provides
     @SysUISingleton
-    static StatusBar provideStatusBar(
+    static CentralSurfaces provideCentralSurfaces(
             Context context,
             NotificationsController notificationsController,
             FragmentService fragmentService,
@@ -197,11 +195,8 @@
             DozeScrimController dozeScrimController,
             VolumeComponent volumeComponent,
             CommandQueue commandQueue,
-            StatusBarComponent.Factory statusBarComponentFactory,
+            CentralSurfacesComponent.Factory statusBarComponentFactory,
             PluginManager pluginManager,
-            Optional<LegacySplitScreen> splitScreenOptional,
-            StatusBarNotificationActivityStarter.Builder
-                    statusBarNotificationActivityStarterBuilder,
             ShadeController shadeController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
             ViewMediatorCallback viewMediatorCallback,
@@ -236,7 +231,7 @@
             DeviceStateManager deviceStateManager,
             DreamOverlayStateController dreamOverlayStateController,
             WiredChargingRippleController wiredChargingRippleController) {
-        return new StatusBar(
+        return new CentralSurfaces(
                 context,
                 notificationsController,
                 fragmentService,
@@ -298,8 +293,6 @@
                 commandQueue,
                 statusBarComponentFactory,
                 pluginManager,
-                splitScreenOptional,
-                statusBarNotificationActivityStarterBuilder,
                 shadeController,
                 statusBarKeyguardViewManager,
                 viewMediatorCallback,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index ebd58fb..79fe700 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -61,6 +61,9 @@
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.tuner.TunerService;
+import com.android.systemui.util.settings.SecureSettings;
+
+import java.util.concurrent.Executor;
 
 import javax.inject.Named;
 
@@ -77,7 +80,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static NotificationShadeWindowView providesNotificationShadeWindowView(
             LayoutInflater layoutInflater) {
         NotificationShadeWindowView notificationShadeWindowView = (NotificationShadeWindowView)
@@ -92,7 +95,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static NotificationStackScrollLayout providesNotificationStackScrollLayout(
             NotificationShadeWindowView notificationShadeWindowView) {
         return notificationShadeWindowView.findViewById(R.id.notification_stack_scroller);
@@ -100,7 +103,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static NotificationShelf providesNotificationShelf(LayoutInflater layoutInflater,
             NotificationStackScrollLayout notificationStackScrollLayout) {
         NotificationShelf view = (NotificationShelf) layoutInflater.inflate(
@@ -115,7 +118,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static NotificationShelfController providesStatusBarWindowView(
             NotificationShelfComponent.Builder notificationShelfComponentBuilder,
             NotificationShelf notificationShelf) {
@@ -131,7 +134,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static NotificationPanelView getNotificationPanelView(
             NotificationShadeWindowView notificationShadeWindowView) {
         return notificationShadeWindowView.getNotificationPanelView();
@@ -139,7 +142,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static LockIconView getLockIconView(
             NotificationShadeWindowView notificationShadeWindowView) {
         return notificationShadeWindowView.findViewById(R.id.lock_icon_view);
@@ -147,7 +150,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     @Nullable
     public static AuthRippleView getAuthRippleView(
             NotificationShadeWindowView notificationShadeWindowView) {
@@ -157,7 +160,7 @@
     /** */
     @Provides
     @Named(SPLIT_SHADE_HEADER)
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static View getSplitShadeStatusBarView(
             NotificationShadeWindowView notificationShadeWindowView,
             FeatureFlags featureFlags) {
@@ -172,7 +175,7 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static OngoingPrivacyChip getSplitShadeOngoingPrivacyChip(
             @Named(SPLIT_SHADE_HEADER) View header) {
         return header.findViewById(R.id.privacy_chip);
@@ -180,21 +183,21 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     static StatusIconContainer providesStatusIconContainer(@Named(SPLIT_SHADE_HEADER) View header) {
         return header.findViewById(R.id.statusIcons);
     }
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     @Named(SPLIT_SHADE_BATTERY_VIEW)
     static BatteryMeterView getBatteryMeterView(@Named(SPLIT_SHADE_HEADER) View view) {
         return view.findViewById(R.id.batteryRemainingIcon);
     }
 
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     @Named(SPLIT_SHADE_BATTERY_CONTROLLER)
     static BatteryMeterViewController getBatteryMeterViewController(
             @Named(SPLIT_SHADE_BATTERY_VIEW) BatteryMeterView batteryMeterView,
@@ -218,14 +221,14 @@
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static TapAgainView getTapAgainView(NotificationPanelView npv) {
         return npv.getTapAgainView();
     }
 
     /** */
     @Provides
-    @StatusBarComponent.StatusBarScope
+    @CentralSurfacesComponent.CentralSurfacesScope
     public static NotificationsQuickSettingsContainer getNotificationsQuickSettingsContainer(
             NotificationShadeWindowView notificationShadeWindowView) {
         return notificationShadeWindowView.findViewById(R.id.notification_container_parent);
@@ -235,9 +238,9 @@
      * Creates a new {@link CollapsedStatusBarFragment}.
      *
      * **IMPORTANT**: This method intentionally does not have
-     * {@link StatusBarComponent.StatusBarScope}, which means a new fragment *will* be created each
-     * time this method is called. This is intentional because we need fragments to re-created in
-     * certain lifecycle scenarios.
+     * {@link CentralSurfacesComponent.CentralSurfacesScope}, which means a new fragment *will* be
+     * created each time this method is called. This is intentional because we need fragments to
+     * re-created in certain lifecycle scenarios.
      *
      * This provider is {@link Named} such that it does not conflict with the provider inside of
      * {@link StatusBarFragmentComponent}.
@@ -260,7 +263,9 @@
             StatusBarStateController statusBarStateController,
             CommandQueue commandQueue,
             CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
-            OperatorNameViewController.Factory operatorNameViewControllerFactory
+            OperatorNameViewController.Factory operatorNameViewControllerFactory,
+            SecureSettings secureSettings,
+            @Main Executor mainExecutor
     ) {
         return new CollapsedStatusBarFragment(statusBarFragmentComponentFactory,
                 ongoingCallController,
@@ -277,6 +282,8 @@
                 statusBarStateController,
                 commandQueue,
                 collapsedStatusBarFragmentLogger,
-                operatorNameViewControllerFactory);
+                operatorNameViewControllerFactory,
+                secureSettings,
+                mainExecutor);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index 2af0772..2c84219 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -30,8 +30,10 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.app.Fragment;
+import android.database.ContentObserver;
 import android.os.Bundle;
 import android.os.Parcelable;
+import android.provider.Settings;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -39,8 +41,11 @@
 import android.view.ViewStub;
 import android.widget.LinearLayout;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.systemui.R;
 import com.android.systemui.animation.Interpolators;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
@@ -66,9 +71,11 @@
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.EncryptionHelper;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.settings.SecureSettings;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 /**
  * Contains the collapsed status bar and handles hiding/showing based on disable flags
@@ -110,6 +117,8 @@
     private final PanelExpansionStateManager mPanelExpansionStateManager;
     private final StatusBarIconController mStatusBarIconController;
     private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
+    private final SecureSettings mSecureSettings;
+    private final Executor mMainExecutor;
 
     private List<String> mBlockedIcons = new ArrayList<>();
 
@@ -145,7 +154,9 @@
             StatusBarStateController statusBarStateController,
             CommandQueue commandQueue,
             CollapsedStatusBarFragmentLogger collapsedStatusBarFragmentLogger,
-            OperatorNameViewController.Factory operatorNameViewControllerFactory
+            OperatorNameViewController.Factory operatorNameViewControllerFactory,
+            SecureSettings secureSettings,
+            @Main Executor mainExecutor
     ) {
         mStatusBarFragmentComponentFactory = statusBarFragmentComponentFactory;
         mOngoingCallController = ongoingCallController;
@@ -163,6 +174,8 @@
         mCommandQueue = commandQueue;
         mCollapsedStatusBarFragmentLogger = collapsedStatusBarFragmentLogger;
         mOperatorNameViewControllerFactory = operatorNameViewControllerFactory;
+        mSecureSettings = secureSettings;
+        mMainExecutor = mainExecutor;
     }
 
     @Override
@@ -187,10 +200,7 @@
         }
         mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons), mFeatureFlags);
         mDarkIconManager.setShouldLog(true);
-        mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_volume));
-        mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_alarm_clock));
-        mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_call_strength));
-        mDarkIconManager.setBlockList(mBlockedIcons);
+        updateBlockedIcons();
         mStatusBarIconController.addIconGroup(mDarkIconManager);
         mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
         mClockView = mStatusBar.findViewById(R.id.clock);
@@ -203,6 +213,24 @@
         mAnimationScheduler.addCallback(this);
     }
 
+    @VisibleForTesting
+    void updateBlockedIcons() {
+        mBlockedIcons.clear();
+
+        if (mSecureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0) == 0) {
+            mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_volume));
+        }
+        mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_alarm_clock));
+        mBlockedIcons.add(getString(com.android.internal.R.string.status_bar_call_strength));
+
+        mMainExecutor.execute(() -> mDarkIconManager.setBlockList(mBlockedIcons));
+    }
+
+    @VisibleForTesting
+    List<String> getBlockedIcons() {
+        return mBlockedIcons;
+    }
+
     @Override
     public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
@@ -217,6 +245,11 @@
         mCommandQueue.addCallback(this);
         mStatusBarStateController.addCallback(this);
         initOngoingCallChip();
+
+        mSecureSettings.registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON),
+                false,
+                mVolumeSettingObserver);
     }
 
     @Override
@@ -225,6 +258,7 @@
         mCommandQueue.removeCallback(this);
         mStatusBarStateController.removeCallback(this);
         mOngoingCallController.removeCallback(mOngoingCallListener);
+        mSecureSettings.unregisterContentObserver(mVolumeSettingObserver);
     }
 
     @Override
@@ -584,6 +618,13 @@
         mLocationPublisher.updateStatusBarMargin(leftMargin, rightMargin);
     }
 
+    private final ContentObserver mVolumeSettingObserver = new ContentObserver(null) {
+        @Override
+        public void onChange(boolean selfChange) {
+            updateBlockedIcons();
+        }
+    };
+
     // Listen for view end changes of PhoneStatusBarView and publish that to the privacy dot
     private View.OnLayoutChangeListener mStatusBarLayoutListener =
             (view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
index 22b7f64..2eba325 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
@@ -18,12 +18,14 @@
 
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.dagger.qualifiers.RootView;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.LightsOutNotifController;
 import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
 import com.android.systemui.statusbar.phone.StatusBarDemoMode;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
 
 import dagger.BindsInstance;
@@ -39,12 +41,6 @@
  *
  * Anything that depends on {@link CollapsedStatusBarFragment} or {@link PhoneStatusBarView}
  * should be included here or in {@link StatusBarFragmentModule}.
- *
- * Note that this is completely separate from
- * {@link com.android.systemui.statusbar.phone.dagger.StatusBarComponent}. This component gets
- * re-created on each new fragment creation, whereas
- * {@link com.android.systemui.statusbar.phone.dagger.StatusBarComponent} is only created once in
- * {@link com.android.systemui.statusbar.phone.StatusBar} and never re-created.
  */
 
 @Subcomponent(modules = {StatusBarFragmentModule.class})
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
index c7f7258..6ee65ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
@@ -21,7 +21,8 @@
 import android.app.IUidObserver
 import android.app.Notification
 import android.app.Notification.CallStyle.CALL_TYPE_ONGOING
-import android.content.Intent
+import android.app.PendingIntent
+import android.content.Context
 import android.util.Log
 import android.view.View
 import androidx.annotation.VisibleForTesting
@@ -52,6 +53,7 @@
  */
 @SysUISingleton
 class OngoingCallController @Inject constructor(
+    private val context: Context,
     private val notifCollection: CommonNotifCollection,
     private val ongoingCallFlags: OngoingCallFlags,
     private val systemClock: SystemClock,
@@ -67,13 +69,10 @@
     private var isFullscreen: Boolean = false
     /** Non-null if there's an active call notification. */
     private var callNotificationInfo: CallNotificationInfo? = null
-    /** True if the application managing the call is visible to the user. */
-    private var isCallAppVisible: Boolean = false
     private var chipView: View? = null
-    private var uidObserver: IUidObserver.Stub? = null
 
     private val mListeners: MutableList<OngoingCallListener> = mutableListOf()
-
+    private val uidObserver = CallAppUidObserver()
     private val notifListener = object : NotifCollectionListener {
         // Temporary workaround for b/178406514 for testing purposes.
         //
@@ -96,7 +95,7 @@
                 val newOngoingCallInfo = CallNotificationInfo(
                         entry.sbn.key,
                         entry.sbn.notification.`when`,
-                        entry.sbn.notification.contentIntent?.intent,
+                        entry.sbn.notification.contentIntent,
                         entry.sbn.uid,
                         entry.sbn.notification.extras.getInt(
                                 Notification.EXTRA_CALL_TYPE, -1) == CALL_TYPE_ONGOING,
@@ -158,7 +157,7 @@
     fun hasOngoingCall(): Boolean {
         return callNotificationInfo?.isOngoing == true &&
                 // When the user is in the phone app, don't show the chip.
-                !isCallAppVisible
+                !uidObserver.isCallAppVisible
     }
 
     override fun addCallback(listener: OngoingCallListener) {
@@ -194,7 +193,7 @@
             }
             updateChipClickListener()
 
-            setUpUidObserver(currentCallNotificationInfo)
+            uidObserver.registerWithUid(currentCallNotificationInfo.uid)
             if (!currentCallNotificationInfo.statusBarSwipedAway) {
                 statusBarWindowController.ifPresent {
                     it.setOngoingProcessRequiresStatusBarVisible(true)
@@ -228,7 +227,6 @@
                     logger.logChipClicked()
                     activityStarter.postStartActivityDismissingKeyguard(
                         intent,
-                        0,
                         ActivityLaunchAnimator.Controller.fromView(
                             backgroundView,
                             InteractionJankMonitor.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP)
@@ -238,51 +236,6 @@
         }
     }
 
-    /**
-     * Sets up an [IUidObserver] to monitor the status of the application managing the ongoing call.
-     */
-    private fun setUpUidObserver(currentCallNotificationInfo: CallNotificationInfo) {
-        isCallAppVisible = isProcessVisibleToUser(
-                iActivityManager.getUidProcessState(currentCallNotificationInfo.uid, null))
-
-        if (uidObserver != null) {
-            iActivityManager.unregisterUidObserver(uidObserver)
-        }
-
-        uidObserver = object : IUidObserver.Stub() {
-            override fun onUidStateChanged(
-                uid: Int,
-                procState: Int,
-                procStateSeq: Long,
-                capability: Int
-            ) {
-                if (uid == currentCallNotificationInfo.uid) {
-                    val oldIsCallAppVisible = isCallAppVisible
-                    isCallAppVisible = isProcessVisibleToUser(procState)
-                    if (oldIsCallAppVisible != isCallAppVisible) {
-                        // Animations may be run as a result of the call's state change, so ensure
-                        // the listener is notified on the main thread.
-                        mainExecutor.execute {
-                            mListeners.forEach { l -> l.onOngoingCallStateChanged(animate = true) }
-                        }
-                    }
-                }
-            }
-
-            override fun onUidGone(uid: Int, disabled: Boolean) {}
-            override fun onUidActive(uid: Int) {}
-            override fun onUidIdle(uid: Int, disabled: Boolean) {}
-            override fun onUidCachedChanged(uid: Int, cached: Boolean) {}
-        }
-
-        iActivityManager.registerUidObserver(
-                uidObserver,
-                ActivityManager.UID_OBSERVER_PROCSTATE,
-                ActivityManager.PROCESS_STATE_UNKNOWN,
-                null
-        )
-    }
-
     /** Returns true if the given [procState] represents a process that's visible to the user. */
     private fun isProcessVisibleToUser(procState: Int): Boolean {
         return procState <= ActivityManager.PROCESS_STATE_TOP
@@ -295,7 +248,7 @@
             swipeStatusBarAwayGestureHandler.ifPresent { it.removeOnGestureDetectedCallback(TAG) }
         } else {
             swipeStatusBarAwayGestureHandler.ifPresent {
-                it.addOnGestureDetectedCallback(TAG, this::onSwipeAwayGestureDetected)
+                it.addOnGestureDetectedCallback(TAG) { _ -> onSwipeAwayGestureDetected() }
             }
         }
     }
@@ -306,9 +259,7 @@
         statusBarWindowController.ifPresent { it.setOngoingProcessRequiresStatusBarVisible(false) }
         swipeStatusBarAwayGestureHandler.ifPresent { it.removeOnGestureDetectedCallback(TAG) }
         mListeners.forEach { l -> l.onOngoingCallStateChanged(animate = true) }
-        if (uidObserver != null) {
-            iActivityManager.unregisterUidObserver(uidObserver)
-        }
+        uidObserver.unregister()
     }
 
     /** Tear down anything related to the chip view to prevent leaks. */
@@ -349,7 +300,7 @@
     private data class CallNotificationInfo(
         val key: String,
         val callStartTime: Long,
-        val intent: Intent?,
+        val intent: PendingIntent?,
         val uid: Int,
         /** True if the call is currently ongoing (as opposed to incoming, screening, etc.). */
         val isOngoing: Boolean,
@@ -365,7 +316,84 @@
 
     override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
         pw.println("Active call notification: $callNotificationInfo")
-        pw.println("Call app visible: $isCallAppVisible")
+        pw.println("Call app visible: ${uidObserver.isCallAppVisible}")
+    }
+
+    /** Our implementation of a [IUidObserver]. */
+    inner class CallAppUidObserver : IUidObserver.Stub() {
+        /** True if the application managing the call is visible to the user. */
+        var isCallAppVisible: Boolean = false
+            private set
+
+        /** The UID of the application managing the call. Null if there is no active call. */
+        private var callAppUid: Int? = null
+
+        /**
+         * True if this observer is currently registered with the activity manager and false
+         * otherwise.
+         */
+        private var isRegistered = false
+
+
+        /** Register this observer with the activity manager and the given [uid]. */
+        fun registerWithUid(uid: Int) {
+            if (callAppUid == uid) {
+                return
+            }
+            callAppUid = uid
+
+            try {
+                isCallAppVisible = isProcessVisibleToUser(
+                    iActivityManager.getUidProcessState(uid, context.opPackageName)
+                )
+                if (isRegistered) {
+                    return
+                }
+                iActivityManager.registerUidObserver(
+                    uidObserver,
+                    ActivityManager.UID_OBSERVER_PROCSTATE,
+                    ActivityManager.PROCESS_STATE_UNKNOWN,
+                    context.opPackageName
+                )
+                isRegistered = true
+            } catch (se: SecurityException) {
+                Log.e(TAG, "Security exception when trying to set up uid observer: $se")
+            }
+        }
+
+        /** Unregister this observer with the activity manager. */
+        fun unregister() {
+            callAppUid = null
+            isRegistered = false
+            iActivityManager.unregisterUidObserver(uidObserver)
+        }
+
+        override fun onUidStateChanged(
+            uid: Int,
+            procState: Int,
+            procStateSeq: Long,
+            capability: Int
+        ) {
+            val currentCallAppUid = callAppUid ?: return
+            if (uid != currentCallAppUid) {
+                return
+            }
+
+            val oldIsCallAppVisible = isCallAppVisible
+            isCallAppVisible = isProcessVisibleToUser(procState)
+            if (oldIsCallAppVisible != isCallAppVisible) {
+                // Animations may be run as a result of the call's state change, so ensure
+                // the listener is notified on the main thread.
+                mainExecutor.execute {
+                    mListeners.forEach { l -> l.onOngoingCallStateChanged(animate = true) }
+                }
+            }
+        }
+
+        override fun onUidGone(uid: Int, disabled: Boolean) {}
+        override fun onUidActive(uid: Int) {}
+        override fun onUidIdle(uid: Int, disabled: Boolean) {}
+        override fun onUidCachedChanged(uid: Int, cached: Boolean) {}
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 562816f..9e1e87b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -88,10 +88,11 @@
     private boolean mAttached;
     private boolean mScreenReceiverRegistered;
     private Calendar mCalendar;
-    private String mClockFormatString;
+    private String mContentDescriptionFormatString;
     private SimpleDateFormat mClockFormat;
     private SimpleDateFormat mContentDescriptionFormat;
     private Locale mLocale;
+    private DateTimePatternGenerator mDateTimePatternGenerator;
 
     private static final int AM_PM_STYLE_NORMAL  = 0;
     private static final int AM_PM_STYLE_SMALL   = 1;
@@ -196,7 +197,8 @@
 
         // The time zone may have changed while the receiver wasn't registered, so update the Time
         mCalendar = Calendar.getInstance(TimeZone.getDefault());
-        mClockFormatString = "";
+        mContentDescriptionFormatString = "";
+        mDateTimePatternGenerator = null;
 
         // Make sure we update to the current time
         updateClock();
@@ -247,7 +249,9 @@
                 handler.post(() -> {
                     if (!newLocale.equals(mLocale)) {
                         mLocale = newLocale;
-                        mClockFormatString = ""; // force refresh
+                         // Force refresh of dependent variables.
+                        mContentDescriptionFormatString = "";
+                        mDateTimePatternGenerator = null;
                     }
                 });
             }
@@ -367,17 +371,22 @@
     private final CharSequence getSmallTime() {
         Context context = getContext();
         boolean is24 = DateFormat.is24HourFormat(context, mCurrentUserId);
-        DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(
+        if (mDateTimePatternGenerator == null) {
+            // Despite its name, getInstance creates a cloned instance, so reuse the generator to
+            // avoid unnecessary churn.
+            mDateTimePatternGenerator = DateTimePatternGenerator.getInstance(
                 context.getResources().getConfiguration().locale);
+        }
 
         final char MAGIC1 = '\uEF00';
         final char MAGIC2 = '\uEF01';
 
-        SimpleDateFormat sdf;
-        String format = mShowSeconds
-                ? is24 ? dtpg.getBestPattern("Hms") : dtpg.getBestPattern("hms")
-                : is24 ? dtpg.getBestPattern("Hm") : dtpg.getBestPattern("hm");
-        if (!format.equals(mClockFormatString)) {
+        final String formatSkeleton = mShowSeconds
+                ? is24 ? "Hms" : "hms"
+                : is24 ? "Hm" : "hm";
+        String format = mDateTimePatternGenerator.getBestPattern(formatSkeleton);
+        if (!format.equals(mContentDescriptionFormatString)) {
+            mContentDescriptionFormatString = format;
             mContentDescriptionFormat = new SimpleDateFormat(format);
             /*
              * Search for an unquoted "a" in the format string, so we can
@@ -409,12 +418,9 @@
                         + "a" + MAGIC2 + format.substring(b + 1);
                 }
             }
-            mClockFormat = sdf = new SimpleDateFormat(format);
-            mClockFormatString = format;
-        } else {
-            sdf = mClockFormat;
+            mClockFormat = new SimpleDateFormat(format);
         }
-        String result = sdf.format(mCalendar.getTime());
+        String result = mClockFormat.format(mCalendar.getTime());
 
         if (mAmPmStyle != AM_PM_STYLE_NORMAL) {
             int magic1 = result.indexOf(MAGIC1);
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/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index f4e53e2..fa26a35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -76,14 +76,11 @@
 import com.android.systemui.qs.QSUserSwitcherEvent;
 import com.android.systemui.qs.user.UserSwitchDialogController.DialogShower;
 import com.android.systemui.settings.UserTracker;
-import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.user.CreateUserActivity;
 import com.android.systemui.util.settings.SecureSettings;
 
-import dagger.Lazy;
-
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -129,7 +126,6 @@
     private final InteractionJankMonitor mInteractionJankMonitor;
     private final LatencyTracker mLatencyTracker;
     private final DialogLaunchAnimator mDialogLaunchAnimator;
-    private final Lazy<ShadeController> mShadeController;
 
     private ArrayList<UserRecord> mUsers = new ArrayList<>();
     @VisibleForTesting
@@ -178,7 +174,6 @@
             InteractionJankMonitor interactionJankMonitor,
             LatencyTracker latencyTracker,
             DumpManager dumpManager,
-            Lazy<ShadeController> shadeController,
             DialogLaunchAnimator dialogLaunchAnimator) {
         mContext = context;
         mActivityManager = activityManager;
@@ -207,7 +202,6 @@
         mActivityStarter = activityStarter;
         mUserManager = userManager;
         mDialogLaunchAnimator = dialogLaunchAnimator;
-        mShadeController = shadeController;
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_ADDED);
@@ -590,13 +584,6 @@
                 .setPackage(mCreateSupervisedUserPackage)
                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
-        // TODO(b/209659998): [to-be-removed] fallback activity for supervised user creation.
-        if (mContext.getPackageManager().resolveActivity(intent, 0) == null) {
-            intent.setPackage(null)
-                    .setClassName("com.android.settings",
-                        "com.android.settings.users.AddSupervisedUserActivity");
-        }
-
         mContext.startActivity(intent);
     }
 
@@ -861,8 +848,7 @@
     public @UserIdInt int createGuest() {
         UserInfo guest;
         try {
-            guest = mUserManager.createGuest(mContext,
-                    mContext.getString(com.android.settingslib.R.string.guest_nickname));
+            guest = mUserManager.createGuest(mContext);
         } catch (UserManager.UserOperationException e) {
             Log.e(TAG, "Couldn't create guest user", e);
             return UserHandle.USER_NULL;
@@ -996,9 +982,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 {
@@ -1206,8 +1192,12 @@
                 if (ActivityManager.isUserAMonkey()) {
                     return;
                 }
-                mShadeController.get().collapsePanel();
-                getContext().startActivity(CreateUserActivity.createIntentForStart(getContext()));
+                // 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));
+                getContext().startActivityAsUser(
+                        CreateUserActivity.createIntentForStart(getContext()),
+                        mUserTracker.getUserHandle());
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index fb6861d..09298b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -73,6 +73,8 @@
 
     @Override
     public void showPictureInPictureMenu() {
-        mContext.sendBroadcast(new Intent(ACTION_SHOW_PIP_MENU), SYSTEMUI_PERMISSION);
+        mContext.sendBroadcast(
+                new Intent(ACTION_SHOW_PIP_MENU).setPackage(mContext.getPackageName()),
+                SYSTEMUI_PERMISSION);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
index 6f587fd..c53d510 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java
@@ -68,6 +68,7 @@
     private final StatusBarContentInsetsProvider mContentInsetsProvider;
     private int mBarHeight = -1;
     private final State mCurrentState = new State();
+    private boolean mIsAttached;
 
     private final ViewGroup mStatusBarWindowView;
     // The container in which we should run launch animations started from the status bar and
@@ -136,6 +137,8 @@
 
         mContentInsetsProvider.addCallback(this::calculateStatusBarLocationsForAllRotations);
         calculateStatusBarLocationsForAllRotations();
+        mIsAttached = true;
+        apply(mCurrentState);
     }
 
     /** Adds the given view to the status bar window view. */
@@ -282,6 +285,9 @@
     }
 
     private void apply(State state) {
+        if (!mIsAttached) {
+            return;
+        }
         applyForceStatusBarVisibleFlag(state);
         applyHeight(state);
         if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
index 3a14914..60f6df6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.DisplayId
 import com.android.systemui.statusbar.CommandQueue
-import com.android.systemui.statusbar.phone.StatusBar
+import com.android.systemui.statusbar.phone.CentralSurfaces
 import javax.inject.Inject
 
 /**
@@ -80,8 +80,8 @@
         }
 
         windowState = state
-        if (StatusBar.DEBUG_WINDOW_STATE) {
-            Log.d(StatusBar.TAG, "Status bar " + windowStateToString(state))
+        if (CentralSurfaces.DEBUG_WINDOW_STATE) {
+            Log.d(CentralSurfaces.TAG, "Status bar " + windowStateToString(state))
         }
         listeners.forEach { it.onStatusBarWindowStateChanged(state) }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
new file mode 100644
index 0000000..3d07491
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/touch/TouchInsetManager.java
@@ -0,0 +1,197 @@
+/*
+ * 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.touch;
+
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.view.View;
+import android.view.ViewRootImpl;
+
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.concurrent.Executor;
+
+/**
+ * {@link TouchInsetManager} handles setting the touchable inset regions for a given View. This
+ * is useful for passing through touch events for all but select areas.
+ */
+public class TouchInsetManager {
+    /**
+     * {@link TouchInsetSession} provides an individualized session with the
+     * {@link TouchInsetManager}, linking any action to the client.
+     */
+    public static class TouchInsetSession {
+        private final TouchInsetManager mManager;
+
+        private final HashSet<View> mTrackedViews;
+        private final Executor mExecutor;
+
+        private final View.OnLayoutChangeListener mOnLayoutChangeListener =
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
+                        -> updateTouchRegion();
+
+        /**
+         * Default constructor
+         * @param manager The parent {@link TouchInsetManager} which will be affected by actions on
+         *                this session.
+         * @param rootView The parent of views that will be tracked.
+         * @param executor An executor for marshalling operations.
+         */
+        TouchInsetSession(TouchInsetManager manager, Executor executor) {
+            mManager = manager;
+            mTrackedViews = new HashSet<>();
+            mExecutor = executor;
+        }
+
+        /**
+         * Adds a descendant of the root view to be tracked.
+         * @param view {@link View} to be tracked.
+         */
+        public void addViewToTracking(View view) {
+            mExecutor.execute(() -> {
+                mTrackedViews.add(view);
+                view.addOnLayoutChangeListener(mOnLayoutChangeListener);
+                updateTouchRegion();
+            });
+        }
+
+        /**
+         * Removes a view from further tracking
+         * @param view {@link View} to be removed.
+         */
+        public void removeViewFromTracking(View view) {
+            mExecutor.execute(() -> {
+                mTrackedViews.remove(view);
+                view.removeOnLayoutChangeListener(mOnLayoutChangeListener);
+                updateTouchRegion();
+            });
+        }
+
+        private void updateTouchRegion() {
+            final Region cumulativeRegion = Region.obtain();
+
+            mTrackedViews.stream().forEach(view -> {
+                final Rect boundaries = new Rect();
+                view.getBoundsOnScreen(boundaries);
+                cumulativeRegion.op(boundaries, Region.Op.UNION);
+            });
+
+            mManager.setTouchRegion(this, cumulativeRegion);
+
+            cumulativeRegion.recycle();
+        }
+
+        /**
+         * Removes all tracked views and updates insets accordingly.
+         */
+        public void clear() {
+            mExecutor.execute(() -> {
+                mManager.clearRegion(this);
+                mTrackedViews.clear();
+            });
+        }
+    }
+
+    private final HashMap<TouchInsetSession, Region> mDefinedRegions = new HashMap<>();
+    private final Executor mExecutor;
+    private final View mRootView;
+
+    private final View.OnAttachStateChangeListener mAttachListener =
+            new View.OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                    updateTouchInset();
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                }
+            };
+
+    /**
+     * Default constructor.
+     * @param executor An {@link Executor} to marshal all operations on.
+     * @param rootView The root {@link View} for all views in sessions.
+     */
+    public TouchInsetManager(Executor executor, View rootView) {
+        mExecutor = executor;
+        mRootView = rootView;
+        mRootView.addOnAttachStateChangeListener(mAttachListener);
+
+    }
+
+    /**
+     * Creates a new associated session.
+     */
+    public TouchInsetSession createSession() {
+        return new TouchInsetSession(this, mExecutor);
+    }
+
+    /**
+     * Checks to see if the given point coordinates fall within an inset region.
+     */
+    public ListenableFuture<Boolean> checkWithinTouchRegion(int x, int y) {
+        return CallbackToFutureAdapter.getFuture(completer -> {
+            mExecutor.execute(() -> completer.set(
+                    mDefinedRegions.values().stream().anyMatch(region -> region.contains(x, y))));
+
+            return "DreamOverlayTouchMonitor::checkWithinTouchRegion";
+        });
+    }
+
+    private void updateTouchInset() {
+        final ViewRootImpl viewRootImpl = mRootView.getViewRootImpl();
+
+        if (viewRootImpl == null) {
+            return;
+        }
+
+        final Region aggregateRegion = Region.obtain();
+
+        for (Region region : mDefinedRegions.values()) {
+            aggregateRegion.op(region, Region.Op.UNION);
+        }
+
+        viewRootImpl.setTouchableRegion(aggregateRegion);
+
+        aggregateRegion.recycle();
+    }
+
+    protected void setTouchRegion(TouchInsetSession session, Region region) {
+        final Region introducedRegion = Region.obtain(region);
+        mExecutor.execute(() -> {
+            mDefinedRegions.put(session, introducedRegion);
+            updateTouchInset();
+        });
+    }
+
+    private void clearRegion(TouchInsetSession session) {
+        mExecutor.execute(() -> {
+            final Region storedRegion = mDefinedRegions.remove(session);
+
+            if (storedRegion != null) {
+                storedRegion.recycle();
+            }
+
+            updateTouchInset();
+        });
+    }
+}
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/unfold/FoldAodAnimationController.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
index e2374ad..d6dfcea 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
@@ -26,7 +26,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.phone.ScreenOffAnimation
-import com.android.systemui.statusbar.phone.StatusBar
+import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.policy.CallbackController
 import com.android.systemui.unfold.FoldAodAnimationController.FoldAodAnimationStatus
 import com.android.systemui.util.settings.GlobalSettings
@@ -50,7 +50,7 @@
     private val globalSettings: GlobalSettings
 ) : CallbackController<FoldAodAnimationStatus>, ScreenOffAnimation, WakefulnessLifecycle.Observer {
 
-    private lateinit var statusBar: StatusBar
+    private lateinit var mCentralSurfaces: CentralSurfaces
 
     private var isFolded = false
     private var isFoldHandled = true
@@ -66,14 +66,14 @@
     private val statusListeners = arrayListOf<FoldAodAnimationStatus>()
 
     private val startAnimationRunnable = Runnable {
-        statusBar.notificationPanelViewController.startFoldToAodAnimation {
+        mCentralSurfaces.notificationPanelViewController.startFoldToAodAnimation {
             // End action
             setAnimationState(playing = false)
         }
     }
 
-    override fun initialize(statusBar: StatusBar, lightRevealScrim: LightRevealScrim) {
-        this.statusBar = statusBar
+    override fun initialize(centralSurfaces: CentralSurfaces, lightRevealScrim: LightRevealScrim) {
+        this.mCentralSurfaces = centralSurfaces
 
         deviceStateManager.registerCallback(executor, FoldListener())
         wakefulnessLifecycle.addObserver(this)
@@ -88,7 +88,7 @@
             globalSettings.getString(Settings.Global.ANIMATOR_DURATION_SCALE) != "0"
         ) {
             setAnimationState(playing = true)
-            statusBar.notificationPanelViewController.prepareFoldToAodAnimation()
+            mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation()
             true
         } else {
             setAnimationState(playing = false)
@@ -98,7 +98,7 @@
     override fun onStartedWakingUp() {
         if (isAnimationPlaying) {
             handler.removeCallbacks(startAnimationRunnable)
-            statusBar.notificationPanelViewController.cancelFoldToAodAnimation()
+            mCentralSurfaces.notificationPanelViewController.cancelFoldToAodAnimation()
         }
 
         setAnimationState(playing = false)
@@ -131,12 +131,14 @@
             // We should play the folding to AOD animation
 
             setAnimationState(playing = true)
-            statusBar.notificationPanelViewController.prepareFoldToAodAnimation()
+            mCentralSurfaces.notificationPanelViewController.prepareFoldToAodAnimation()
 
             // We don't need to wait for the scrim as it is already displayed
             // but we should wait for the initial animation preparations to be drawn
             // (setting initial alpha/translation)
-            OneShotPreDrawListener.add(statusBar.notificationPanelViewController.view, onReady)
+            OneShotPreDrawListener.add(
+                mCentralSurfaces.notificationPanelViewController.view, onReady
+            )
         } else {
             // No animation, call ready callback immediately
             onReady.run()
diff --git a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
index 14585fb..c0d7925 100644
--- a/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
@@ -35,9 +35,8 @@
 import android.widget.ArrayAdapter
 import android.widget.ImageView
 import android.widget.TextView
-
 import androidx.constraintlayout.helper.widget.Flow
-
+import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.util.UserIcons
 import com.android.settingslib.Utils
 import com.android.systemui.R
@@ -47,12 +46,12 @@
 import com.android.systemui.statusbar.phone.ShadeController
 import com.android.systemui.statusbar.policy.UserSwitcherController
 import com.android.systemui.statusbar.policy.UserSwitcherController.BaseUserAdapter
-import com.android.systemui.statusbar.policy.UserSwitcherController.UserRecord
 import com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA
 import com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA
+import com.android.systemui.statusbar.policy.UserSwitcherController.UserRecord
 import com.android.systemui.util.LifecycleActivity
-
 import javax.inject.Inject
+import kotlin.math.ceil
 
 private const val USER_VIEW = "user_view"
 
@@ -137,6 +136,18 @@
             return UserIcons.getDefaultUserIcon(resources, item.info.id, false)
         }
 
+        fun getTotalUserViews(): Int {
+            return users.count { item ->
+                !doNotRenderUserView(item)
+            }
+        }
+
+        fun doNotRenderUserView(item: UserRecord): Boolean {
+            return item.isAddUser ||
+                    item.isAddSupervisedUser ||
+                    item.isGuest && item.info == null
+        }
+
         private fun getDrawable(item: UserRecord): Drawable {
             var drawable = if (item.isCurrent && item.isGuest) {
                 getDrawable(R.drawable.ic_avatar_guest_user)
@@ -211,7 +222,8 @@
 
         userSwitcherController.init(parent)
         initBroadcastReceiver()
-        buildUserViews()
+
+        parent.post { buildUserViews() }
     }
 
     private fun showPopupMenu() {
@@ -272,16 +284,32 @@
         }
         parent.removeViews(start, count)
         addUserRecords.clear()
-
         val flow = requireViewById<Flow>(R.id.flow)
+        val totalWidth = parent.width
+        val userViewCount = adapter.getTotalUserViews()
+        val maxColumns = getMaxColumns(userViewCount)
+        val horizontalGap = resources
+            .getDimensionPixelSize(R.dimen.user_switcher_fullscreen_horizontal_gap)
+        val totalWidthOfHorizontalGap = (maxColumns - 1) * horizontalGap
+        val maxWidgetDiameter = (totalWidth - totalWidthOfHorizontalGap) / maxColumns
+
+        flow.setMaxElementsWrap(maxColumns)
+
         for (i in 0 until adapter.getCount()) {
             val item = adapter.getItem(i)
-            if (item.isAddUser ||
-                item.isAddSupervisedUser ||
-                item.isGuest && item.info == null) {
+            if (adapter.doNotRenderUserView(item)) {
                 addUserRecords.add(item)
             } else {
                 val userView = adapter.getView(i, null, parent)
+                userView.requireViewById<ImageView>(R.id.user_switcher_icon).apply {
+                    val lp = layoutParams
+                    if (maxWidgetDiameter < lp.width) {
+                        lp.width = maxWidgetDiameter
+                        lp.height = maxWidgetDiameter
+                        layoutParams = lp
+                    }
+                }
+
                 userView.setId(View.generateViewId())
                 parent.addView(userView)
 
@@ -333,6 +361,11 @@
         broadcastDispatcher.registerReceiver(broadcastReceiver, filter)
     }
 
+    @VisibleForTesting
+    fun getMaxColumns(userCount: Int): Int {
+        return if (userCount < 5) 4 else ceil(userCount / 2.0).toInt()
+    }
+
     private class ItemAdapter(
         val parentContext: Context,
         val resource: Int,
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/util/view/ViewUtil.kt b/packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
new file mode 100644
index 0000000..613a797
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
@@ -0,0 +1,26 @@
+package com.android.systemui.util.view
+
+import android.view.View
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+/**
+ * A class with generic view utility methods.
+ *
+ * Doesn't use static methods so that it can be easily mocked out in tests.
+ */
+@SysUISingleton
+class ViewUtil @Inject constructor() {
+    /**
+     * Returns true if the given (x, y) point (in screen coordinates) is within the status bar
+     * view's range and false otherwise.
+     */
+    fun touchIsWithinView(view: View, x: Float, y: Float): Boolean {
+        val left = view.locationOnScreen[0]
+        val top = view.locationOnScreen[1]
+        return left <= x &&
+                x <= left + view.width &&
+                top <= y &&
+                y <= top + view.height
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
index 1862ed3..ae23ca6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
@@ -28,14 +28,11 @@
 import com.android.keyguard.AlphaOptimizedImageButton;
 import com.android.systemui.R;
 
-/** Toggle button in Volume Dialog that allows extra state for when streams are opted-out */
+/** Toggle button in Volume Dialog for controlling system captions state */
 public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
 
-    private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut };
-
     private ConfirmedTapListener mConfirmedTapListener;
     private boolean mCaptionsEnabled = false;
-    private boolean mOptedOut = false;
 
     private GestureDetector mGestureDetector;
     private GestureDetector.SimpleOnGestureListener mGestureListener =
@@ -60,11 +57,7 @@
 
     @Override
     public int[] onCreateDrawableState(int extraSpace) {
-        int[] state = super.onCreateDrawableState(extraSpace + 1);
-        if (mOptedOut) {
-            mergeDrawableStates(state, OPTED_OUT_STATE);
-        }
-        return state;
+        return super.onCreateDrawableState(extraSpace + 1);
     }
 
     Runnable setCaptionsEnabled(boolean areCaptionsEnabled) {
@@ -95,16 +88,6 @@
         return this.mCaptionsEnabled;
     }
 
-    /** Sets whether or not the current stream has opted out of captions */
-    void setOptedOut(boolean isOptedOut) {
-        this.mOptedOut = isOptedOut;
-        refreshDrawableState();
-    }
-
-    boolean getOptedOut() {
-        return this.mOptedOut;
-    }
-
     void setOnConfirmedTapListener(ConfirmedTapListener listener, Handler handler) {
         mConfirmedTapListener = listener;
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 57c7f11..85a6eeb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -54,6 +54,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.CaptioningManager;
 
 import androidx.lifecycle.Observer;
 
@@ -130,6 +131,7 @@
     private final Receiver mReceiver = new Receiver();
     private final RingerModeObservers mRingerModeObservers;
     private final MediaSessions mMediaSessions;
+    private final CaptioningManager mCaptioningManager;
     protected C mCallbacks = new C();
     private final State mState = new State();
     protected final MediaSessionsCallbacks mMediaSessionsCallbacksW;
@@ -175,7 +177,8 @@
             IAudioService iAudioService,
             AccessibilityManager accessibilityManager,
             PackageManager packageManager,
-            WakefulnessLifecycle wakefulnessLifecycle) {
+            WakefulnessLifecycle wakefulnessLifecycle,
+            CaptioningManager captioningManager) {
         mContext = context.getApplicationContext();
         mPackageManager = packageManager;
         mWakefulnessLifecycle = wakefulnessLifecycle;
@@ -200,6 +203,7 @@
         mVibrator = vibrator;
         mHasVibrator = mVibrator.hasVibrator();
         mAudioService = iAudioService;
+        mCaptioningManager = captioningManager;
 
         boolean accessibilityVolumeStreamActive = accessibilityManager
                 .isAccessibilityVolumeStreamActive();
@@ -307,20 +311,11 @@
     }
 
     public boolean areCaptionsEnabled() {
-        int currentValue = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.ODI_CAPTIONS_ENABLED, 0, UserHandle.USER_CURRENT);
-        return currentValue == 1;
+        return mCaptioningManager.isSystemAudioCaptioningEnabled();
     }
 
     public void setCaptionsEnabled(boolean isEnabled) {
-        Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0, UserHandle.USER_CURRENT);
-    }
-
-    @Override
-    public boolean isCaptionStreamOptedOut() {
-        // TODO(b/129768185): Removing secure setting, to be replaced by sound event listener
-        return false;
+        mCaptioningManager.setSystemAudioCaptioningEnabled(isEnabled);
     }
 
     public void getCaptionsComponentState(boolean fromTooltip) {
@@ -423,6 +418,13 @@
     }
 
     private void onGetCaptionsComponentStateW(boolean fromTooltip) {
+        if (mCaptioningManager.isSystemAudioCaptioningUiEnabled()) {
+            mCallbacks.onCaptionComponentStateChanged(true, fromTooltip);
+            return;
+        }
+
+        // TODO(b/220968335): Remove this check once system captions component migrates
+        // to new CaptioningManager APIs.
         try {
             String componentNameString = mContext.getString(
                     com.android.internal.R.string.config_defaultSystemCaptionsService);
@@ -460,11 +462,15 @@
     private boolean checkRoutedToBluetoothW(int stream) {
         boolean changed = false;
         if (stream == AudioManager.STREAM_MUSIC) {
+            // Note: Here we didn't use DEVICE_OUT_BLE_SPEAKER and DEVICE_OUT_BLE_BROADCAST
+            //       Since their values overlap with DEVICE_OUT_EARPIECE and DEVICE_OUT_SPEAKER.
+            //       Anyway, we can check BLE devices by using just DEVICE_OUT_BLE_HEADSET.
             final boolean routedToBluetooth =
                     (mAudio.getDevicesForStream(AudioManager.STREAM_MUSIC) &
                             (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
                             AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
-                            AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0;
+                            AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
+                            AudioManager.DEVICE_OUT_BLE_HEADSET)) != 0;
             changed |= updateStreamRoutedToBluetoothW(stream, routedToBluetooth);
         }
         return changed;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 58f74a0..bfdcbd6 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -1180,11 +1180,6 @@
         if (mODICaptionsIcon.getCaptionsEnabled() != captionsEnabled) {
             mHandler.post(mODICaptionsIcon.setCaptionsEnabled(captionsEnabled));
         }
-
-        boolean isOptedOut = mController.isCaptionStreamOptedOut();
-        if (mODICaptionsIcon.getOptedOut() != isOptedOut) {
-            mHandler.post(() -> mODICaptionsIcon.setOptedOut(isOptedOut));
-        }
     }
 
     private void onCaptionIconClicked() {
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 b2a79b0..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;
@@ -58,7 +59,6 @@
 import com.android.wm.shell.compatui.CompatUI;
 import com.android.wm.shell.draganddrop.DragAndDrop;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.nano.WmShellTraceProto;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.onehanded.OneHandedEventCallback;
@@ -108,7 +108,6 @@
 
     // Shell interfaces
     private final Optional<Pip> mPipOptional;
-    private final Optional<LegacySplitScreen> mLegacySplitScreenOptional;
     private final Optional<SplitScreen> mSplitScreenOptional;
     private final Optional<OneHanded> mOneHandedOptional;
     private final Optional<HideDisplayCutout> mHideDisplayCutoutOptional;
@@ -118,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;
@@ -128,17 +128,15 @@
     private final Executor mSysUiMainExecutor;
 
     private boolean mIsSysUiStateValid;
-    private KeyguardUpdateMonitorCallback mLegacySplitScreenKeyguardCallback;
     private KeyguardUpdateMonitorCallback mSplitScreenKeyguardCallback;
     private KeyguardUpdateMonitorCallback mPipKeyguardCallback;
     private KeyguardUpdateMonitorCallback mOneHandedKeyguardCallback;
-    private KeyguardUpdateMonitorCallback mCompatUIKeyguardCallback;
+    private KeyguardStateController.Callback mCompatUIKeyguardCallback;
     private WakefulnessLifecycle.Observer mWakefulnessObserver;
 
     @Inject
     public WMShell(Context context,
             Optional<Pip> pipOptional,
-            Optional<LegacySplitScreen> legacySplitScreenOptional,
             Optional<SplitScreen> splitScreenOptional,
             Optional<OneHanded> oneHandedOptional,
             Optional<HideDisplayCutout> hideDisplayCutoutOptional,
@@ -147,6 +145,7 @@
             Optional<DragAndDrop> dragAndDropOptional,
             CommandQueue commandQueue,
             ConfigurationController configurationController,
+            KeyguardStateController keyguardStateController,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
             NavigationModeController navigationModeController,
             ScreenLifecycle screenLifecycle,
@@ -158,12 +157,12 @@
         super(context);
         mCommandQueue = commandQueue;
         mConfigurationController = configurationController;
+        mKeyguardStateController = keyguardStateController;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mNavigationModeController = navigationModeController;
         mScreenLifecycle = screenLifecycle;
         mSysUiState = sysUiState;
         mPipOptional = pipOptional;
-        mLegacySplitScreenOptional = legacySplitScreenOptional;
         mSplitScreenOptional = splitScreenOptional;
         mOneHandedOptional = oneHandedOptional;
         mHideDisplayCutoutOptional = hideDisplayCutoutOptional;
@@ -183,7 +182,6 @@
         mProtoTracer.add(this);
         mCommandQueue.addCallback(this);
         mPipOptional.ifPresent(this::initPip);
-        mLegacySplitScreenOptional.ifPresent(this::initLegacySplitScreen);
         mSplitScreenOptional.ifPresent(this::initSplitScreen);
         mOneHandedOptional.ifPresent(this::initOneHanded);
         mHideDisplayCutoutOptional.ifPresent(this::initHideDisplayCutout);
@@ -238,21 +236,6 @@
     }
 
     @VisibleForTesting
-    void initLegacySplitScreen(LegacySplitScreen legacySplitScreen) {
-        mLegacySplitScreenKeyguardCallback = new KeyguardUpdateMonitorCallback() {
-            @Override
-            public void onKeyguardVisibilityChanged(boolean showing) {
-                // Hide the divider when keyguard is showing. Even though keyguard/statusbar is
-                // above everything, it is actually transparent except for notifications, so
-                // we still need to hide any surfaces that are below it.
-                // TODO(b/148906453): Figure out keyguard dismiss animation for divider view.
-                legacySplitScreen.onKeyguardVisibilityChanged(showing);
-            }
-        };
-        mKeyguardUpdateMonitor.registerCallback(mLegacySplitScreenKeyguardCallback);
-    }
-
-    @VisibleForTesting
     void initSplitScreen(SplitScreen splitScreen) {
         mSplitScreenKeyguardCallback = new KeyguardUpdateMonitorCallback() {
             @Override
@@ -383,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/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index 8e1e42a..e980eb7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -88,6 +88,6 @@
     fun onPause_clearsTextField() {
         mKeyguardPatternViewController.init()
         mKeyguardPatternViewController.onPause()
-        verify(mKeyguardMessageAreaController).setMessage("")
+        verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index 217092e..2fc9122 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,
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/ScreenDecorHwcLayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
new file mode 100644
index 0000000..95aa08d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
@@ -0,0 +1,182 @@
+/*
+ * 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
+
+import android.graphics.Insets
+import android.graphics.PixelFormat
+import android.graphics.Rect
+import android.graphics.RectF
+import android.hardware.graphics.common.DisplayDecorationSupport
+import android.testing.AndroidTestingRunner
+import android.view.Display
+import android.view.DisplayCutout
+import android.view.DisplayInfo
+import android.view.View
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.systemui.util.mockito.eq
+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.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ScreenDecorHwcLayerTest : SysuiTestCase() {
+
+    @Mock private lateinit var mockDisplay: Display
+    @Mock private lateinit var mockRootView: View
+
+    private val displayWidth = 100
+    private val displayHeight = 200
+    private val cutoutSize = 10
+    private val roundedSizeTop = 15
+    private val roundedSizeBottom = 20
+
+    private lateinit var decorHwcLayer: ScreenDecorHwcLayer
+    private val cutoutTop: DisplayCutout = DisplayCutout.Builder()
+        .setSafeInsets(Insets.of(0, cutoutSize, 0, 0))
+        .setBoundingRectTop(Rect(1, 0, 2, cutoutSize))
+        .build()
+
+    private val cutoutRight: DisplayCutout = DisplayCutout.Builder()
+        .setSafeInsets(Insets.of(0, 0, cutoutSize, 0))
+        .setBoundingRectRight(Rect(displayWidth - cutoutSize, 50, displayWidth, 52))
+        .build()
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mContext.orCreateTestableResources.addOverride(
+            R.array.config_displayUniqueIdArray, arrayOf<String>())
+        mContext.orCreateTestableResources.addOverride(
+            R.bool.config_fillMainBuiltInDisplayCutout, true)
+
+        val decorationSupport = DisplayDecorationSupport()
+        decorationSupport.format = PixelFormat.R_8
+        decorHwcLayer = Mockito.spy(ScreenDecorHwcLayer(mContext, decorationSupport))
+        whenever(decorHwcLayer.width).thenReturn(displayWidth)
+        whenever(decorHwcLayer.height).thenReturn(displayHeight)
+        whenever(decorHwcLayer.display).thenReturn(mockDisplay)
+        whenever(decorHwcLayer.rootView).thenReturn(mockRootView)
+        whenever(mockRootView.left).thenReturn(0)
+        whenever(mockRootView.top).thenReturn(0)
+        whenever(mockRootView.right).thenReturn(displayWidth)
+        whenever(mockRootView.bottom).thenReturn(displayHeight)
+    }
+
+    @Test
+    fun testTransparentRegion_noCutout_noRoundedCorner_noProtection() {
+        setupConfigs(null, 0, 0, RectF(), 0f)
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(0, 0, decorHwcLayer.width, decorHwcLayer.height))
+    }
+
+    @Test
+    fun testTransparentRegion_onlyShortEdgeCutout() {
+        setupConfigs(cutoutTop, 0, 0, RectF(), 0f)
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(0, cutoutSize, decorHwcLayer.width, decorHwcLayer.height))
+    }
+
+    @Test
+    fun testTransparentRegion_onlyLongEdgeCutout() {
+        setupConfigs(cutoutRight, 0, 0, RectF(), 0f)
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(0, 0, decorHwcLayer.width - cutoutSize, decorHwcLayer.height))
+    }
+
+    @Test
+    fun testTransparentRegion_onlyRoundedCorners() {
+        setupConfigs(null, roundedSizeTop, roundedSizeBottom, RectF(), 0f)
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(0, roundedSizeTop, decorHwcLayer.width,
+                decorHwcLayer.height - roundedSizeBottom))
+    }
+
+    @Test
+    fun testTransparentRegion_onlyCutoutProtection() {
+        setupConfigs(null, 0, 0, RectF(48f, 1f, 52f, 5f), 0.5f)
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(0, 4, decorHwcLayer.width, decorHwcLayer.height))
+
+        decorHwcLayer.cameraProtectionProgress = 1f
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(0, 5, decorHwcLayer.width, decorHwcLayer.height))
+    }
+
+    @Test
+    fun testTransparentRegion_hasShortEdgeCutout_hasRoundedCorner_hasCutoutProtection() {
+        setupConfigs(cutoutTop, roundedSizeTop, roundedSizeBottom, RectF(48f, 1f, 52f, 5f), 1f)
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(0, 15, decorHwcLayer.width, decorHwcLayer.height - 20))
+    }
+
+    @Test
+    fun testTransparentRegion_hasLongEdgeCutout_hasRoundedCorner_hasCutoutProtection() {
+        setupConfigs(cutoutRight, roundedSizeTop, roundedSizeBottom, RectF(48f, 1f, 52f, 5f), 1f)
+
+        decorHwcLayer.calculateTransparentRect()
+
+        assertThat(decorHwcLayer.transparentRect)
+            .isEqualTo(Rect(20, 5, decorHwcLayer.width - 20, decorHwcLayer.height))
+    }
+
+    private fun setupConfigs(
+        cutout: DisplayCutout?,
+        roundedTop: Int,
+        roundedBottom: Int,
+        protectionRect: RectF,
+        protectionProgress: Float
+    ) {
+        whenever(mockDisplay.getDisplayInfo(eq(decorHwcLayer.displayInfo))
+        ).then {
+            val info = it.getArgument<DisplayInfo>(0)
+            info.displayCutout = cutout
+            return@then true
+        }
+        decorHwcLayer.updateRoundedCornerSize(roundedTop, roundedBottom)
+        decorHwcLayer.protectionRect.set(protectionRect)
+        decorHwcLayer.cameraProtectionProgress = protectionProgress
+        decorHwcLayer.updateCutout()
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
index 796af11..58b4af4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/IWindowMagnificationConnectionTest.java
@@ -134,6 +134,16 @@
     }
 
     @Test
+    public void moveWindowMagnifierToPosition() throws RemoteException {
+        mIWindowMagnificationConnection.moveWindowMagnifierToPosition(TEST_DISPLAY,
+                100f, 200f, mAnimationCallback);
+        waitForIdleSync();
+
+        verify(mWindowMagnificationController).moveWindowMagnifierToPosition(
+                eq(100f), eq(200f), any(IRemoteMagnificationAnimationCallback.class));
+    }
+
+    @Test
     public void showMagnificationButton() throws RemoteException {
         mIWindowMagnificationConnection.showMagnificationButton(TEST_DISPLAY,
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MockMagnificationAnimationCallback.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MockMagnificationAnimationCallback.java
new file mode 100644
index 0000000..30bff09
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MockMagnificationAnimationCallback.java
@@ -0,0 +1,54 @@
+/*
+ * 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.accessibility;
+
+import android.os.RemoteException;
+import android.view.accessibility.IRemoteMagnificationAnimationCallback;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MockMagnificationAnimationCallback extends IRemoteMagnificationAnimationCallback.Stub {
+
+    private final CountDownLatch mCountDownLatch;
+    private final AtomicInteger mSuccessCount;
+    private final AtomicInteger mFailedCount;
+
+    MockMagnificationAnimationCallback(CountDownLatch countDownLatch) {
+        mCountDownLatch = countDownLatch;
+        mSuccessCount = new AtomicInteger();
+        mFailedCount = new AtomicInteger();
+    }
+
+    public int getSuccessCount() {
+        return mSuccessCount.get();
+    }
+
+    public int getFailedCount() {
+        return mFailedCount.get();
+    }
+
+    @Override
+    public void onResult(boolean success) throws RemoteException {
+        mCountDownLatch.countDown();
+        if (success) {
+            mSuccessCount.getAndIncrement();
+        } else {
+            mFailedCount.getAndIncrement();
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index 3cc177d..21c3d6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -60,6 +60,8 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
 @Ignore
@@ -218,6 +220,29 @@
     }
 
     @Test
+    public void enableWindowMagnificationWithUnchanged_enabling_expectedValuesToDefault()
+            throws InterruptedException {
+        final CountDownLatch countDownLatch = new CountDownLatch(2);
+        final MockMagnificationAnimationCallback animationCallback =
+                new MockMagnificationAnimationCallback(countDownLatch);
+
+        enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
+                animationCallback);
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    mWindowMagnificationAnimationController.enableWindowMagnification(Float.NaN,
+                            Float.NaN, Float.NaN, animationCallback);
+                });
+
+        assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
+        // The callback in 2nd enableWindowMagnification will return true
+        assertEquals(1, animationCallback.getSuccessCount());
+        // The callback in 1st enableWindowMagnification will return false
+        assertEquals(1, animationCallback.getFailedCount());
+        verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X, DEFAULT_CENTER_Y);
+    }
+
+    @Test
     public void enableWindowMagnificationWithScaleOne_enabled_AnimationAndInvokeCallback()
             throws RemoteException {
         enableWindowMagnificationWithoutAnimation();
@@ -425,6 +450,102 @@
     }
 
     @Test
+    public void moveWindowMagnifierToPosition_enabled_expectedValues()
+            throws InterruptedException {
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        final MockMagnificationAnimationCallback animationCallback =
+                new MockMagnificationAnimationCallback(countDownLatch);
+        final float targetCenterX = DEFAULT_CENTER_X + 100;
+        final float targetCenterY = DEFAULT_CENTER_Y + 100;
+        enableWindowMagnificationWithoutAnimation();
+
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
+                    targetCenterX, targetCenterY, animationCallback);
+        });
+
+        assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
+        assertEquals(1, animationCallback.getSuccessCount());
+        assertEquals(0, animationCallback.getFailedCount());
+        verifyFinalSpec(DEFAULT_SCALE, targetCenterX, targetCenterY);
+    }
+
+    @Test
+    public void moveWindowMagnifierToPositionMultipleTimes_enabled_expectedValuesToLastOne()
+            throws InterruptedException {
+        final CountDownLatch countDownLatch = new CountDownLatch(4);
+        final MockMagnificationAnimationCallback animationCallback =
+                new MockMagnificationAnimationCallback(countDownLatch);
+        enableWindowMagnificationWithoutAnimation();
+
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
+                    DEFAULT_CENTER_X + 10, DEFAULT_CENTER_Y + 10, animationCallback);
+            mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
+                    DEFAULT_CENTER_X + 20, DEFAULT_CENTER_Y + 20, animationCallback);
+            mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
+                    DEFAULT_CENTER_X + 30, DEFAULT_CENTER_Y + 30, animationCallback);
+            mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
+                    DEFAULT_CENTER_X + 40, DEFAULT_CENTER_Y + 40, animationCallback);
+        });
+
+        assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
+        // only the last one callback will return true
+        assertEquals(1, animationCallback.getSuccessCount());
+        // the others will return false
+        assertEquals(3, animationCallback.getFailedCount());
+        verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X + 40, DEFAULT_CENTER_Y + 40);
+    }
+
+    @Test
+    public void moveWindowMagnifierToPosition_enabling_expectedValuesToLastOne()
+            throws InterruptedException {
+        final CountDownLatch countDownLatch = new CountDownLatch(2);
+        final MockMagnificationAnimationCallback animationCallback =
+                new MockMagnificationAnimationCallback(countDownLatch);
+        final float targetCenterX = DEFAULT_CENTER_X + 100;
+        final float targetCenterY = DEFAULT_CENTER_Y + 100;
+
+        enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
+                animationCallback);
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
+                            targetCenterX, targetCenterY, animationCallback);
+                });
+
+        assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
+        // The callback in moveWindowMagnifierToPosition will return true
+        assertEquals(1, animationCallback.getSuccessCount());
+        // The callback in enableWindowMagnification will return false
+        assertEquals(1, animationCallback.getFailedCount());
+        verifyFinalSpec(DEFAULT_SCALE, targetCenterX, targetCenterY);
+    }
+
+    @Test
+    public void moveWindowMagnifierToPositionWithCenterUnchanged_enabling_expectedValuesToDefault()
+            throws InterruptedException {
+        final CountDownLatch countDownLatch = new CountDownLatch(2);
+        final MockMagnificationAnimationCallback animationCallback =
+                new MockMagnificationAnimationCallback(countDownLatch);
+
+        enableWindowMagnificationAndWaitAnimating(mWaitIntermediateAnimationPeriod,
+                animationCallback);
+        mInstrumentation.runOnMainSync(
+                () -> {
+                    mWindowMagnificationAnimationController.moveWindowMagnifierToPosition(
+                            Float.NaN, Float.NaN, animationCallback);
+                });
+
+        assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
+        // The callback in moveWindowMagnifierToPosition will return true
+        assertEquals(1, animationCallback.getSuccessCount());
+        // The callback in enableWindowMagnification will return false
+        assertEquals(1, animationCallback.getFailedCount());
+        verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X, DEFAULT_CENTER_Y);
+    }
+
+    @Test
     public void enableWindowMagnificationWithSameScale_enabled_doNothingButInvokeCallback()
             throws RemoteException {
         enableWindowMagnificationAndWaitAnimating(mWaitingAnimationPeriod, null);
@@ -569,6 +690,20 @@
         verifyFinalSpec(DEFAULT_SCALE, DEFAULT_CENTER_X + 100f, DEFAULT_CENTER_Y + 100f);
     }
 
+    @Test
+    public void moveWindowMagnifierToPosition_enabled() {
+        final float targetCenterX = DEFAULT_CENTER_X + 100;
+        final float targetCenterY = DEFAULT_CENTER_Y + 100;
+        enableWindowMagnificationWithoutAnimation();
+
+        mInstrumentation.runOnMainSync(
+                () -> mController.moveWindowMagnifierToPosition(targetCenterX, targetCenterY,
+                        mAnimationCallback));
+        SystemClock.sleep(mWaitingAnimationPeriod);
+
+        verifyFinalSpec(DEFAULT_SCALE, targetCenterX, targetCenterY);
+    }
+
     private void verifyFinalSpec(float expectedScale, float expectedCenterX,
             float expectedCenterY) {
         assertEquals(expectedScale, mController.getScale(), 0f);
@@ -663,6 +798,13 @@
         }
 
         @Override
+        void moveWindowMagnifierToPosition(float positionX, float positionY,
+                IRemoteMagnificationAnimationCallback callback) {
+            super.moveWindowMagnifierToPosition(positionX, positionY, callback);
+            mSpyController.moveWindowMagnifierToPosition(positionX, positionY, callback);
+        }
+
+        @Override
         void setScale(float scale) {
             super.setScale(scale);
             mSpyController.setScale(scale);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 6e5926d..a49c4d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -40,6 +40,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -88,6 +89,8 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
 @LargeTest
@@ -96,12 +99,16 @@
 public class WindowMagnificationControllerTest extends SysuiTestCase {
 
     private static final int LAYOUT_CHANGE_TIMEOUT_MS = 5000;
+    private static final long ANIMATION_DURATION_MS = 300;
+    private final long mWaitingAnimationPeriod = 2 * ANIMATION_DURATION_MS;
     @Mock
     private SfVsyncFrameCallbackProvider mSfVsyncFrameProvider;
     @Mock
     private MirrorWindowControl mMirrorWindowControl;
     @Mock
     private WindowMagnifierCallback mWindowMagnifierCallback;
+    @Mock
+    IRemoteMagnificationAnimationCallback mAnimationCallback;
     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
 
@@ -287,6 +294,82 @@
     }
 
     @Test
+    public void moveWindowMagnifierToPositionWithAnimation_expectedValuesAndInvokeCallback()
+            throws InterruptedException {
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
+                    Float.NaN, 0, 0, null);
+        });
+        final CountDownLatch countDownLatch = new CountDownLatch(1);
+        final MockMagnificationAnimationCallback animationCallback =
+                new MockMagnificationAnimationCallback(countDownLatch);
+        final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
+        verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
+                .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
+        final float targetCenterX = sourceBoundsCaptor.getValue().exactCenterX() + 10;
+        final float targetCenterY = sourceBoundsCaptor.getValue().exactCenterY() + 10;
+
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.moveWindowMagnifierToPosition(
+                    targetCenterX, targetCenterY, animationCallback);
+        });
+
+        assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
+        assertEquals(1, animationCallback.getSuccessCount());
+        assertEquals(0, animationCallback.getFailedCount());
+        verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
+                .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
+        assertEquals(mWindowMagnificationController.getCenterX(),
+                sourceBoundsCaptor.getValue().exactCenterX(), 0);
+        assertEquals(mWindowMagnificationController.getCenterY(),
+                sourceBoundsCaptor.getValue().exactCenterY(), 0);
+        assertEquals(mWindowMagnificationController.getCenterX(), targetCenterX, 0);
+        assertEquals(mWindowMagnificationController.getCenterY(), targetCenterY, 0);
+    }
+
+    @Test
+    public void moveWindowMagnifierToPositionMultipleTimes_expectedValuesAndInvokeCallback()
+            throws InterruptedException {
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.enableWindowMagnification(Float.NaN, Float.NaN,
+                    Float.NaN, 0, 0, null);
+        });
+        final CountDownLatch countDownLatch = new CountDownLatch(4);
+        final MockMagnificationAnimationCallback animationCallback =
+                new MockMagnificationAnimationCallback(countDownLatch);
+        final ArgumentCaptor<Rect> sourceBoundsCaptor = ArgumentCaptor.forClass(Rect.class);
+        verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
+                .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
+        final float centerX = sourceBoundsCaptor.getValue().exactCenterX();
+        final float centerY = sourceBoundsCaptor.getValue().exactCenterY();
+
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.moveWindowMagnifierToPosition(
+                    centerX + 10, centerY + 10, animationCallback);
+            mWindowMagnificationController.moveWindowMagnifierToPosition(
+                    centerX + 20, centerY + 20, animationCallback);
+            mWindowMagnificationController.moveWindowMagnifierToPosition(
+                    centerX + 30, centerY + 30, animationCallback);
+            mWindowMagnificationController.moveWindowMagnifierToPosition(
+                    centerX + 40, centerY + 40, animationCallback);
+        });
+
+        assertTrue(countDownLatch.await(mWaitingAnimationPeriod, TimeUnit.MILLISECONDS));
+        // only the last one callback will return true
+        assertEquals(1, animationCallback.getSuccessCount());
+        // the others will return false
+        assertEquals(3, animationCallback.getFailedCount());
+        verify(mWindowMagnifierCallback, timeout(LAYOUT_CHANGE_TIMEOUT_MS))
+                .onSourceBoundsChanged((eq(mContext.getDisplayId())), sourceBoundsCaptor.capture());
+        assertEquals(mWindowMagnificationController.getCenterX(),
+                sourceBoundsCaptor.getValue().exactCenterX(), 0);
+        assertEquals(mWindowMagnificationController.getCenterY(),
+                sourceBoundsCaptor.getValue().exactCenterY(), 0);
+        assertEquals(mWindowMagnificationController.getCenterX(), centerX + 40, 0);
+        assertEquals(mWindowMagnificationController.getCenterY(), centerY + 40, 0);
+    }
+
+    @Test
     public void setScale_enabled_expectedValueAndUpdateStateDescription() {
         mInstrumentation.runOnMainSync(
                 () -> mWindowMagnificationController.enableWindowMagnificationInternal(2.0f,
@@ -484,6 +567,7 @@
                 mirrorView.performAccessibilityAction(R.id.accessibility_action_move_right, null));
         assertTrue(
                 mirrorView.performAccessibilityAction(R.id.accessibility_action_move_left, null));
+        verify(mWindowMagnifierCallback, times(4)).onMove(eq(displayId));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
index d3f30c50..ccf2f8b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationTest.java
@@ -148,13 +148,13 @@
     }
 
     @Test
-    public void onDrag_enabled_notifyCallback() throws RemoteException {
+    public void onMove_enabled_notifyCallback() throws RemoteException {
         mCommandQueue.requestWindowMagnificationConnection(true);
         waitForIdleSync();
 
-        mWindowMagnification.onDrag(TEST_DISPLAY);
+        mWindowMagnification.onMove(TEST_DISPLAY);
 
-        verify(mConnectionCallback).onDrag(TEST_DISPLAY);
+        verify(mConnectionCallback).onMove(TEST_DISPLAY);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java
deleted file mode 100644
index 619d48d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceToFingerprintViewTest.java
+++ /dev/null
@@ -1,344 +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.biometrics;
-
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
-import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.hardware.biometrics.ComponentInfoInternal;
-import android.hardware.biometrics.SensorLocationInternal;
-import android.hardware.biometrics.SensorProperties;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.os.Bundle;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class AuthBiometricFaceToFingerprintViewTest extends SysuiTestCase {
-
-    @Mock AuthBiometricView.Callback mCallback;
-
-    private AuthBiometricFaceToFingerprintView mFaceToFpView;
-
-    @Mock private Button mNegativeButton;
-    @Mock private Button mCancelButton;
-    @Mock private Button mConfirmButton;
-    @Mock private Button mUseCredentialButton;
-    @Mock private Button mTryAgainButton;
-
-    @Mock private TextView mTitleView;
-    @Mock private TextView mSubtitleView;
-    @Mock private TextView mDescriptionView;
-    @Mock private TextView mIndicatorView;
-    @Mock private ImageView mIconView;
-    @Mock private View mIconHolderView;
-    @Mock private AuthBiometricFaceView.IconController mFaceIconController;
-    @Mock private AuthBiometricFaceToFingerprintView.UdfpsIconController mUdfpsIconController;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        mFaceToFpView = new TestableView(mContext);
-        mFaceToFpView.mFaceIconController = mFaceIconController;
-        mFaceToFpView.mUdfpsIconController = mUdfpsIconController;
-        mFaceToFpView.setCallback(mCallback);
-
-        mFaceToFpView.mNegativeButton = mNegativeButton;
-        mFaceToFpView.mCancelButton = mCancelButton;
-        mFaceToFpView.mUseCredentialButton = mUseCredentialButton;
-        mFaceToFpView.mConfirmButton = mConfirmButton;
-        mFaceToFpView.mTryAgainButton = mTryAgainButton;
-        mFaceToFpView.mIndicatorView = mIndicatorView;
-    }
-
-    @Test
-    public void testStateUpdated_whenDialogAnimatedIn() {
-        mFaceToFpView.onDialogAnimatedIn();
-        verify(mFaceToFpView.mFaceIconController)
-                .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
-        verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt());
-    }
-
-    @Test
-    public void testIconUpdatesState_whenDialogStateUpdated() {
-        mFaceToFpView.onDialogAnimatedIn();
-        verify(mFaceToFpView.mFaceIconController)
-                .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
-        verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt());
-
-        mFaceToFpView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATED);
-        verify(mFaceToFpView.mFaceIconController).updateState(
-                eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING),
-                eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATED));
-        verify(mFaceToFpView.mUdfpsIconController, never()).updateState(anyInt());
-
-        assertEquals(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATED, mFaceToFpView.mState);
-    }
-
-    @Test
-    public void testStateUpdated_whenSwitchToFingerprint() {
-        mFaceToFpView.onDialogAnimatedIn();
-        verify(mFaceToFpView.mFaceIconController)
-                .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
-
-        mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_ERROR);
-
-        verify(mFaceToFpView.mFaceIconController).deactivate();
-        verify(mFaceToFpView.mUdfpsIconController).updateState(
-                eq(AuthBiometricFaceToFingerprintView.STATE_IDLE));
-        verify(mConfirmButton).setVisibility(eq(View.GONE));
-
-        mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
-
-        verify(mFaceToFpView.mUdfpsIconController).updateState(
-                eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
-    }
-
-    @Test
-    public void testStateUpdated_whenSwitchToFingerprint_invokesCallbacks() {
-        class TestModalityListener implements ModalityListener {
-            public int switchCount = 0;
-
-            @Override
-            public void onModalitySwitched(int oldModality, int newModality) {
-                assertEquals(TYPE_FINGERPRINT, newModality);
-                assertEquals(TYPE_FACE, oldModality);
-                switchCount++;
-            }
-        }
-        final TestModalityListener modalityListener = new TestModalityListener();
-
-        mFaceToFpView.onDialogAnimatedIn();
-        mFaceToFpView.setModalityListener(modalityListener);
-
-        assertEquals(0, modalityListener.switchCount);
-
-        mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_ERROR);
-        mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
-
-        assertEquals(1, modalityListener.switchCount);
-    }
-
-    @Test
-    @Ignore("flaky, b/189031816")
-    public void testModeUpdated_onSoftError_whenSwitchToFingerprint() {
-        mFaceToFpView.onDialogAnimatedIn();
-        mFaceToFpView.onAuthenticationFailed(TYPE_FACE, "no face");
-        waitForIdleSync();
-
-        verify(mIndicatorView).setText(
-                eq(mContext.getString(R.string.fingerprint_dialog_use_fingerprint_instead)));
-        verify(mCallback).onAction(
-                eq(AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR));
-
-        // First we enter the error state, since we need to show the error animation/text. The
-        // error state is later cleared based on a timer, and we enter STATE_AUTHENTICATING.
-        assertEquals(AuthBiometricFaceToFingerprintView.STATE_ERROR, mFaceToFpView.mState);
-    }
-
-    @Test
-    @Ignore("flaky, b/189031816")
-    public void testModeUpdated_onHardError_whenSwitchToFingerprint() {
-        mFaceToFpView.onDialogAnimatedIn();
-        mFaceToFpView.onError(TYPE_FACE, "oh no!");
-        waitForIdleSync();
-
-        verify(mIndicatorView).setText(
-                eq(mContext.getString(R.string.fingerprint_dialog_use_fingerprint_instead)));
-        verify(mCallback).onAction(
-                eq(AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR));
-
-        // First we enter the error state, since we need to show the error animation/text. The
-        // error state is later cleared based on a timer, and we enter STATE_AUTHENTICATING.
-        assertEquals(AuthBiometricFaceToFingerprintView.STATE_ERROR, mFaceToFpView.mState);
-    }
-
-    @Test
-    public void testFingerprintOnlyStartsOnFirstError() {
-        mFaceToFpView.onDialogAnimatedIn();
-        verify(mFaceToFpView.mFaceIconController)
-                .updateState(anyInt(), eq(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING));
-
-        mFaceToFpView.onDialogAnimatedIn();
-        mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_ERROR);
-        mFaceToFpView.updateState(AuthBiometricFaceToFingerprintView.STATE_AUTHENTICATING);
-
-        reset(mCallback);
-
-        mFaceToFpView.onError(TYPE_FACE, "oh no!");
-        mFaceToFpView.onAuthenticationFailed(TYPE_FACE, "no face");
-
-        verify(mCallback, never()).onAction(
-                eq(AuthBiometricView.Callback.ACTION_START_DELAYED_FINGERPRINT_SENSOR));
-    }
-
-    @Test
-    public void testOnSaveState() {
-        final FingerprintSensorPropertiesInternal sensorProps = createFingerprintSensorProps();
-        mFaceToFpView.setFingerprintSensorProps(sensorProps);
-
-        final Bundle savedState = new Bundle();
-        mFaceToFpView.onSaveState(savedState);
-
-        assertEquals(savedState.getInt(AuthDialog.KEY_BIOMETRIC_SENSOR_TYPE),
-                mFaceToFpView.getActiveSensorType());
-        assertEquals(savedState.getParcelable(AuthDialog.KEY_BIOMETRIC_SENSOR_PROPS), sensorProps);
-    }
-
-    @Test
-    public void testRestoreState() {
-        final Bundle savedState = new Bundle();
-        savedState.putInt(AuthDialog.KEY_BIOMETRIC_SENSOR_TYPE, TYPE_FINGERPRINT);
-        savedState.putParcelable(AuthDialog.KEY_BIOMETRIC_SENSOR_PROPS,
-                createFingerprintSensorProps());
-
-        mFaceToFpView.restoreState(savedState);
-
-        assertEquals(mFaceToFpView.getActiveSensorType(), TYPE_FINGERPRINT);
-        assertTrue(mFaceToFpView.isFingerprintUdfps());
-    }
-
-    @NonNull
-    private static FingerprintSensorPropertiesInternal createFingerprintSensorProps() {
-        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
-        componentInfo.add(new ComponentInfoInternal("componentId", "hardwareVersion",
-                "firmwareVersion", "serialNumber", "softwareVersion"));
-
-        return new FingerprintSensorPropertiesInternal(
-                0 /* sensorId */,
-                SensorProperties.STRENGTH_STRONG,
-                5 /* maxEnrollmentsPerUser */,
-                componentInfo,
-                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
-                true /* resetLockoutRequiresHardwareAuthToken */,
-                List.of(new SensorLocationInternal("" /* displayId */,
-                        540 /* sensorLocationX */,
-                        1600 /* sensorLocationY */,
-                        100 /* sensorRadius */)));
-    }
-
-    public class TestableView extends AuthBiometricFaceToFingerprintView {
-        public TestableView(Context context) {
-            super(context, null, new MockInjector());
-        }
-
-        @Override
-        protected int getDelayAfterAuthenticatedDurationMs() {
-            return 0;
-        }
-    }
-
-    private class MockInjector extends AuthBiometricView.Injector {
-        @Override
-        public Button getNegativeButton() {
-            return mNegativeButton;
-        }
-
-        @Override
-        public Button getCancelButton() {
-            return mCancelButton;
-        }
-
-        @Override
-        public Button getUseCredentialButton() {
-            return mUseCredentialButton;
-        }
-
-        @Override
-        public Button getConfirmButton() {
-            return mConfirmButton;
-        }
-
-        @Override
-        public Button getTryAgainButton() {
-            return mTryAgainButton;
-        }
-
-        @Override
-        public TextView getTitleView() {
-            return mTitleView;
-        }
-
-        @Override
-        public TextView getSubtitleView() {
-            return mSubtitleView;
-        }
-
-        @Override
-        public TextView getDescriptionView() {
-            return mDescriptionView;
-        }
-
-        @Override
-        public TextView getIndicatorView() {
-            return mIndicatorView;
-        }
-
-        @Override
-        public ImageView getIconView() {
-            return mIconView;
-        }
-
-        @Override
-        public View getIconHolderView() {
-            return mIconHolderView;
-        }
-
-        @Override
-        public int getDelayAfterError() {
-            return 0;
-        }
-
-        @Override
-        public int getMediumToLargeAnimationDurationMs() {
-            return 0;
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
deleted file mode 100644
index b93381d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFaceViewTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper.RunWithLooper;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-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;
-
-import com.android.systemui.R;
-
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-@SmallTest
-public class AuthBiometricFaceViewTest extends SysuiTestCase {
-
-    @Mock
-    AuthBiometricView.Callback mCallback;
-
-    private TestableFaceView mFaceView;
-
-    @Mock private Button mNegativeButton;
-    @Mock private Button mCancelButton;
-    @Mock private Button mUseCredentialButton;
-
-    @Mock private Button mConfirmButton;
-    @Mock private Button mTryAgainButton;
-
-    @Mock private TextView mErrorView;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mFaceView = new TestableFaceView(mContext);
-        mFaceView.mFaceIconController = mock(TestableFaceView.TestableIconController.class);
-        mFaceView.setCallback(mCallback);
-
-        mFaceView.mNegativeButton = mNegativeButton;
-        mFaceView.mCancelButton = mCancelButton;
-        mFaceView.mUseCredentialButton = mUseCredentialButton;
-
-        mFaceView.mConfirmButton = mConfirmButton;
-        mFaceView.mTryAgainButton = mTryAgainButton;
-
-        mFaceView.mIndicatorView = mErrorView;
-    }
-
-    @Test
-    public void testStateUpdated_whenDialogAnimatedIn() {
-        mFaceView.onDialogAnimatedIn();
-        verify(mFaceView.mFaceIconController)
-                .updateState(anyInt(), eq(AuthBiometricFaceView.STATE_AUTHENTICATING));
-    }
-
-    @Test
-    public void testIconUpdatesState_whenDialogStateUpdated() {
-        mFaceView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATING);
-        verify(mFaceView.mFaceIconController)
-                .updateState(anyInt(), eq(AuthBiometricFaceView.STATE_AUTHENTICATING));
-
-        mFaceView.updateState(AuthBiometricFaceView.STATE_AUTHENTICATED);
-        verify(mFaceView.mFaceIconController).updateState(
-                eq(AuthBiometricFaceView.STATE_AUTHENTICATING),
-                eq(AuthBiometricFaceView.STATE_AUTHENTICATED));
-    }
-
-    public class TestableFaceView extends AuthBiometricFaceView {
-
-        public class TestableIconController extends IconController {
-            TestableIconController(Context context, ImageView iconView) {
-                super(context, iconView, mock(TextView.class));
-            }
-
-            public void startPulsing() {
-                // Stub for testing
-            }
-        }
-
-        @Override
-        protected int getDelayAfterAuthenticatedDurationMs() {
-            return 0; // Keep this at 0 for tests to invoke callback immediately.
-        }
-
-        public TestableFaceView(Context context) {
-            super(context);
-        }
-    }
-
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
index f8e38e4..9418b50 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricViewTest.java
@@ -20,137 +20,109 @@
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 
+import static com.android.systemui.biometrics.AuthBiometricView.Callback.ACTION_AUTHENTICATED;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
-import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.PromptInfo;
 import android.os.Bundle;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
-import android.util.AttributeSet;
+import android.testing.ViewUtils;
+import android.view.LayoutInflater;
 import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
-import org.junit.Before;
 import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
+@Ignore
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
 public class AuthBiometricViewTest extends SysuiTestCase {
 
-    @Mock private AuthBiometricView.Callback mCallback;
-    @Mock private AuthPanelController mPanelController;
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
-    @Mock private Button mNegativeButton;
-    @Mock private Button mCancelButton;
-    @Mock private Button mUseCredentialButton;
+    @Mock
+    private AuthBiometricView.Callback mCallback;
+    @Mock
+    private AuthPanelController mPanelController;
 
-    @Mock private Button mPositiveButton;
-    @Mock private Button mTryAgainButton;
-
-    @Mock private TextView mTitleView;
-    @Mock private TextView mSubtitleView;
-    @Mock private TextView mDescriptionView;
-    @Mock private TextView mIndicatorView;
-    @Mock private ImageView mIconView;
-    @Mock private View mIconHolderView;
-
-    private TestableBiometricView mBiometricView;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
+    private AuthBiometricView mBiometricView;
 
     @Test
     public void testOnAuthenticationSucceeded_noConfirmationRequired_sendsActionAuthenticated() {
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
         // The onAuthenticated runnable is posted when authentication succeeds.
-        mBiometricView.onAuthenticationSucceeded();
+        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
         waitForIdleSync();
         assertEquals(AuthBiometricView.STATE_AUTHENTICATED, mBiometricView.mState);
-        verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED);
+        verify(mCallback).onAction(ACTION_AUTHENTICATED);
     }
 
     @Test
     public void testOnAuthenticationSucceeded_confirmationRequired_updatesDialogContents() {
-        final Button negativeButton = new Button(mContext);
-        final Button cancelButton = new Button(mContext);
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
-            @Override
-            public Button getNegativeButton() {
-                return negativeButton;
-            }
-
-            @Override
-            public Button getCancelButton() {
-                return cancelButton;
-            }
-        });
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
         mBiometricView.setRequireConfirmation(true);
-        mBiometricView.onAuthenticationSucceeded();
+        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
         waitForIdleSync();
-        assertEquals(AuthBiometricView.STATE_PENDING_CONFIRMATION, mBiometricView.mState);
-        verify(mCallback, never()).onAction(anyInt());
 
-        assertEquals(View.GONE, negativeButton.getVisibility());
-        assertEquals(View.VISIBLE, cancelButton.getVisibility());
-        assertTrue(cancelButton.isEnabled());
+        // TODO: this should be tested in the subclasses
+        if (mBiometricView.supportsRequireConfirmation()) {
+            assertEquals(AuthBiometricView.STATE_PENDING_CONFIRMATION, mBiometricView.mState);
 
-        verify(mBiometricView.mConfirmButton).setEnabled(eq(true));
-        verify(mIndicatorView).setText(eq(R.string.biometric_dialog_tap_confirm));
-        verify(mIndicatorView).setVisibility(eq(View.VISIBLE));
+            verify(mCallback, never()).onAction(anyInt());
+
+            assertEquals(View.GONE, mBiometricView.mNegativeButton.getVisibility());
+            assertEquals(View.VISIBLE, mBiometricView.mCancelButton.getVisibility());
+            assertTrue(mBiometricView.mCancelButton.isEnabled());
+
+            assertTrue(mBiometricView.mConfirmButton.isEnabled());
+            assertEquals(mContext.getText(R.string.biometric_dialog_tap_confirm),
+                    mBiometricView.mIndicatorView.getText());
+            assertEquals(View.VISIBLE, mBiometricView.mIndicatorView.getVisibility());
+        } else {
+            assertEquals(AuthBiometricView.STATE_AUTHENTICATED, mBiometricView.mState);
+            verify(mCallback).onAction(eq(ACTION_AUTHENTICATED));
+        }
+
     }
 
     @Test
     public void testPositiveButton_sendsActionAuthenticated() {
-        Button button = new Button(mContext);
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
-           @Override
-            public Button getConfirmButton() {
-               return button;
-           }
-        });
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
-        button.performClick();
+        mBiometricView.mConfirmButton.performClick();
         waitForIdleSync();
 
-        verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_AUTHENTICATED);
+        verify(mCallback).onAction(ACTION_AUTHENTICATED);
         assertEquals(AuthBiometricView.STATE_AUTHENTICATED, mBiometricView.mState);
     }
 
     @Test
     public void testNegativeButton_beforeAuthentication_sendsActionButtonNegative() {
-        Button button = new Button(mContext);
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
-            @Override
-            public Button getNegativeButton() {
-                return button;
-            }
-        });
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
         mBiometricView.onDialogAnimatedIn();
-        button.performClick();
+        mBiometricView.mNegativeButton.performClick();
         waitForIdleSync();
 
         verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE);
@@ -158,25 +130,14 @@
 
     @Test
     public void testCancelButton_whenPendingConfirmation_sendsActionUserCanceled() {
-        Button cancelButton = new Button(mContext);
-        Button negativeButton = new Button(mContext);
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
-            @Override
-            public Button getNegativeButton() {
-                return negativeButton;
-            }
-            @Override
-            public Button getCancelButton() {
-                return cancelButton;
-            }
-        });
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
         mBiometricView.setRequireConfirmation(true);
-        mBiometricView.onAuthenticationSucceeded();
+        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
 
-        assertEquals(View.GONE, negativeButton.getVisibility());
+        assertEquals(View.GONE, mBiometricView.mNegativeButton.getVisibility());
 
-        cancelButton.performClick();
+        mBiometricView.mCancelButton.performClick();
         waitForIdleSync();
 
         verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_USER_CANCELED);
@@ -184,15 +145,9 @@
 
     @Test
     public void testTryAgainButton_sendsActionTryAgain() {
-        Button button = new Button(mContext);
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
-            @Override
-            public Button getTryAgainButton() {
-                return button;
-            }
-        });
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
-        button.performClick();
+        mBiometricView.mTryAgainButton.performClick();
         waitForIdleSync();
 
         verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN);
@@ -202,7 +157,7 @@
     @Test
     @Ignore("flaky, b/189031816")
     public void testError_sendsActionError() {
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
+        initDialog(false /* allowDeviceCredential */, mCallback);
         final String testError = "testError";
         mBiometricView.onError(TYPE_FACE, testError);
         waitForIdleSync();
@@ -213,7 +168,7 @@
 
     @Test
     public void testBackgroundClicked_sendsActionUserCanceled() {
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
         View view = new View(mContext);
         mBiometricView.setBackgroundView(view);
@@ -223,18 +178,18 @@
 
     @Test
     public void testBackgroundClicked_afterAuthenticated_neverSendsUserCanceled() {
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
         View view = new View(mContext);
         mBiometricView.setBackgroundView(view);
-        mBiometricView.onAuthenticationSucceeded();
+        mBiometricView.onAuthenticationSucceeded(TYPE_FINGERPRINT);
         view.performClick();
         verify(mCallback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_USER_CANCELED));
     }
 
     @Test
     public void testBackgroundClicked_whenSmallDialog_neverSendsUserCanceled() {
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
+        initDialog(false /* allowDeviceCredential */, mCallback);
         mBiometricView.mLayoutParams = new AuthDialog.LayoutParams(0, 0);
         mBiometricView.updateSize(AuthDialog.SIZE_SMALL);
 
@@ -246,7 +201,7 @@
 
     @Test
     public void testIgnoresUselessHelp() {
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector());
+        initDialog(false /* allowDeviceCredential */, mCallback);
 
         mBiometricView.onDialogAnimatedIn();
         waitForIdleSync();
@@ -256,33 +211,16 @@
         mBiometricView.onHelp(TYPE_FINGERPRINT, "");
         waitForIdleSync();
 
-        verify(mIndicatorView, never()).setText(any());
+        assertEquals("", mBiometricView.mIndicatorView.getText());
         verify(mCallback, never()).onAction(eq(AuthBiometricView.Callback.ACTION_ERROR));
         assertEquals(AuthBiometricView.STATE_AUTHENTICATING, mBiometricView.mState);
     }
 
     @Test
     public void testRestoresState() {
-        final boolean requireConfirmation = true; // set/init from AuthController
+        final boolean requireConfirmation = true;
 
-        Button tryAgainButton = new Button(mContext);
-        TextView indicatorView = new TextView(mContext);
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, new MockInjector() {
-            @Override
-            public Button getTryAgainButton() {
-                return tryAgainButton;
-            }
-            @Override
-            public TextView getIndicatorView() {
-                return indicatorView;
-            }
-
-            @Override
-            public int getDelayAfterError() {
-                // keep a real delay to test saving in the error state
-                return BiometricPrompt.HIDE_DIALOG_DELAY;
-            }
-        });
+        initDialog(false /* allowDeviceCredential */, mCallback, null, 10000);
 
         final String failureMessage = "testFailureMessage";
         mBiometricView.setRequireConfirmation(requireConfirmation);
@@ -292,8 +230,8 @@
         Bundle state = new Bundle();
         mBiometricView.onSaveState(state);
 
-        assertEquals(View.VISIBLE, tryAgainButton.getVisibility());
-        assertEquals(View.VISIBLE, state.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY));
+        assertEquals(View.GONE, mBiometricView.mTryAgainButton.getVisibility());
+        assertEquals(View.GONE, state.getInt(AuthDialog.KEY_BIOMETRIC_TRY_AGAIN_VISIBILITY));
 
         assertEquals(AuthBiometricView.STATE_ERROR, mBiometricView.mState);
         assertEquals(AuthBiometricView.STATE_ERROR, state.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
@@ -307,25 +245,12 @@
         // TODO: Test dialog size. Should move requireConfirmation to buildBiometricPromptBundle
 
         // Create new dialog and restore the previous state into it
-        Button tryAgainButton2 = new Button(mContext);
-        TextView indicatorView2 = new TextView(mContext);
-        initDialog(mContext, false /* allowDeviceCredential */, mCallback, state,
-                new MockInjector() {
-                    @Override
-                    public Button getTryAgainButton() {
-                        return tryAgainButton2;
-                    }
-
-                    @Override
-                    public TextView getIndicatorView() {
-                        return indicatorView2;
-                    }
-                });
+        initDialog(false /* allowDeviceCredential */, mCallback, state, 10000);
+        mBiometricView.mAnimationDurationHideDialog = 10000;
         mBiometricView.setRequireConfirmation(requireConfirmation);
         waitForIdleSync();
 
-        // Test restored state
-        assertEquals(View.VISIBLE, tryAgainButton.getVisibility());
+        assertEquals(View.GONE, mBiometricView.mTryAgainButton.getVisibility());
         assertEquals(AuthBiometricView.STATE_ERROR, mBiometricView.mState);
         assertEquals(View.VISIBLE, mBiometricView.mIndicatorView.getVisibility());
 
@@ -334,23 +259,12 @@
     }
 
     @Test
-    public void testCredentialButton_whenDeviceCredentialAllowed() {
-        final Button negativeButton = new Button(mContext);
-        final Button useCredentialButton = new Button(mContext);
-        initDialog(mContext, true /* allowDeviceCredential */, mCallback, new MockInjector() {
-            @Override
-            public Button getNegativeButton() {
-                return negativeButton;
-            }
+    public void testCredentialButton_whenDeviceCredentialAllowed() throws InterruptedException {
+        initDialog(true /* allowDeviceCredential */, mCallback);
 
-            @Override
-            public Button getUseCredentialButton() {
-                return useCredentialButton;
-            }
-        });
-
-        assertEquals(View.GONE, negativeButton.getVisibility());
-        useCredentialButton.performClick();
+        assertEquals(View.VISIBLE, mBiometricView.mUseCredentialButton.getVisibility());
+        assertEquals(View.GONE, mBiometricView.mNegativeButton.getVisibility());
+        mBiometricView.mUseCredentialButton.performClick();
         waitForIdleSync();
 
         verify(mCallback).onAction(AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL);
@@ -369,120 +283,30 @@
         return promptInfo;
     }
 
-    private void initDialog(Context context, boolean allowDeviceCredential,
-            AuthBiometricView.Callback callback,
-            Bundle savedState, MockInjector injector) {
-        mBiometricView = new TestableBiometricView(context, null, injector);
+    private void initDialog(boolean allowDeviceCredential, AuthBiometricView.Callback callback) {
+        initDialog(allowDeviceCredential, callback,
+                null /* savedState */, 0 /* hideDelay */);
+    }
+
+    private void initDialog(boolean allowDeviceCredential,
+            AuthBiometricView.Callback callback, Bundle savedState, int hideDelay) {
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
+        mBiometricView = (AuthBiometricView) inflater.inflate(
+                R.layout.auth_biometric_view, null, false);
+        mBiometricView.mAnimationDurationLong = 0;
+        mBiometricView.mAnimationDurationShort = 0;
+        mBiometricView.mAnimationDurationHideDialog = hideDelay;
         mBiometricView.setPromptInfo(buildPromptInfo(allowDeviceCredential));
         mBiometricView.setCallback(callback);
         mBiometricView.restoreState(savedState);
-        mBiometricView.onFinishInflateInternal();
-        mBiometricView.onAttachedToWindowInternal();
-
+        ViewUtils.attachView(mBiometricView);
         mBiometricView.setPanelController(mPanelController);
+        waitForIdleSync();
     }
 
-    private void initDialog(Context context, boolean allowDeviceCredential,
-            AuthBiometricView.Callback callback, MockInjector injector) {
-        initDialog(context, allowDeviceCredential, callback, null /* savedState */, injector);
-    }
-
-    private class MockInjector extends AuthBiometricView.Injector {
-        @Override
-        public Button getNegativeButton() {
-            return mNegativeButton;
-        }
-
-        @Override
-        public Button getCancelButton() {
-            return mCancelButton;
-        }
-
-        @Override
-        public Button getUseCredentialButton() {
-            return mUseCredentialButton;
-        }
-
-        @Override
-        public Button getConfirmButton() {
-            return mPositiveButton;
-        }
-
-        @Override
-        public Button getTryAgainButton() {
-            return mTryAgainButton;
-        }
-
-        @Override
-        public TextView getTitleView() {
-            return mTitleView;
-        }
-
-        @Override
-        public TextView getSubtitleView() {
-            return mSubtitleView;
-        }
-
-        @Override
-        public TextView getDescriptionView() {
-            return mDescriptionView;
-        }
-
-        @Override
-        public TextView getIndicatorView() {
-            return mIndicatorView;
-        }
-
-        @Override
-        public ImageView getIconView() {
-            return mIconView;
-        }
-
-        @Override
-        public View getIconHolderView() {
-            return mIconHolderView;
-        }
-
-        @Override
-        public int getDelayAfterError() {
-            return 0; // Keep this at 0 for tests to invoke callback immediately.
-        }
-
-        @Override
-        public int getMediumToLargeAnimationDurationMs() {
-            return 0;
-        }
-    }
-
-    private class TestableBiometricView extends AuthBiometricView {
-        TestableBiometricView(Context context, AttributeSet attrs,
-                Injector injector) {
-            super(context, attrs, injector);
-        }
-
-        @Override
-        protected int getDelayAfterAuthenticatedDurationMs() {
-            return 0; // Keep this at 0 for tests to invoke callback immediately.
-        }
-
-        @Override
-        protected int getStateForAfterError() {
-            return 0;
-        }
-
-        @Override
-        protected void handleResetAfterError() {
-
-        }
-
-        @Override
-        protected void handleResetAfterHelp() {
-
-        }
-
-        @Override
-        protected boolean supportsSmallDialog() {
-            return false;
-        }
+    @Override
+    protected void waitForIdleSync() {
+        TestableLooper.get(this).processAllMessages();
+        super.waitForIdleSync();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
deleted file mode 100644
index ae1268d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.biometrics;
-
-import static android.hardware.biometrics.BiometricManager.Authenticators;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.ComponentInfoInternal;
-import android.hardware.biometrics.PromptInfo;
-import android.hardware.biometrics.SensorProperties;
-import android.hardware.face.FaceSensorPropertiesInternal;
-import android.hardware.fingerprint.FingerprintSensorProperties;
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
-import android.os.IBinder;
-import android.os.UserManager;
-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 android.view.WindowInsets;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ScrollView;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-
-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.List;
-
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper
-@SmallTest
-public class AuthContainerViewTest extends SysuiTestCase {
-
-    private TestableAuthContainer mAuthContainer;
-
-    private @Mock AuthDialogCallback mCallback;
-    private @Mock UserManager mUserManager;
-    private @Mock WakefulnessLifecycle mWakefulnessLifecycle;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @Test
-    public void testActionAuthenticated_sendsDismissedAuthenticated() {
-        initializeContainer(Authenticators.BIOMETRIC_WEAK);
-
-        mAuthContainer.mBiometricCallback.onAction(
-                AuthBiometricView.Callback.ACTION_AUTHENTICATED);
-        verify(mCallback).onDismissed(
-                eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
-                eq(null) /* credentialAttestation */);
-    }
-
-    @Test
-    public void testActionUserCanceled_sendsDismissedUserCanceled() {
-        initializeContainer(Authenticators.BIOMETRIC_WEAK);
-
-        mAuthContainer.mBiometricCallback.onAction(
-                AuthBiometricView.Callback.ACTION_USER_CANCELED);
-        verify(mCallback).onSystemEvent(eq(
-                BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL));
-        verify(mCallback).onDismissed(
-                eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
-                eq(null) /* credentialAttestation */);
-    }
-
-    @Test
-    public void testActionButtonNegative_sendsDismissedButtonNegative() {
-        initializeContainer(Authenticators.BIOMETRIC_WEAK);
-
-        mAuthContainer.mBiometricCallback.onAction(
-                AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE);
-        verify(mCallback).onDismissed(
-                eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
-                eq(null) /* credentialAttestation */);
-    }
-
-    @Test
-    public void testActionTryAgain_sendsTryAgain() {
-        initializeContainer(Authenticators.BIOMETRIC_WEAK);
-
-        mAuthContainer.mBiometricCallback.onAction(
-                AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN);
-        verify(mCallback).onTryAgainPressed();
-    }
-
-    @Test
-    public void testActionError_sendsDismissedError() {
-        initializeContainer(Authenticators.BIOMETRIC_WEAK);
-
-        mAuthContainer.mBiometricCallback.onAction(
-                AuthBiometricView.Callback.ACTION_ERROR);
-        verify(mCallback).onDismissed(
-                eq(AuthDialogCallback.DISMISSED_ERROR),
-                eq(null) /* credentialAttestation */);
-    }
-
-    @Test
-    public void testActionUseDeviceCredential_sendsOnDeviceCredentialPressed() {
-        initializeContainer(
-                Authenticators.BIOMETRIC_WEAK | Authenticators.DEVICE_CREDENTIAL);
-
-        mAuthContainer.mBiometricCallback.onAction(
-                AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL);
-        verify(mCallback).onDeviceCredentialPressed();
-
-        // Credential view is attached to the frame layout
-        waitForIdleSync();
-        assertNotNull(mAuthContainer.mCredentialView);
-        verify(mAuthContainer.mFrameLayout).addView(eq(mAuthContainer.mCredentialView));
-    }
-
-    @Test
-    public void testAnimateToCredentialUI_invokesStartTransitionToCredentialUI() {
-        initializeContainer(
-                Authenticators.BIOMETRIC_WEAK | Authenticators.DEVICE_CREDENTIAL);
-
-        mAuthContainer.mBiometricView = mock(AuthBiometricView.class);
-        mAuthContainer.animateToCredentialUI();
-        verify(mAuthContainer.mBiometricView).startTransitionToCredentialUI();
-    }
-
-    @Test
-    public void testShowBiometricUI() {
-        initializeContainer(Authenticators.BIOMETRIC_WEAK);
-
-        assertNotEquals(null, mAuthContainer.mBiometricView);
-
-        mAuthContainer.onAttachedToWindowInternal();
-        verify(mAuthContainer.mBiometricScrollView).addView(mAuthContainer.mBiometricView);
-        // Credential view is not added
-        verify(mAuthContainer.mFrameLayout, never()).addView(any());
-    }
-
-    @Test
-    public void testShowCredentialUI_doesNotInflateBiometricUI() {
-        initializeContainer(Authenticators.DEVICE_CREDENTIAL);
-
-        mAuthContainer.onAttachedToWindowInternal();
-
-        assertNull(null, mAuthContainer.mBiometricView);
-        assertNotNull(mAuthContainer.mCredentialView);
-        verify(mAuthContainer.mFrameLayout).addView(mAuthContainer.mCredentialView);
-    }
-
-    @Test
-    public void testCredentialViewUsesEffectiveUserId() {
-        final int dummyEffectiveUserId = 200;
-        when(mUserManager.getCredentialOwnerProfile(anyInt())).thenReturn(dummyEffectiveUserId);
-
-        initializeContainer(Authenticators.DEVICE_CREDENTIAL);
-        mAuthContainer.onAttachedToWindowInternal();
-        assertTrue(mAuthContainer.mCredentialView instanceof AuthCredentialPatternView);
-        assertEquals(dummyEffectiveUserId, mAuthContainer.mCredentialView.mEffectiveUserId);
-        assertEquals(Utils.CREDENTIAL_PATTERN, mAuthContainer.mCredentialView.mCredentialType);
-    }
-
-    @Test
-    public void testCredentialUI_disablesClickingOnBackground() {
-        // In the credential view, clicking on the background (to cancel authentication) is not
-        // valid. Thus, the listener should be null, and it should not be in the accessibility
-        // hierarchy.
-        initializeContainer(Authenticators.DEVICE_CREDENTIAL);
-
-        mAuthContainer.onAttachedToWindowInternal();
-
-        verify(mAuthContainer.mBackgroundView).setOnClickListener(eq(null));
-        verify(mAuthContainer.mBackgroundView).setImportantForAccessibility(
-                eq(View.IMPORTANT_FOR_ACCESSIBILITY_NO));
-    }
-
-    @Test
-    public void testOnDialogAnimatedIn_sendsCancelReason_whenPendingDismiss() {
-        initializeContainer(Authenticators.BIOMETRIC_WEAK);
-        mAuthContainer.mContainerState = AuthContainerView.STATE_PENDING_DISMISS;
-        mAuthContainer.onDialogAnimatedIn();
-        verify(mCallback).onDismissed(
-                eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
-                eq(null) /* credentialAttestation */);
-    }
-
-    @Test
-    public void testLayoutParams_hasSecureWindowFlag() {
-        final IBinder windowToken = mock(IBinder.class);
-        final WindowManager.LayoutParams layoutParams =
-                AuthContainerView.getLayoutParams(windowToken, "");
-        assertTrue((layoutParams.flags & WindowManager.LayoutParams.FLAG_SECURE) != 0);
-    }
-
-    @Test
-    public void testLayoutParams_excludesImeInsets() {
-        final IBinder windowToken = mock(IBinder.class);
-        final WindowManager.LayoutParams layoutParams =
-                AuthContainerView.getLayoutParams(windowToken, "");
-        assertTrue((layoutParams.getFitInsetsTypes() & WindowInsets.Type.ime()) == 0);
-    }
-
-    private void initializeContainer(int authenticators) {
-        AuthContainerView.Config config = new AuthContainerView.Config();
-        config.mContext = mContext;
-        config.mCallback = mCallback;
-        config.mSensorIds = new int[] {0};
-        config.mCredentialAllowed = false;
-
-        PromptInfo promptInfo = new PromptInfo();
-        promptInfo.setAuthenticators(authenticators);
-        config.mPromptInfo = promptInfo;
-
-        final List<FingerprintSensorPropertiesInternal> fpProps = new ArrayList<>();
-
-        final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
-        componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
-                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
-                "00000001" /* serialNumber */, "" /* softwareVersion */));
-        componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */,
-                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
-                "vendor/version/revision" /* softwareVersion */));
-
-        fpProps.add(new FingerprintSensorPropertiesInternal(0,
-                SensorProperties.STRENGTH_STRONG,
-                5 /* maxEnrollmentsPerUser */,
-                componentInfo,
-                FingerprintSensorProperties.TYPE_REAR,
-                false /* resetLockoutRequiresHardwareAuthToken */));
-        mAuthContainer = new TestableAuthContainer(config, fpProps, null /* faceProps */,
-                mWakefulnessLifecycle);
-    }
-
-    private class TestableAuthContainer extends AuthContainerView {
-        TestableAuthContainer(AuthContainerView.Config config,
-                @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
-                @Nullable List<FaceSensorPropertiesInternal> faceProps,
-                WakefulnessLifecycle wakefulnessLifecycle) {
-
-            super(config, new MockInjector(), fpProps, faceProps, wakefulnessLifecycle);
-        }
-
-        @Override
-        public void animateAway(int reason) {
-            // TODO: Credential attestation should be testable/tested
-            mConfig.mCallback.onDismissed(reason, null /* credentialAttestation */);
-        }
-    }
-
-    private final class MockInjector extends AuthContainerView.Injector {
-        @Override
-        public ScrollView getBiometricScrollView(FrameLayout parent) {
-            return mock(ScrollView.class);
-        }
-
-        @Override
-        public FrameLayout inflateContainerView(LayoutInflater factory, ViewGroup root) {
-            return mock(FrameLayout.class);
-        }
-
-        @Override
-        public AuthPanelController getPanelController(Context context, View view) {
-            return mock(AuthPanelController.class);
-        }
-
-        @Override
-        public ImageView getBackgroundView(FrameLayout parent) {
-            return mock(ImageView.class);
-        }
-
-        @Override
-        public View getPanelView(FrameLayout parent) {
-            return mock(View.class);
-        }
-
-        @Override
-        public int getAnimateCredentialStartDelayMs() {
-            return 0;
-        }
-
-        @Override
-        public UserManager getUserManager(Context context) {
-            return mUserManager;
-        }
-
-        @Override
-        public @Utils.CredentialType int getCredentialType(Context context, int effectiveUserId) {
-            return Utils.CREDENTIAL_PATTERN;
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
new file mode 100644
index 0000000..6f0a8a6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -0,0 +1,324 @@
+/*
+ * 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.biometrics
+
+import android.app.admin.DevicePolicyManager
+import android.hardware.biometrics.BiometricConstants
+import android.hardware.biometrics.BiometricManager
+import android.hardware.biometrics.ComponentInfoInternal
+import android.hardware.biometrics.PromptInfo
+import android.hardware.biometrics.SensorProperties
+import android.hardware.face.FaceSensorPropertiesInternal
+import android.hardware.fingerprint.FingerprintSensorProperties
+import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
+import android.os.Handler
+import android.os.IBinder
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import android.testing.ViewUtils
+import android.view.View
+import android.view.WindowInsets
+import android.view.WindowManager
+import android.widget.ScrollView
+import androidx.test.filters.SmallTest
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.google.common.truth.Truth.assertThat
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.eq
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
+
+@Ignore
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper
+@SmallTest
+class AuthContainerViewTest : SysuiTestCase() {
+
+    @JvmField @Rule
+    var rule = MockitoJUnit.rule()
+
+    @Mock
+    lateinit var callback: AuthDialogCallback
+    @Mock
+    lateinit var userManager: UserManager
+    @Mock
+    lateinit var lockPatternUtils: LockPatternUtils
+    @Mock
+    lateinit var wakefulnessLifecycle: WakefulnessLifecycle
+    @Mock
+    lateinit var windowToken: IBinder
+
+    private lateinit var authContainer: TestAuthContainerView
+
+    @Test
+    fun testActionAuthenticated_sendsDismissedAuthenticated() {
+        initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+        authContainer.mBiometricCallback.onAction(
+            AuthBiometricView.Callback.ACTION_AUTHENTICATED
+        )
+        waitForIdleSync()
+
+        verify(callback).onDismissed(
+            eq(AuthDialogCallback.DISMISSED_BIOMETRIC_AUTHENTICATED),
+            eq<ByteArray?>(null) /* credentialAttestation */
+        )
+        assertThat(authContainer.parent).isNull()
+    }
+
+    @Test
+    fun testActionUserCanceled_sendsDismissedUserCanceled() {
+        initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+        authContainer.mBiometricCallback.onAction(
+            AuthBiometricView.Callback.ACTION_USER_CANCELED
+        )
+        waitForIdleSync()
+
+        verify(callback).onSystemEvent(
+            eq(BiometricConstants.BIOMETRIC_SYSTEM_EVENT_EARLY_USER_CANCEL)
+        )
+        verify(callback).onDismissed(
+            eq(AuthDialogCallback.DISMISSED_USER_CANCELED),
+            eq<ByteArray?>(null) /* credentialAttestation */
+        )
+        assertThat(authContainer.parent).isNull()
+    }
+
+    @Test
+    fun testActionButtonNegative_sendsDismissedButtonNegative() {
+        initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+        authContainer.mBiometricCallback.onAction(
+            AuthBiometricView.Callback.ACTION_BUTTON_NEGATIVE
+        )
+        waitForIdleSync()
+
+        verify(callback).onDismissed(
+            eq(AuthDialogCallback.DISMISSED_BUTTON_NEGATIVE),
+            eq<ByteArray?>(null) /* credentialAttestation */
+        )
+        assertThat(authContainer.parent).isNull()
+    }
+
+    @Test
+    fun testActionTryAgain_sendsTryAgain() {
+        initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+        authContainer.mBiometricCallback.onAction(
+            AuthBiometricView.Callback.ACTION_BUTTON_TRY_AGAIN
+        )
+        waitForIdleSync()
+
+        verify(callback).onTryAgainPressed()
+    }
+
+    @Test
+    fun testActionError_sendsDismissedError() {
+        initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+        authContainer.mBiometricCallback.onAction(
+            AuthBiometricView.Callback.ACTION_ERROR
+        )
+        waitForIdleSync()
+
+        verify(callback).onDismissed(
+            eq(AuthDialogCallback.DISMISSED_ERROR),
+            eq<ByteArray?>(null) /* credentialAttestation */
+        )
+        assertThat(authContainer.parent).isNull()
+    }
+
+    @Test
+    fun testActionUseDeviceCredential_sendsOnDeviceCredentialPressed() {
+        initializeContainer(
+            BiometricManager.Authenticators.BIOMETRIC_WEAK or
+                BiometricManager.Authenticators.DEVICE_CREDENTIAL
+        )
+        authContainer.mBiometricCallback.onAction(
+            AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL
+        )
+        waitForIdleSync()
+
+        verify(callback).onDeviceCredentialPressed()
+        assertThat(authContainer.hasCredentialView()).isTrue()
+    }
+
+    @Test
+    fun testAnimateToCredentialUI_invokesStartTransitionToCredentialUI() {
+        initializeContainer(
+            BiometricManager.Authenticators.BIOMETRIC_WEAK or
+                BiometricManager.Authenticators.DEVICE_CREDENTIAL
+        )
+        authContainer.animateToCredentialUI()
+        waitForIdleSync()
+
+        assertThat(authContainer.hasCredentialView()).isTrue()
+    }
+
+    @Test
+    fun testShowBiometricUI() {
+        initializeContainer(BiometricManager.Authenticators.BIOMETRIC_WEAK)
+
+        waitForIdleSync()
+
+        assertThat(authContainer.hasCredentialView()).isFalse()
+        assertThat(authContainer.hasBiometricPrompt()).isTrue()
+    }
+
+    @Test
+    fun testShowCredentialUI() {
+        initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+        waitForIdleSync()
+
+        assertThat(authContainer.hasCredentialView()).isTrue()
+        assertThat(authContainer.hasBiometricPrompt()).isFalse()
+    }
+
+    @Test
+    fun testCredentialViewUsesEffectiveUserId() {
+        whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(200)
+        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(200))).thenReturn(
+            DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
+        )
+
+        initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+        waitForIdleSync()
+
+        assertThat(authContainer.hasCredentialPatternView()).isTrue()
+        assertThat(authContainer.hasBiometricPrompt()).isFalse()
+    }
+
+    @Test
+    fun testCredentialUI_disablesClickingOnBackground() {
+        whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(20)
+        whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20))).thenReturn(
+            DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+        )
+
+        // In the credential view, clicking on the background (to cancel authentication) is not
+        // valid. Thus, the listener should be null, and it should not be in the accessibility
+        // hierarchy.
+        initializeContainer(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
+        waitForIdleSync()
+
+        assertThat(authContainer.hasCredentialPasswordView()).isTrue()
+        assertThat(authContainer.hasBiometricPrompt()).isFalse()
+        assertThat(
+            authContainer.findViewById<View>(R.id.background)?.isImportantForAccessibility
+        ).isFalse()
+
+        authContainer.findViewById<View>(R.id.background)?.performClick()
+        waitForIdleSync()
+
+        assertThat(authContainer.hasCredentialPasswordView()).isTrue()
+        assertThat(authContainer.hasBiometricPrompt()).isFalse()
+    }
+
+    @Test
+    fun testLayoutParams_hasSecureWindowFlag() {
+        val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+        assertThat((layoutParams.flags and WindowManager.LayoutParams.FLAG_SECURE) != 0).isTrue()
+    }
+
+    @Test
+    fun testLayoutParams_excludesImeInsets() {
+        val layoutParams = AuthContainerView.getLayoutParams(windowToken, "")
+        assertThat((layoutParams.fitInsetsTypes and WindowInsets.Type.ime()) == 0).isTrue()
+    }
+
+    private fun initializeContainer(authenticators: Int) {
+        val config = AuthContainerView.Config()
+        config.mContext = mContext
+        config.mCallback = callback
+        config.mSensorIds = intArrayOf(0)
+        config.mSkipAnimation = true
+        config.mPromptInfo = PromptInfo()
+        config.mPromptInfo.authenticators = authenticators
+        val componentInfo = listOf(
+            ComponentInfoInternal(
+                "faceSensor" /* componentId */,
+                "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */,
+                "00000001" /* serialNumber */, "" /* softwareVersion */
+            ),
+            ComponentInfoInternal(
+                "matchingAlgorithm" /* componentId */,
+                "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */,
+                "vendor/version/revision" /* softwareVersion */
+            )
+        )
+        val fpProps = listOf(
+            FingerprintSensorPropertiesInternal(
+                0,
+                SensorProperties.STRENGTH_STRONG,
+                5 /* maxEnrollmentsPerUser */,
+                componentInfo,
+                FingerprintSensorProperties.TYPE_REAR,
+                false /* resetLockoutRequiresHardwareAuthToken */
+            )
+        )
+        authContainer = TestAuthContainerView(
+            config,
+            fpProps,
+            listOf(),
+            wakefulnessLifecycle,
+            userManager,
+            lockPatternUtils,
+            Handler(TestableLooper.get(this).looper)
+        )
+        ViewUtils.attachView(authContainer)
+    }
+
+    private inner class TestAuthContainerView(
+        config: Config,
+        fpProps: List<FingerprintSensorPropertiesInternal>,
+        faceProps: List<FaceSensorPropertiesInternal>,
+        wakefulnessLifecycle: WakefulnessLifecycle,
+        userManager: UserManager,
+        lockPatternUtils: LockPatternUtils,
+        mainHandler: Handler
+    ) : AuthContainerView(
+        config, fpProps, faceProps,
+        wakefulnessLifecycle, userManager, lockPatternUtils, mainHandler
+    ) {
+        override fun postOnAnimation(runnable: Runnable) {
+            runnable.run()
+        }
+    }
+
+    override fun waitForIdleSync() {
+        TestableLooper.get(this).processAllMessages()
+        super.waitForIdleSync()
+    }
+}
+
+private fun AuthContainerView.hasBiometricPrompt() =
+    (findViewById<ScrollView>(R.id.biometric_scrollview)?.childCount ?: 0) > 0
+
+private fun AuthContainerView.hasCredentialView() =
+    hasCredentialPatternView() || hasCredentialPasswordView()
+
+private fun AuthContainerView.hasCredentialPatternView() =
+    findViewById<View>(R.id.lockPattern) != null
+
+private fun AuthContainerView.hasCredentialPasswordView() =
+    findViewById<View>(R.id.lockPassword) != null
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index c37e966..cfac9651 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -16,8 +16,9 @@
 
 package com.android.systemui.biometrics;
 
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
-import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT;
+import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNull;
@@ -62,6 +63,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.os.UserManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableContext;
 import android.testing.TestableLooper;
@@ -71,6 +73,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -79,6 +82,8 @@
 import com.android.systemui.util.concurrency.FakeExecution;
 
 import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.AdditionalMatchers;
@@ -86,7 +91,8 @@
 import org.mockito.Captor;
 import org.mockito.InOrder;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -94,11 +100,15 @@
 
 import javax.inject.Provider;
 
+@Ignore
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
 @SmallTest
 public class AuthControllerTest extends SysuiTestCase {
 
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
     @Mock
     private PackageManager mPackageManager;
     @Mock
@@ -128,6 +138,10 @@
     @Mock
     private WakefulnessLifecycle mWakefulnessLifecycle;
     @Mock
+    private UserManager mUserManager;
+    @Mock
+    private LockPatternUtils mLockPatternUtils;
+    @Mock
     private StatusBarStateController mStatusBarStateController;
     @Captor
     ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
@@ -144,8 +158,6 @@
 
     @Before
     public void setup() throws RemoteException {
-        MockitoAnnotations.initMocks(this);
-
         mContextSpy = spy(mContext);
         mExecution = new FakeExecution();
         mTestableLooper = TestableLooper.get(this);
@@ -343,8 +355,8 @@
     @Test
     public void testOnAuthenticationSucceededInvoked_whenSystemRequested() {
         showDialog(new int[] {1} /* sensorIds */, false /* credentialAllowed */);
-        mAuthController.onBiometricAuthenticated();
-        verify(mDialog1).onAuthenticationSucceeded();
+        mAuthController.onBiometricAuthenticated(TYPE_FINGERPRINT);
+        verify(mDialog1).onAuthenticationSucceeded(eq(TYPE_FINGERPRINT));
     }
 
     @Test
@@ -528,8 +540,7 @@
         doAnswer(invocation -> {
             Object[] args = invocation.getArguments();
             Bundle savedState = (Bundle) args[0];
-            savedState.putInt(
-                    AuthDialog.KEY_CONTAINER_STATE, AuthContainerView.STATE_SHOWING);
+            savedState.putBoolean(AuthDialog.KEY_CONTAINER_GOING_AWAY, false);
             return null; // onSaveState returns void
         }).when(mDialog1).onSaveState(any());
 
@@ -558,8 +569,7 @@
         doAnswer(invocation -> {
             Object[] args = invocation.getArguments();
             Bundle savedState = (Bundle) args[0];
-            savedState.putInt(
-                    AuthDialog.KEY_CONTAINER_STATE, AuthContainerView.STATE_SHOWING);
+            savedState.putBoolean(AuthDialog.KEY_CONTAINER_GOING_AWAY, false);
             savedState.putBoolean(AuthDialog.KEY_CREDENTIAL_SHOWING, true);
             return null; // onSaveState returns void
         }).when(mDialog1).onSaveState(any());
@@ -697,7 +707,7 @@
                 0 /* operationId */,
                 "testPackage",
                 1 /* requestId */,
-                BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT);
+                BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE);
     }
 
     private PromptInfo createTestPromptInfo() {
@@ -739,15 +749,16 @@
             super(context, execution, commandQueue, activityTaskManager, windowManager,
                     fingerprintManager, faceManager, udfpsControllerFactory,
                     sidefpsControllerFactory, mDisplayManager, mWakefulnessLifecycle,
-                    statusBarStateController, mHandler);
+                    mUserManager, mLockPatternUtils, statusBarStateController, mHandler);
         }
 
         @Override
         protected AuthDialog buildDialog(PromptInfo promptInfo,
-                boolean requireConfirmation, int userId, int[] sensorIds, boolean credentialAllowed,
+                boolean requireConfirmation, int userId, int[] sensorIds,
                 String opPackageName, boolean skipIntro, long operationId, long requestId,
                 @BiometricManager.BiometricMultiSensorMode int multiSensorConfig,
-                WakefulnessLifecycle wakefulnessLifecycle) {
+                WakefulnessLifecycle wakefulnessLifecycle, UserManager userManager,
+                LockPatternUtils lockPatternUtils) {
 
             mLastBiometricPromptInfo = promptInfo;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
index 5128ccc..ec2c1de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
@@ -32,7 +32,7 @@
 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.StatusBar
+import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.leak.RotationUtils
@@ -61,7 +61,7 @@
     private lateinit var staticMockSession: MockitoSession
 
     private lateinit var controller: AuthRippleController
-    @Mock private lateinit var statusBar: StatusBar
+    @Mock private lateinit var mCentralSurfaces: CentralSurfaces
     @Mock private lateinit var rippleView: AuthRippleView
     @Mock private lateinit var commandRegistry: CommandRegistry
     @Mock private lateinit var configurationController: ConfigurationController
@@ -89,7 +89,7 @@
         `when`(udfpsControllerProvider.get()).thenReturn(udfpsController)
 
         controller = AuthRippleController(
-            statusBar,
+            mCentralSurfaces,
             context,
             authController,
             configurationController,
@@ -105,7 +105,7 @@
             rippleView
         )
         controller.init()
-        `when`(statusBar.lightRevealScrim).thenReturn(lightRevealScrim)
+        `when`(mCentralSurfaces.lightRevealScrim).thenReturn(lightRevealScrim)
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
index 254fc59..839c0ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
@@ -17,10 +17,10 @@
 package com.android.systemui.biometrics
 
 import android.animation.Animator
-import android.graphics.Insets
 import android.app.ActivityManager
 import android.app.ActivityTaskManager
 import android.content.ComponentName
+import android.graphics.Insets
 import android.graphics.Rect
 import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_KEYGUARD
 import android.hardware.biometrics.BiometricOverlayConstants.REASON_AUTH_SETTINGS
@@ -65,8 +65,8 @@
 import org.mockito.Mockito.`when`
 import org.mockito.Mockito.any
 import org.mockito.Mockito.anyFloat
-import org.mockito.Mockito.anyLong
 import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.anyLong
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 066a866..ef82c3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -57,9 +57,9 @@
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
 import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when` as whenever
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
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 35e838b..1856fda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -65,7 +65,7 @@
 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.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.phone.SystemUIDialogManager;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
@@ -121,7 +121,7 @@
     @Mock
     private StatusBarStateController mStatusBarStateController;
     @Mock
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     @Mock
     private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
index e9a4e15..186f2bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerTest.java
@@ -124,6 +124,7 @@
         when(mView.getContext()).thenReturn(mResourceContext);
         when(mResourceContext.getString(anyInt())).thenReturn("test string");
         when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(false);
+        when(mView.getDialogSuggestedAlpha()).thenReturn(1f);
         mController = new UdfpsKeyguardViewController(
                 mView,
                 mStatusBarStateController,
@@ -144,7 +145,7 @@
     @Test
     public void testRegistersExpansionChangedListenerOnAttached() {
         mController.onViewAttached();
-        captureExpansionListeners();
+        captureStatusBarExpansionListeners();
     }
 
     @Test
@@ -166,14 +167,14 @@
 
         mController.onViewAttached();
         verify(mView, atLeast(1)).setPauseAuth(true);
-        verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount);
+        verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount, true);
     }
 
     @Test
     public void testListenersUnregisteredOnDetached() {
         mController.onViewAttached();
         captureStatusBarStateListeners();
-        captureExpansionListeners();
+        captureStatusBarExpansionListeners();
         captureKeyguardStateControllerCallback();
         mController.onViewDetached();
 
@@ -193,17 +194,48 @@
         final float eased = .65f;
         mStatusBarStateListener.onDozeAmountChanged(linear, eased);
 
-        verify(mView).onDozeAmountChanged(linear, eased);
+        verify(mView).onDozeAmountChanged(linear, eased, true);
     }
 
     @Test
     public void testShouldPauseAuthBouncerShowing() {
         mController.onViewAttached();
         captureStatusBarStateListeners();
-
         sendStatusBarStateChanged(StatusBarState.KEYGUARD);
 
-        assertFalse(mController.shouldPauseAuth());
+        captureAltAuthInterceptor();
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+        mAltAuthInterceptor.onBouncerVisibilityChanged();
+
+        assertTrue(mController.shouldPauseAuth());
+    }
+
+    @Test
+    public void testShouldPauseAuthDialogSuggestedAlpha0() {
+        mController.onViewAttached();
+        captureStatusBarStateListeners();
+
+        when(mView.getDialogSuggestedAlpha()).thenReturn(0f);
+        sendStatusBarStateChanged(StatusBarState.KEYGUARD);
+
+        assertTrue(mController.shouldPauseAuth());
+    }
+
+    @Test
+    public void testFadeFromDialogSuggestedAlpha() {
+        // GIVEN view is attached and status bar expansion is 1f
+        mController.onViewAttached();
+        captureStatusBarStateListeners();
+        captureStatusBarExpansionListeners();
+        updateStatusBarExpansion(1f, true);
+        reset(mView);
+
+        // WHEN dialog suggested alpha is .6f
+        when(mView.getDialogSuggestedAlpha()).thenReturn(.6f);
+        sendStatusBarStateChanged(StatusBarState.KEYGUARD);
+
+        // THEN alpha is updated based on dialog suggested alpha
+        verify(mView).setUnpausedAlpha((int) (.6f * 255));
     }
 
     @Test
@@ -367,7 +399,7 @@
     public void testFadeInWithStatusBarExpansion() {
         // GIVEN view is attached
         mController.onViewAttached();
-        captureExpansionListeners();
+        captureStatusBarExpansionListeners();
         captureKeyguardStateControllerCallback();
         reset(mView);
 
@@ -382,7 +414,7 @@
     public void testShowUdfpsBouncer() {
         // GIVEN view is attached and status bar expansion is 0
         mController.onViewAttached();
-        captureExpansionListeners();
+        captureStatusBarExpansionListeners();
         captureKeyguardStateControllerCallback();
         captureAltAuthInterceptor();
         updateStatusBarExpansion(0, true);
@@ -401,9 +433,10 @@
     public void testTransitionToFullShadeProgress() {
         // GIVEN view is attached and status bar expansion is 1f
         mController.onViewAttached();
-        captureExpansionListeners();
+        captureStatusBarExpansionListeners();
         updateStatusBarExpansion(1f, true);
         reset(mView);
+        when(mView.getDialogSuggestedAlpha()).thenReturn(1f);
 
         // WHEN we're transitioning to the full shade
         float transitionProgress = .6f;
@@ -417,7 +450,7 @@
     public void testShowUdfpsBouncer_transitionToFullShadeProgress() {
         // GIVEN view is attached and status bar expansion is 1f
         mController.onViewAttached();
-        captureExpansionListeners();
+        captureStatusBarExpansionListeners();
         captureKeyguardStateControllerCallback();
         captureAltAuthInterceptor();
         updateStatusBarExpansion(1f, true);
@@ -440,7 +473,7 @@
         mStatusBarStateListener = mStateListenerCaptor.getValue();
     }
 
-    private void captureExpansionListeners() {
+    private void captureStatusBarExpansionListeners() {
         verify(mPanelExpansionStateManager, times(2))
                 .addExpansionListener(mExpansionListenerCaptor.capture());
         // first (index=0) is from super class, UdfpsAnimationViewController.
@@ -460,8 +493,6 @@
         mAltAuthInterceptor = mAltAuthInterceptorCaptor.getValue();
     }
 
-
-
     private void captureKeyguardStateControllerCallback() {
         verify(mKeyguardStateController).addCallback(
                 mKeyguardStateControllerCallbackCaptor.capture());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index 2cd470e..3d8d128 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -38,11 +38,11 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.nullable
 import org.mockito.Mockito.never
-import org.mockito.Mockito.`when` as whenever
+import org.mockito.Mockito.nullable
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
 
 private const val DISPLAY_ID = "" // default display id
 private const val SENSOR_X = 50
diff --git a/packages/SystemUI/tests/src/com/android/systemui/chooser/ChooserHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/chooser/ChooserHelperTest.java
deleted file mode 100644
index ecfb9ee..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/chooser/ChooserHelperTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.chooser;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Activity;
-import android.app.ActivityTaskManager;
-import android.content.Intent;
-import android.os.Binder;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ChooserHelperTest extends SysuiTestCase {
-
-    @Test
-    public void testOnChoose_CallsStartActivityAsCallerWithToken() {
-        final Intent intent = new Intent();
-        final Binder token = new Binder();
-        intent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, token);
-
-        final Activity mockActivity = mock(Activity.class);
-        when(mockActivity.getIntent()).thenReturn(intent);
-
-        ChooserHelper.onChoose(mockActivity);
-        verify(mockActivity, times(1)).startActivityAsCaller(
-                any(), any(), eq(token), anyBoolean(), anyInt());
-    }
-}
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 9908d44..da25c62 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
@@ -16,15 +16,22 @@
 
 package com.android.systemui.controls.ui
 
+import android.database.ContentObserver
+import android.net.Uri
+import android.os.Handler
+import android.provider.Settings
+import android.test.suitebuilder.annotation.SmallTest
 import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.controls.ControlsMetricsLogger
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.concurrency.DelayableExecutor
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.settings.SecureSettings
 import com.android.wm.shell.TaskViewFactory
+import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -44,7 +51,6 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 class ControlActionCoordinatorImplTest : SysuiTestCase() {
-
     @Mock
     private lateinit var vibratorHelper: VibratorHelper
     @Mock
@@ -61,6 +67,10 @@
     private lateinit var cvh: ControlViewHolder
     @Mock
     private lateinit var metricsLogger: ControlsMetricsLogger
+    @Mock
+    private lateinit var secureSettings: SecureSettings
+    @Mock
+    private lateinit var mainHandler: Handler
 
     companion object {
         fun <T> any(): T = Mockito.any<T>()
@@ -75,16 +85,24 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
+        `when`(secureSettings.getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
+                .thenReturn(Settings.Secure
+                        .getUriFor(Settings.Secure.LOCKSCREEN_ALLOW_TRIVIAL_CONTROLS))
+
         coordinator = spy(ControlActionCoordinatorImpl(
-            mContext,
-            bgExecutor,
-            uiExecutor,
-            activityStarter,
-            keyguardStateController,
-            taskViewFactory,
-            metricsLogger,
-            vibratorHelper
-        ))
+                mContext,
+                bgExecutor,
+                uiExecutor,
+                activityStarter,
+                keyguardStateController,
+                taskViewFactory,
+                metricsLogger,
+                vibratorHelper,
+                secureSettings,
+                mainHandler))
+
+        verify(secureSettings).registerContentObserver(any(Uri::class.java),
+                anyBoolean(), any(ContentObserver::class.java))
 
         `when`(cvh.cws.ci.controlId).thenReturn(ID)
         `when`(cvh.cws.control?.isAuthRequired()).thenReturn(true)
@@ -126,10 +144,23 @@
     fun testToggleRunsWhenLockedAndAuthNotRequired() {
         `when`(keyguardStateController.isShowing()).thenReturn(true)
         `when`(keyguardStateController.isUnlocked()).thenReturn(false)
-        `when`(cvh.cws.control?.isAuthRequired()).thenReturn(false)
+        doReturn(false).`when`(coordinator).isAuthRequired(
+                any(), anyBoolean())
 
         coordinator.toggle(cvh, "", true)
+
         verify(coordinator).bouncerOrRun(action, false /* authRequired */)
         verify(action).invoke()
     }
+
+    @Test
+    fun testIsAuthRequired() {
+        `when`(cvh.cws.control?.isAuthRequired).thenReturn(true)
+        assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
+
+        `when`(cvh.cws.control?.isAuthRequired).thenReturn(false)
+        assertThat(coordinator.isAuthRequired(cvh, false)).isTrue()
+
+        assertThat(coordinator.isAuthRequired(cvh, true)).isFalse()
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
index 12096bc..af3f24a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
@@ -210,4 +210,25 @@
                 eq(actionCallbackService))
         assertEquals(action, wrapperCaptor.getValue().getWrappedAction())
     }
+
+    @Test
+    fun testFalseBindCallsUnbind() {
+        val falseContext = mock(Context::class.java)
+        `when`(falseContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(false)
+        val manager = ControlsProviderLifecycleManager(
+            falseContext,
+            executor,
+            actionCallbackService,
+            UserHandle.of(0),
+            componentName
+        )
+        manager.bindService()
+        executor.runAllReady()
+
+        val captor = ArgumentCaptor.forClass(
+            ServiceConnection::class.java
+        )
+        verify(falseContext).bindServiceAsUser(any(), captor.capture(), anyInt(), any())
+        verify(falseContext).unbindService(captor.value)
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index 5684429..3340f2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -143,8 +143,8 @@
     }
 
     @Test
-    public void testInitialize_dozeSuppressed_alwaysOnDisabled_goesToDoze() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testInitialize_alwaysOnSuppressed_alwaysOnDisabled_goesToDoze() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
 
         mMachine.requestState(INITIALIZED);
@@ -154,8 +154,8 @@
     }
 
     @Test
-    public void testInitialize_dozeSuppressed_alwaysOnEnabled_goesToDoze() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testInitialize_alwaysOnSuppressed_alwaysOnEnabled_goesToDoze() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
 
         mMachine.requestState(INITIALIZED);
@@ -165,8 +165,8 @@
     }
 
     @Test
-    public void testInitialize_dozeSuppressed_afterDocked_goesToDoze() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testInitialize_alwaysOnSuppressed_afterDocked_goesToDoze() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mDockManager.isDocked()).thenReturn(true);
 
         mMachine.requestState(INITIALIZED);
@@ -176,8 +176,8 @@
     }
 
     @Test
-    public void testInitialize_dozeSuppressed_alwaysOnDisabled_afterDockPaused_goesToDoze() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testInitialize_alwaysOnSuppressed_alwaysOnDisabled_afterDockPaused_goesToDoze() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
         when(mDockManager.isDocked()).thenReturn(true);
         when(mDockManager.isHidden()).thenReturn(true);
@@ -189,8 +189,8 @@
     }
 
     @Test
-    public void testInitialize_dozeSuppressed_alwaysOnEnabled_afterDockPaused_goesToDoze() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testInitialize_alwaysOnSuppressed_alwaysOnEnabled_afterDockPaused_goesToDoze() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
         when(mDockManager.isDocked()).thenReturn(true);
         when(mDockManager.isHidden()).thenReturn(true);
@@ -228,8 +228,8 @@
     }
 
     @Test
-    public void testPulseDone_dozeSuppressed_goesToSuppressed() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testPulseDone_alwaysOnSuppressed_goesToSuppressed() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
         mMachine.requestState(INITIALIZED);
         mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
@@ -266,8 +266,8 @@
     }
 
     @Test
-    public void testPulseDone_dozeSuppressed_afterDocked_goesToDoze() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testPulseDone_alwaysOnSuppressed_afterDocked_goesToDoze() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mDockManager.isDocked()).thenReturn(true);
         mMachine.requestState(INITIALIZED);
         mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
@@ -295,8 +295,8 @@
     }
 
     @Test
-    public void testPulseDone_dozeSuppressed_afterDockPaused_goesToDoze() {
-        when(mHost.isDozeSuppressed()).thenReturn(true);
+    public void testPulseDone_alwaysOnSuppressed_afterDockPaused_goesToDoze() {
+        when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
         when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
         when(mDockManager.isDocked()).thenReturn(true);
         when(mDockManager.isHidden()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
new file mode 100644
index 0000000..aa0a909
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSuppressorTest.java
@@ -0,0 +1,231 @@
+/*
+ * 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 andatest
+ * limitations under the License.
+ */
+
+package com.android.systemui.doze;
+
+import static com.android.systemui.doze.DozeMachine.State.DOZE;
+import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
+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.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.UiModeManager;
+import android.content.BroadcastReceiver;
+import android.content.res.Configuration;
+import android.hardware.display.AmbientDisplayConfiguration;
+import android.testing.AndroidTestingRunner;
+import android.testing.UiThreadTest;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+
+import org.junit.After;
+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 dagger.Lazy;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@UiThreadTest
+public class DozeSuppressorTest extends SysuiTestCase {
+
+    DozeSuppressor mDozeSuppressor;
+    @Mock
+    private DozeLog mDozeLog;
+    @Mock
+    private DozeHost mDozeHost;
+    @Mock
+    private AmbientDisplayConfiguration mConfig;
+    @Mock
+    private BroadcastDispatcher mBroadcastDispatcher;
+    @Mock
+    private UiModeManager mUiModeManager;
+    @Mock
+    private Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
+    @Mock
+    private BiometricUnlockController mBiometricUnlockController;
+
+    @Mock
+    private DozeMachine mDozeMachine;
+
+    @Captor
+    private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
+    private BroadcastReceiver mBroadcastReceiver;
+
+    @Captor
+    private ArgumentCaptor<DozeHost.Callback> mDozeHostCaptor;
+    private DozeHost.Callback mDozeHostCallback;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        // setup state for NOT ending doze immediately
+        when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
+        when(mBiometricUnlockController.hasPendingAuthentication()).thenReturn(false);
+        when(mDozeHost.isProvisioned()).thenReturn(true);
+
+        mDozeSuppressor = new DozeSuppressor(
+                mDozeHost,
+                mConfig,
+                mDozeLog,
+                mBroadcastDispatcher,
+                mUiModeManager,
+                mBiometricUnlockControllerLazy);
+
+        mDozeSuppressor.setDozeMachine(mDozeMachine);
+    }
+
+    @After
+    public void tearDown() {
+        mDozeSuppressor.destroy();
+    }
+
+    @Test
+    public void testRegistersListenersOnInitialized_unregisteredOnFinish() {
+        // check that receivers and callbacks registered
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        captureBroadcastReceiver();
+        captureDozeHostCallback();
+
+        // check that receivers and callbacks are unregistered
+        mDozeSuppressor.transitionTo(INITIALIZED, FINISH);
+        verify(mBroadcastDispatcher).unregisterReceiver(mBroadcastReceiver);
+        verify(mDozeHost).removeCallback(mDozeHostCallback);
+    }
+
+    @Test
+    public void testEndDoze_carMode() {
+        // GIVEN car mode
+        when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
+
+        // WHEN dozing begins
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+
+        // THEN doze immediately ends
+        verify(mDozeMachine).requestState(FINISH);
+    }
+
+    @Test
+    public void testEndDoze_unprovisioned() {
+        // GIVEN device unprovisioned
+        when(mDozeHost.isProvisioned()).thenReturn(false);
+
+        // WHEN dozing begins
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+
+        // THEN doze immediately ends
+        verify(mDozeMachine).requestState(FINISH);
+    }
+
+    @Test
+    public void testEndDoze_hasPendingUnlock() {
+        // GIVEN device unprovisioned
+        when(mBiometricUnlockController.hasPendingAuthentication()).thenReturn(true);
+
+        // WHEN dozing begins
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+
+        // THEN doze immediately ends
+        verify(mDozeMachine).requestState(FINISH);
+    }
+
+    @Test
+    public void testPowerSaveChanged_active() {
+        // GIVEN AOD power save is active and doze is initialized
+        when(mDozeHost.isPowerSaveActive()).thenReturn(true);
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        captureDozeHostCallback();
+
+        // WHEN power save change gets triggered (even if active = false, since it
+        // may differ from the aodPowerSaveActive state reported by DostHost)
+        mDozeHostCallback.onPowerSaveChanged(false);
+
+        // THEN the state changes to DOZE
+        verify(mDozeMachine).requestState(DOZE);
+    }
+
+    @Test
+    public void testPowerSaveChanged_notActive() {
+        // GIVEN DOZE (not showing aod content)
+        when(mConfig.alwaysOnEnabled(anyInt())).thenReturn(true);
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        when(mDozeMachine.getState()).thenReturn(DOZE);
+        captureDozeHostCallback();
+
+        // WHEN power save mode is no longer active
+        when(mDozeHost.isPowerSaveActive()).thenReturn(false);
+        mDozeHostCallback.onPowerSaveChanged(false);
+
+        // THEN the state changes to DOZE_AOD
+        verify(mDozeMachine).requestState(DOZE_AOD);
+    }
+
+    @Test
+    public void testAlwaysOnSuppressedChanged_nowSuppressed() {
+        // GIVEN DOZE_AOD
+        when(mConfig.alwaysOnEnabled(anyInt())).thenReturn(true);
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        when(mDozeMachine.getState()).thenReturn(DOZE_AOD);
+        captureDozeHostCallback();
+
+        // WHEN alwaysOnSuppressedChanged to suppressed=true
+        mDozeHostCallback.onAlwaysOnSuppressedChanged(true);
+
+        // THEN DOZE requested
+        verify(mDozeMachine).requestState(DOZE);
+    }
+
+    @Test
+    public void testAlwaysOnSuppressedChanged_notSuppressed() {
+        // GIVEN DOZE
+        when(mConfig.alwaysOnEnabled(anyInt())).thenReturn(true);
+        mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
+        when(mDozeMachine.getState()).thenReturn(DOZE);
+        captureDozeHostCallback();
+
+        // WHEN alwaysOnSuppressedChanged to suppressed=false
+        mDozeHostCallback.onAlwaysOnSuppressedChanged(false);
+
+        // THEN DOZE_AOD requested
+        verify(mDozeMachine).requestState(DOZE_AOD);
+    }
+
+    private void captureDozeHostCallback() {
+        verify(mDozeHost).addCallback(mDozeHostCaptor.capture());
+        mDozeHostCallback = mDozeHostCaptor.getValue();
+    }
+
+    private void captureBroadcastReceiver() {
+        verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(),
+                anyObject());
+        mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
+    }
+}
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 7af039b..ff9e13a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -17,9 +17,7 @@
 package com.android.systemui.dreams;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -35,7 +33,6 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dreams.complication.ComplicationHostViewController;
-import com.android.systemui.dreams.complication.dagger.ComplicationHostViewComponent;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -50,6 +47,7 @@
     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;
 
     @Mock
     Resources mResources;
@@ -67,12 +65,6 @@
     ComplicationHostViewController mComplicationHostViewController;
 
     @Mock
-    ComplicationHostViewComponent.Factory mComplicationHostViewComponentFactory;
-
-    @Mock
-    ComplicationHostViewComponent mComplicationHostViewComponent;
-
-    @Mock
     ViewGroup mDreamOverlayContentView;
 
     @Mock
@@ -89,19 +81,16 @@
                         DREAM_OVERLAY_NOTIFICATIONS_DRAG_AREA_HEIGHT);
         when(mDreamOverlayContainerView.getResources()).thenReturn(mResources);
         when(mDreamOverlayContainerView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
-        when(mComplicationHostViewComponentFactory.create())
-                .thenReturn(mComplicationHostViewComponent);
-        when(mComplicationHostViewComponent.getController())
-                .thenReturn(mComplicationHostViewController);
 
         mController = new DreamOverlayContainerViewController(
                 mDreamOverlayContainerView,
-                mComplicationHostViewComponentFactory,
+                mComplicationHostViewController,
                 mDreamOverlayContentView,
                 mDreamOverlayStatusBarViewController,
                 mHandler,
                 MAX_BURN_IN_OFFSET,
-                BURN_IN_PROTECTION_UPDATE_INTERVAL);
+                BURN_IN_PROTECTION_UPDATE_INTERVAL,
+                MILLIS_UNTIL_FULL_JITTER);
     }
 
     @Test
@@ -118,31 +107,6 @@
     }
 
     @Test
-    public void testOnViewAttachedRegistersComputeInsetsListener() {
-        mController.onViewAttached();
-        verify(mViewTreeObserver).addOnComputeInternalInsetsListener(any());
-    }
-
-    @Test
-    public void testOnViewDetachedUnregistersComputeInsetsListener() {
-        mController.onViewDetached();
-        verify(mViewTreeObserver).removeOnComputeInternalInsetsListener(any());
-    }
-
-    @Test
-    public void testComputeInsetsListenerReturnsRegion() {
-        final ArgumentCaptor<ViewTreeObserver.OnComputeInternalInsetsListener>
-                computeInsetsListenerCapture =
-                ArgumentCaptor.forClass(ViewTreeObserver.OnComputeInternalInsetsListener.class);
-        mController.onViewAttached();
-        verify(mViewTreeObserver).addOnComputeInternalInsetsListener(
-                computeInsetsListenerCapture.capture());
-        final ViewTreeObserver.InternalInsetsInfo info = new ViewTreeObserver.InternalInsetsInfo();
-        computeInsetsListenerCapture.getValue().onComputeInternalInsets(info);
-        assertNotNull(info.touchableRegion);
-    }
-
-    @Test
     public void testBurnInProtectionStartsWhenContentViewAttached() {
         mController.onViewAttached();
         verify(mHandler).postDelayed(any(Runnable.class), eq(BURN_IN_PROTECTION_UPDATE_INTERVAL));
@@ -155,14 +119,14 @@
     }
 
     @Test
-    public void testBurnInProtectionUpdatesPeriodically() {
+    public void testBurnInProtectionOffsetsStartAtZero() {
         ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
         mController.onViewAttached();
         verify(mHandler).postDelayed(
                 runnableCaptor.capture(), eq(BURN_IN_PROTECTION_UPDATE_INTERVAL));
         runnableCaptor.getValue().run();
-        verify(mDreamOverlayContainerView).setTranslationX(anyFloat());
-        verify(mDreamOverlayContainerView).setTranslationY(anyFloat());
+        verify(mDreamOverlayContainerView).setTranslationX(0.f);
+        verify(mDreamOverlayContainerView).setTranslationY(0.f);
     }
 
     @Test
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 58ffbfa..7d7ccb4 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;
 
@@ -28,6 +29,7 @@
 import android.service.dreams.IDreamOverlay;
 import android.service.dreams.IDreamOverlayCallback;
 import android.testing.AndroidTestingRunner;
+import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
 
@@ -38,6 +40,7 @@
 
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dreams.complication.DreamPreviewComplication;
 import com.android.systemui.dreams.dagger.DreamOverlayComponent;
 import com.android.systemui.dreams.touch.DreamOverlayTouchMonitor;
 import com.android.systemui.util.concurrency.FakeExecutor;
@@ -95,6 +98,12 @@
     @Mock
     DreamOverlayStateController mStateController;
 
+    @Mock
+    DreamPreviewComplication mPreviewComplication;
+
+    @Mock
+    ViewGroup mDreamOverlayContainerViewParent;
+
     DreamOverlayService mService;
 
     @Before
@@ -119,7 +128,8 @@
         mService = new DreamOverlayService(mContext, mMainExecutor,
                 mDreamOverlayComponentFactory,
                 mStateController,
-                mKeyguardUpdateMonitor);
+                mKeyguardUpdateMonitor,
+                mPreviewComplication);
     }
 
     @Test
@@ -147,6 +157,23 @@
     }
 
     @Test
+    public void testDreamOverlayContainerViewRemovedFromOldParentWhenInitialized()
+            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);
+        mMainExecutor.runAllReady();
+
+        verify(mDreamOverlayContainerViewParent).removeView(mDreamOverlayContainerView);
+    }
+
+    @Test
     public void testShouldShowComplicationsTrueByDefault() {
         mService.onBind(new Intent());
 
@@ -163,6 +190,31 @@
     }
 
     @Test
+    public void testPreviewModeFalseByDefault() {
+        mService.onBind(new Intent());
+
+        assertThat(mService.isPreviewMode()).isFalse();
+    }
+
+    @Test
+    public void testPreviewModeSetByIntentExtra() {
+        final Intent intent = new Intent();
+        intent.putExtra(DreamService.EXTRA_IS_PREVIEW, true);
+        mService.onBind(intent);
+
+        assertThat(mService.isPreviewMode()).isTrue();
+    }
+
+    @Test
+    public void testDreamLabel() {
+        final Intent intent = new Intent();
+        intent.putExtra(DreamService.EXTRA_DREAM_LABEL, "TestDream");
+        mService.onBind(intent);
+
+        assertThat(mService.getDreamLabel()).isEqualTo("TestDream");
+    }
+
+    @Test
     public void testDestroy() {
         mService.onDestroy();
         mMainExecutor.runAllReady();
@@ -171,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/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index 515a1ac8..49da4bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -61,7 +61,7 @@
     }
 
     @Test
-    public void testStateChange() {
+    public void testStateChange_overlayActive() {
         final DreamOverlayStateController stateController = new DreamOverlayStateController(
                 mExecutor);
         stateController.addCallback(mCallback);
@@ -83,6 +83,38 @@
     }
 
     @Test
+    public void testStateChange_isPreviewMode() {
+        final DreamOverlayStateController stateController = new DreamOverlayStateController(
+                mExecutor);
+        stateController.addCallback(mCallback);
+        stateController.setPreviewMode(true);
+        mExecutor.runAllReady();
+
+        verify(mCallback).onStateChanged();
+        assertThat(stateController.isPreviewMode()).isTrue();
+
+        Mockito.clearInvocations(mCallback);
+        stateController.setPreviewMode(true);
+        mExecutor.runAllReady();
+        verify(mCallback, never()).onStateChanged();
+    }
+
+    @Test
+    public void testPreviewModeFalseByDefault() {
+        final DreamOverlayStateController stateController = new DreamOverlayStateController(
+                mExecutor);
+        assertThat(stateController.isPreviewMode()).isFalse();
+    }
+
+    @Test
+    public void testPreviewModeSetToTrue() {
+        final DreamOverlayStateController stateController = new DreamOverlayStateController(
+                mExecutor);
+        stateController.setPreviewMode(true);
+        assertThat(stateController.isPreviewMode()).isTrue();
+    }
+
+    @Test
     public void testCallback() {
         final DreamOverlayStateController stateController = new DreamOverlayStateController(
                 mExecutor);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index 6587029..a32ff80 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -17,18 +17,34 @@
 package com.android.systemui.dreams;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.AlarmManager;
+import android.content.res.Resources;
+import android.hardware.SensorPrivacyManager;
 import android.net.ConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
+import android.provider.Settings;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
 
 import androidx.test.filters.SmallTest;
 
+import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
+import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.touch.TouchInsetManager;
+import com.android.systemui.util.time.DateFormatUtil;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -40,6 +56,8 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase {
+    private static final String NOTIFICATION_INDICATOR_FORMATTER_STRING =
+            "{count, plural, =1 {# notification} other {# notifications}}";
 
     @Mock
     DreamOverlayStatusBarView mView;
@@ -49,13 +67,57 @@
     NetworkCapabilities mNetworkCapabilities;
     @Mock
     Network mNetwork;
+    @Mock
+    TouchInsetManager.TouchInsetSession mTouchSession;
+    @Mock
+    Resources mResources;
+    @Mock
+    AlarmManager mAlarmManager;
+    @Mock
+    AlarmManager.AlarmClockInfo mAlarmClockInfo;
+    @Mock
+    NextAlarmController mNextAlarmController;
+    @Mock
+    DateFormatUtil mDateFormatUtil;
+    @Mock
+    IndividualSensorPrivacyController mSensorPrivacyController;
+    @Mock
+    StatusBarNotification mStatusBarNotification;
+    @Mock
+    NotificationListenerService.RankingMap mRankingMap;
+    @Mock
+    NotificationListener mNotificationListener;
+    @Mock
+    ZenModeController mZenModeController;
 
     DreamOverlayStatusBarViewController mController;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mController = new DreamOverlayStatusBarViewController(mView, mConnectivityManager);
+
+        when(mResources.getString(R.string.dream_overlay_status_bar_notification_indicator))
+                .thenReturn(NOTIFICATION_INDICATOR_FORMATTER_STRING);
+
+        mController = new DreamOverlayStatusBarViewController(
+                mView,
+                mResources,
+                mConnectivityManager,
+                mTouchSession,
+                mAlarmManager,
+                mNextAlarmController,
+                mDateFormatUtil,
+                mSensorPrivacyController,
+                mNotificationListener,
+                mZenModeController);
+    }
+
+    @Test
+    public void testOnViewAttachedAddsCallbacks() {
+        mController.onViewAttached();
+        verify(mNextAlarmController).addCallback(any());
+        verify(mSensorPrivacyController).addCallback(any());
+        verify(mZenModeController).addCallback(any());
     }
 
     @Test
@@ -67,28 +129,97 @@
     }
 
     @Test
-    public void testOnViewAttachedShowsWifiStatusWhenWifiUnavailable() {
+    public void testOnViewAttachedShowsWifiIconWhenWifiUnavailable() {
         when(mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                 .thenReturn(false);
         when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(mNetworkCapabilities);
         mController.onViewAttached();
-        verify(mView).showWifiStatus(true);
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, true);
     }
 
     @Test
-    public void testOnViewAttachedHidesWifiStatusWhenWifiAvailable() {
+    public void testOnViewAttachedHidesWifiIconWhenWifiAvailable() {
         when(mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                 .thenReturn(true);
         when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(mNetworkCapabilities);
         mController.onViewAttached();
-        verify(mView).showWifiStatus(false);
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, false);
     }
 
     @Test
-    public void testOnViewAttachedShowsWifiStatusWhenNetworkCapabilitiesUnavailable() {
+    public void testOnViewAttachedShowsWifiIconWhenNetworkCapabilitiesUnavailable() {
         when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(null);
         mController.onViewAttached();
-        verify(mView).showWifiStatus(true);
+    }
+
+    @Test
+    public void testOnViewAttachedShowsAlarmIconWhenAlarmExists() {
+        when(mAlarmClockInfo.getTriggerTime()).thenReturn(1L);
+        when(mAlarmManager.getNextAlarmClock(anyInt())).thenReturn(mAlarmClockInfo);
+        mController.onViewAttached();
+        verify(mView).showIcon(
+                eq(DreamOverlayStatusBarView.STATUS_ICON_ALARM_SET), eq(true), any());
+    }
+
+    @Test
+    public void testOnViewAttachedHidesAlarmIconWhenNoAlarmExists() {
+        when(mAlarmManager.getNextAlarmClock(anyInt())).thenReturn(null);
+        mController.onViewAttached();
+        verify(mView).showIcon(
+                eq(DreamOverlayStatusBarView.STATUS_ICON_ALARM_SET), eq(false), isNull());
+    }
+
+    @Test
+    public void testOnViewAttachedShowsMicCameraIconWhenDisabled() {
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
+                .thenReturn(true);
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
+                .thenReturn(true);
+        mController.onViewAttached();
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, true);
+    }
+
+    @Test
+    public void testOnViewAttachedHidesMicCameraIconWhenEnabled() {
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
+                .thenReturn(false);
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
+                .thenReturn(false);
+        mController.onViewAttached();
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false);
+    }
+
+    @Test
+    public void testOnViewAttachedShowsNotificationsIconWhenNotificationsExist() {
+        StatusBarNotification[] notifications = { mStatusBarNotification };
+        when(mNotificationListener.getActiveNotifications()).thenReturn(notifications);
+        mController.onViewAttached();
+        verify(mView).showIcon(
+                eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(true), any());
+    }
+
+    @Test
+    public void testOnViewAttachedHidesNotificationsIconWhenNoNotificationsExist() {
+        when(mNotificationListener.getActiveNotifications()).thenReturn(null);
+        mController.onViewAttached();
+        verify(mView).showIcon(
+                eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(false), isNull());
+    }
+
+    @Test
+    public void testOnViewAttachedShowsPriorityModeIconWhenEnabled() {
+        when(mZenModeController.getZen()).thenReturn(
+                Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS);
+        mController.onViewAttached();
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_PRIORITY_MODE_ON, true);
+    }
+
+    @Test
+    public void testOnViewAttachedHidesPriorityModeIconWhenDisabled() {
+        when(mZenModeController.getZen()).thenReturn(
+                Settings.Global.ZEN_MODE_OFF);
+        mController.onViewAttached();
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_PRIORITY_MODE_ON, false);
     }
 
     @Test
@@ -99,10 +230,19 @@
     }
 
     @Test
-    public void testWifiStatusHiddenWhenWifiBecomesAvailable() {
-        // Make sure wifi starts out unavailable when onViewAttached is called.
+    public void testOnViewDetachedRemovesCallbacks() {
+        mController.onViewDetached();
+        verify(mNextAlarmController).removeCallback(any());
+        verify(mSensorPrivacyController).removeCallback(any());
+        verify(mZenModeController).removeCallback(any());
+    }
+
+    @Test
+    public void testWifiIconHiddenWhenWifiBecomesAvailable() {
+        // Make sure wifi starts out unavailable when onViewAttached is called, and then returns
+        // true on the second query.
         when(mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
-                .thenReturn(false);
+                .thenReturn(false).thenReturn(true);
         when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(mNetworkCapabilities);
         mController.onViewAttached();
 
@@ -110,14 +250,15 @@
                 ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
         verify(mConnectivityManager).registerNetworkCallback(any(), callbackCapture.capture());
         callbackCapture.getValue().onAvailable(mNetwork);
-        verify(mView).showWifiStatus(false);
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, false);
     }
 
     @Test
-    public void testWifiStatusShownWhenWifiBecomesUnavailable() {
-        // Make sure wifi starts out available when onViewAttached is called.
+    public void testWifiIconShownWhenWifiBecomesUnavailable() {
+        // Make sure wifi starts out available when onViewAttached is called, then returns false
+        // on the second query.
         when(mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
-                .thenReturn(true);
+                .thenReturn(true).thenReturn(false);
         when(mConnectivityManager.getNetworkCapabilities(any())).thenReturn(mNetworkCapabilities);
         mController.onViewAttached();
 
@@ -125,11 +266,11 @@
                 ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
         verify(mConnectivityManager).registerNetworkCallback(any(), callbackCapture.capture());
         callbackCapture.getValue().onLost(mNetwork);
-        verify(mView).showWifiStatus(true);
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, true);
     }
 
     @Test
-    public void testWifiStatusHiddenWhenCapabilitiesChange() {
+    public void testWifiIconHiddenWhenCapabilitiesChange() {
         // Make sure wifi starts out unavailable when onViewAttached is called.
         when(mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                 .thenReturn(false);
@@ -142,6 +283,102 @@
         when(mNetworkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                 .thenReturn(true);
         callbackCapture.getValue().onCapabilitiesChanged(mNetwork, mNetworkCapabilities);
-        verify(mView).showWifiStatus(false);
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_WIFI_UNAVAILABLE, false);
+    }
+
+    @Test
+    public void testNotificationsIconShownWhenNotificationAdded() {
+        mController.onViewAttached();
+
+        StatusBarNotification[] notifications = { mStatusBarNotification };
+        when(mNotificationListener.getActiveNotifications()).thenReturn(notifications);
+
+        final ArgumentCaptor<NotificationListener.NotificationHandler> callbackCapture =
+                ArgumentCaptor.forClass(NotificationListener.NotificationHandler.class);
+        verify(mNotificationListener).addNotificationHandler(callbackCapture.capture());
+        callbackCapture.getValue().onNotificationPosted(mStatusBarNotification, mRankingMap);
+
+        verify(mView).showIcon(
+                eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(true), any());
+    }
+
+    @Test
+    public void testNotificationsIconHiddenWhenLastNotificationRemoved() {
+        StatusBarNotification[] notifications = { mStatusBarNotification };
+        when(mNotificationListener.getActiveNotifications()).thenReturn(notifications)
+                .thenReturn(null);
+        mController.onViewAttached();
+
+        final ArgumentCaptor<NotificationListener.NotificationHandler> callbackCapture =
+                ArgumentCaptor.forClass(NotificationListener.NotificationHandler.class);
+        verify(mNotificationListener).addNotificationHandler(callbackCapture.capture());
+        callbackCapture.getValue().onNotificationPosted(mStatusBarNotification, mRankingMap);
+
+        verify(mView).showIcon(
+                eq(DreamOverlayStatusBarView.STATUS_ICON_NOTIFICATIONS), eq(false), any());
+    }
+
+    @Test
+    public void testMicCameraIconShownWhenSensorsBlocked() {
+        mController.onViewAttached();
+
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
+                .thenReturn(true);
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
+                .thenReturn(true);
+
+        final ArgumentCaptor<IndividualSensorPrivacyController.Callback> callbackCapture =
+                ArgumentCaptor.forClass(IndividualSensorPrivacyController.Callback.class);
+        verify(mSensorPrivacyController).addCallback(callbackCapture.capture());
+        callbackCapture.getValue().onSensorBlockedChanged(
+                SensorPrivacyManager.Sensors.MICROPHONE, true);
+
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, true);
+    }
+
+    @Test
+    public void testMicCameraIconHiddenWhenSensorsNotBlocked() {
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.MICROPHONE))
+                .thenReturn(true).thenReturn(false);
+        when(mSensorPrivacyController.isSensorBlocked(SensorPrivacyManager.Sensors.CAMERA))
+                .thenReturn(true).thenReturn(false);
+        mController.onViewAttached();
+
+        final ArgumentCaptor<IndividualSensorPrivacyController.Callback> callbackCapture =
+                ArgumentCaptor.forClass(IndividualSensorPrivacyController.Callback.class);
+        verify(mSensorPrivacyController).addCallback(callbackCapture.capture());
+        callbackCapture.getValue().onSensorBlockedChanged(
+                SensorPrivacyManager.Sensors.MICROPHONE, false);
+
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_MIC_CAMERA_DISABLED, false);
+    }
+
+    @Test
+    public void testPriorityModeIconShownWhenZenModeEnabled() {
+        mController.onViewAttached();
+
+        when(mZenModeController.getZen()).thenReturn(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS);
+
+        final ArgumentCaptor<ZenModeController.Callback> callbackCapture =
+                ArgumentCaptor.forClass(ZenModeController.Callback.class);
+        verify(mZenModeController).addCallback(callbackCapture.capture());
+        callbackCapture.getValue().onZenChanged(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS);
+
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_PRIORITY_MODE_ON, true);
+    }
+
+    @Test
+    public void testPriorityModeIconHiddenWhenZenModeDisabled() {
+        when(mZenModeController.getZen()).thenReturn(Settings.Global.ZEN_MODE_NO_INTERRUPTIONS)
+                .thenReturn(Settings.Global.ZEN_MODE_OFF);
+        mController.onViewAttached();
+
+
+        final ArgumentCaptor<ZenModeController.Callback> callbackCapture =
+                ArgumentCaptor.forClass(ZenModeController.Callback.class);
+        verify(mZenModeController).addCallback(callbackCapture.capture());
+        callbackCapture.getValue().onZenChanged(Settings.Global.ZEN_MODE_OFF);
+
+        verify(mView).showIcon(DreamOverlayStatusBarView.STATUS_ICON_PRIORITY_MODE_ON, false);
     }
 }
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/dreams/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
index 64b267d..d1d9ec3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationLayoutEngineTest.java
@@ -29,6 +29,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.touch.TouchInsetManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,6 +47,9 @@
     @Mock
     ConstraintLayout mLayout;
 
+    @Mock
+    TouchInsetManager.TouchInsetSession mTouchSession;
+
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
@@ -112,7 +116,8 @@
                 Complication.CATEGORY_STANDARD,
                 mLayout);
 
-        final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, 0);
+        final ComplicationLayoutEngine engine =
+                new ComplicationLayoutEngine(mLayout, 0, mTouchSession, 0, 0);
         addComplication(engine, firstViewInfo);
 
         // Ensure the view is added to the top end corner
@@ -139,7 +144,8 @@
                 Complication.CATEGORY_STANDARD,
                 mLayout);
 
-        final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, 0);
+        final ComplicationLayoutEngine engine =
+                new ComplicationLayoutEngine(mLayout, 0, mTouchSession, 0, 0);
         addComplication(engine, firstViewInfo);
 
         // Ensure the view is added to the top end corner
@@ -155,7 +161,8 @@
      */
     @Test
     public void testDirectionLayout() {
-        final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, 0);
+        final ComplicationLayoutEngine engine =
+                new ComplicationLayoutEngine(mLayout, 0, mTouchSession, 0, 0);
 
         final ViewInfo firstViewInfo = new ViewInfo(
                 new ComplicationLayoutParams(
@@ -203,7 +210,8 @@
      */
     @Test
     public void testPositionLayout() {
-        final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, 0);
+        final ComplicationLayoutEngine engine =
+                new ComplicationLayoutEngine(mLayout, 0, mTouchSession, 0, 0);
 
         final ViewInfo firstViewInfo = new ViewInfo(
                 new ComplicationLayoutParams(
@@ -290,7 +298,8 @@
     @Test
     public void testMargin() {
         final int margin = 5;
-        final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, margin);
+        final ComplicationLayoutEngine engine =
+                new ComplicationLayoutEngine(mLayout, margin, mTouchSession, 0, 0);
 
         final ViewInfo firstViewInfo = new ViewInfo(
                 new ComplicationLayoutParams(
@@ -364,7 +373,8 @@
      */
     @Test
     public void testRemoval() {
-        final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, 0);
+        final ComplicationLayoutEngine engine =
+                new ComplicationLayoutEngine(mLayout, 0, mTouchSession, 0, 0);
 
         final ViewInfo firstViewInfo = new ViewInfo(
                 new ComplicationLayoutParams(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index cad98f4..6e01541 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyFloat;
@@ -27,19 +26,21 @@
 import static org.mockito.Mockito.when;
 
 import android.animation.ValueAnimator;
+import android.graphics.Rect;
+import android.graphics.Region;
 import android.testing.AndroidTestingRunner;
+import android.util.DisplayMetrics;
 import android.view.GestureDetector;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.shared.system.InputChannelCompat;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
@@ -51,8 +52,6 @@
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
-import java.util.Random;
-
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
@@ -60,7 +59,7 @@
     StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     @Mock
-    StatusBar mStatusBar;
+    CentralSurfaces mCentralSurfaces;
 
     @Mock
     NotificationShadeWindowController mNotificationShadeWindowController;
@@ -89,38 +88,51 @@
     @Mock
     VelocityTracker mVelocityTracker;
 
+    final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+
     private static final float TOUCH_REGION = .3f;
-    private static final float SCREEN_HEIGHT_PX = 100;
+    private static final int SCREEN_WIDTH_PX = 1024;
+    private static final int SCREEN_HEIGHT_PX = 100;
 
     @Before
     public void setup() {
+        mDisplayMetrics.widthPixels = SCREEN_WIDTH_PX;
+        mDisplayMetrics.heightPixels = SCREEN_HEIGHT_PX;
+
         MockitoAnnotations.initMocks(this);
         mTouchHandler = new BouncerSwipeTouchHandler(
+                mDisplayMetrics,
                 mStatusBarKeyguardViewManager,
-                mStatusBar,
+                mCentralSurfaces,
                 mNotificationShadeWindowController,
                 mValueAnimatorCreator,
                 mVelocityTrackerFactory,
                 mFlingAnimationUtils,
                 mFlingAnimationUtilsClosing,
                 TOUCH_REGION);
-        when(mStatusBar.getDisplayHeight()).thenReturn(SCREEN_HEIGHT_PX);
+
+        when(mCentralSurfaces.getDisplayHeight()).thenReturn((float) SCREEN_HEIGHT_PX);
         when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator);
         when(mVelocityTrackerFactory.obtain()).thenReturn(mVelocityTracker);
     }
 
-    private static void beginValidSwipe(GestureDetector.OnGestureListener listener) {
-        listener.onDown(MotionEvent.obtain(0, 0,
-                MotionEvent.ACTION_DOWN, 0,
-                SCREEN_HEIGHT_PX - (.5f * TOUCH_REGION * SCREEN_HEIGHT_PX), 0));
-    }
-
     /**
      * Ensures expansion only happens when touch down happens in valid part of the screen.
      */
-    @FlakyTest
     @Test
     public void testSessionStart() {
+        final Region region = Region.obtain();
+        mTouchHandler.getTouchInitiationRegion(region);
+
+        final Rect bounds = region.getBounds();
+
+        final Rect expected = new Rect();
+
+        expected.set(0, Math.round(SCREEN_HEIGHT_PX * (1 - TOUCH_REGION)), SCREEN_WIDTH_PX,
+                SCREEN_HEIGHT_PX);
+
+        assertThat(bounds).isEqualTo(expected);
+
         mTouchHandler.onSessionStart(mTouchSession);
         verify(mNotificationShadeWindowController).setForcePluginOpen(eq(true), any());
         ArgumentCaptor<InputChannelCompat.InputEventListener> eventListenerCaptor =
@@ -130,34 +142,12 @@
         verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
         verify(mTouchSession).registerInputListener(eventListenerCaptor.capture());
 
-        final Random random = new Random(System.currentTimeMillis());
-
-        // If an initial touch down meeting criteria has been met, scroll behavior should be
-        // ignored.
-        assertThat(gestureListenerCaptor.getValue()
-                .onScroll(Mockito.mock(MotionEvent.class),
-                        Mockito.mock(MotionEvent.class),
-                        random.nextFloat(),
-                        random.nextFloat())).isFalse();
-
-        // A touch at the top of the screen should also not trigger listening.
-        final MotionEvent touchDownEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN,
-                0, 0, 0);
-
-        gestureListenerCaptor.getValue().onDown(touchDownEvent);
-        assertThat(gestureListenerCaptor.getValue()
-                .onScroll(Mockito.mock(MotionEvent.class),
-                        Mockito.mock(MotionEvent.class),
-                        random.nextFloat(),
-                        random.nextFloat())).isFalse();
-
         // A touch within range at the bottom of the screen should trigger listening
-        beginValidSwipe(gestureListenerCaptor.getValue());
         assertThat(gestureListenerCaptor.getValue()
                 .onScroll(Mockito.mock(MotionEvent.class),
                         Mockito.mock(MotionEvent.class),
-                        random.nextFloat(),
-                        random.nextFloat())).isTrue();
+                        1,
+                        2)).isTrue();
     }
 
     /**
@@ -170,8 +160,6 @@
                 ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
         verify(mTouchSession).registerGestureListener(gestureListenerCaptor.capture());
 
-        beginValidSwipe(gestureListenerCaptor.getValue());
-
         final float scrollAmount = .3f;
         final float distanceY = SCREEN_HEIGHT_PX * scrollAmount;
 
@@ -203,8 +191,6 @@
 
         when(mVelocityTracker.getYVelocity()).thenReturn(velocityY);
 
-        beginValidSwipe(gestureListenerCaptor.getValue());
-
         final float distanceY = SCREEN_HEIGHT_PX * position;
 
         final MotionEvent event1 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
index 74b217b..29f56e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
@@ -21,10 +21,13 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.graphics.Rect;
+import android.graphics.Region;
 import android.testing.AndroidTestingRunner;
 import android.util.Pair;
 import android.view.GestureDetector;
@@ -137,6 +140,81 @@
     }
 
     @Test
+    public void testEntryTouchZone() {
+        final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+        final Rect touchArea = new Rect(4, 4, 8 , 8);
+
+        doAnswer(invocation -> {
+            final Region region = (Region) invocation.getArguments()[0];
+            region.set(touchArea);
+            return null;
+        }).when(touchHandler).getTouchInitiationRegion(any());
+
+        final Environment environment = new Environment(Stream.of(touchHandler)
+                .collect(Collectors.toCollection(HashSet::new)));
+
+        // Ensure touch outside specified region is not delivered.
+        final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
+        when(initialEvent.getX()).thenReturn(0.0f);
+        when(initialEvent.getY()).thenReturn(1.0f);
+        environment.publishInputEvent(initialEvent);
+        verify(touchHandler, never()).onSessionStart(any());
+
+        // Make sure touch inside region causes session start.
+        when(initialEvent.getX()).thenReturn(5.0f);
+        when(initialEvent.getY()).thenReturn(5.0f);
+        environment.publishInputEvent(initialEvent);
+        verify(touchHandler).onSessionStart(any());
+    }
+
+    @Test
+    public void testSessionCount() {
+        final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
+        final Rect touchArea = new Rect(4, 4, 8 , 8);
+
+        final DreamTouchHandler unzonedTouchHandler = Mockito.mock(DreamTouchHandler.class);
+        doAnswer(invocation -> {
+            final Region region = (Region) invocation.getArguments()[0];
+            region.set(touchArea);
+            return null;
+        }).when(touchHandler).getTouchInitiationRegion(any());
+
+        final Environment environment = new Environment(Stream.of(touchHandler, unzonedTouchHandler)
+                .collect(Collectors.toCollection(HashSet::new)));
+
+        // Ensure touch outside specified region is delivered to unzoned touch handler.
+        final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);
+        when(initialEvent.getX()).thenReturn(0.0f);
+        when(initialEvent.getY()).thenReturn(1.0f);
+        environment.publishInputEvent(initialEvent);
+
+        ArgumentCaptor<DreamTouchHandler.TouchSession> touchSessionCaptor = ArgumentCaptor.forClass(
+                DreamTouchHandler.TouchSession.class);
+
+        // Make sure only one active session.
+        {
+            verify(unzonedTouchHandler).onSessionStart(touchSessionCaptor.capture());
+            final DreamTouchHandler.TouchSession touchSession = touchSessionCaptor.getValue();
+            assertThat(touchSession.getActiveSessionCount()).isEqualTo(1);
+            touchSession.pop();
+            environment.executeAll();
+        }
+
+        // Make sure touch inside the touch region.
+        when(initialEvent.getX()).thenReturn(5.0f);
+        when(initialEvent.getY()).thenReturn(5.0f);
+        environment.publishInputEvent(initialEvent);
+
+        // Make sure there are two active sessions.
+        {
+            verify(touchHandler).onSessionStart(touchSessionCaptor.capture());
+            final DreamTouchHandler.TouchSession touchSession = touchSessionCaptor.getValue();
+            assertThat(touchSession.getActiveSessionCount()).isEqualTo(2);
+            touchSession.pop();
+        }
+    }
+
+    @Test
     public void testInputEventPropagation() {
         final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/HideComplicationTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/HideComplicationTouchHandlerTest.java
new file mode 100644
index 0000000..0a02133
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/HideComplicationTouchHandlerTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.touch;
+
+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.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.testing.AndroidTestingRunner;
+import android.view.MotionEvent;
+import android.view.View;
+
+import androidx.concurrent.futures.CallbackToFutureAdapter;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dreams.complication.Complication;
+import com.android.systemui.shared.system.InputChannelCompat;
+import com.android.systemui.touch.TouchInsetManager;
+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;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class HideComplicationTouchHandlerTest extends SysuiTestCase {
+    private static final int RESTORE_TIMEOUT = 1000;
+
+    @Mock
+    Complication.VisibilityController mVisibilityController;
+
+    @Mock
+    TouchInsetManager mTouchInsetManager;
+
+    @Mock
+    Handler mHandler;
+
+    @Mock
+    MotionEvent mMotionEvent;
+
+    @Mock
+    DreamTouchHandler.TouchSession mSession;
+
+    FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    /**
+     * Ensures no actions are taken when there multiple sessions.
+     */
+    @Test
+    public void testSessionEndOnMultipleSessions() {
+        final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler(
+                mVisibilityController,
+                RESTORE_TIMEOUT,
+                mTouchInsetManager,
+                mFakeExecutor,
+                mHandler);
+
+        // Report multiple active sessions.
+        when(mSession.getActiveSessionCount()).thenReturn(2);
+
+        // Start session.
+        touchHandler.onSessionStart(mSession);
+
+        // Verify session end.
+        verify(mSession).pop();
+
+        // Verify no interaction with visibility controller.
+        verify(mVisibilityController, never()).setVisibility(anyInt(), anyBoolean());
+    }
+
+    /**
+     * Ensures no actions are taken when there multiple sessions.
+     */
+    @Test
+    public void testSessionEndWithTouchInInset() {
+        final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler(
+                mVisibilityController,
+                RESTORE_TIMEOUT,
+                mTouchInsetManager,
+                mFakeExecutor,
+                mHandler);
+
+        // Report one session
+        when(mSession.getActiveSessionCount()).thenReturn(1);
+
+        // Start session
+        touchHandler.onSessionStart(mSession);
+
+        // Capture input listener
+        final ArgumentCaptor<InputChannelCompat.InputEventListener> inputEventListenerCaptor =
+                ArgumentCaptor.forClass(InputChannelCompat.InputEventListener.class);
+        verify(mSession).registerInputListener(inputEventListenerCaptor.capture());
+
+        // Report touch within the inset
+        when(mTouchInsetManager.checkWithinTouchRegion(anyInt(), anyInt())).thenReturn(
+                CallbackToFutureAdapter.getFuture(completer -> {
+                    completer.set(true);
+                    return "testSessionEndWithTouchInInset";
+                })
+        );
+
+        inputEventListenerCaptor.getValue().onInputEvent(mMotionEvent);
+        mFakeExecutor.runAllReady();
+
+        // Verify session ended.
+        verify(mSession).pop();
+
+        // Verify no interaction with visibility controller.
+        verify(mVisibilityController, never()).setVisibility(anyInt(), anyBoolean());
+    }
+
+    /**
+     * Make sure visibility changes are triggered from session events.
+     */
+    @Test
+    public void testSessionLifecycle() {
+        final HideComplicationTouchHandler touchHandler = new HideComplicationTouchHandler(
+                mVisibilityController,
+                RESTORE_TIMEOUT,
+                mTouchInsetManager,
+                mFakeExecutor,
+                mHandler);
+
+        // Report one session
+        when(mSession.getActiveSessionCount()).thenReturn(1);
+
+        // Start session
+        touchHandler.onSessionStart(mSession);
+
+        // Capture input listener
+        final ArgumentCaptor<InputChannelCompat.InputEventListener> inputEventListenerCaptor =
+                ArgumentCaptor.forClass(InputChannelCompat.InputEventListener.class);
+        verify(mSession).registerInputListener(inputEventListenerCaptor.capture());
+
+        // Report touch outside the inset
+        when(mTouchInsetManager.checkWithinTouchRegion(anyInt(), anyInt())).thenReturn(
+                CallbackToFutureAdapter.getFuture(completer -> {
+                    completer.set(false);
+                    return "testSessionEndWithTouchInInset";
+                })
+        );
+
+        // Send down event.
+        when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_DOWN);
+        inputEventListenerCaptor.getValue().onInputEvent(mMotionEvent);
+        mFakeExecutor.runAllReady();
+
+        // Verify callback to restore visibility cancelled.
+        verify(mHandler).removeCallbacks(any());
+
+        // Verify visibility controller told to hide complications.
+        verify(mVisibilityController).setVisibility(eq(View.INVISIBLE), anyBoolean());
+
+        Mockito.clearInvocations(mVisibilityController, mHandler);
+
+        // Send up event.
+        when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_UP);
+        inputEventListenerCaptor.getValue().onInputEvent(mMotionEvent);
+        mFakeExecutor.runAllReady();
+
+        // Verify visibility controller told to show complications.
+        ArgumentCaptor<Runnable> delayRunnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+        verify(mHandler).postDelayed(delayRunnableCaptor.capture(),
+                eq(Long.valueOf(RESTORE_TIMEOUT)));
+        delayRunnableCaptor.getValue().run();
+        verify(mVisibilityController).setVisibility(eq(View.VISIBLE), anyBoolean());
+
+        // Verify session ended.
+        verify(mSession).pop();
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
index 4cc5673..23a5b2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
@@ -20,7 +20,7 @@
 import android.content.Intent
 import android.content.pm.PackageManager.NameNotFoundException
 import android.content.res.Resources
-import androidx.test.filters.SmallTest
+import android.test.suitebuilder.annotation.SmallTest
 import com.android.internal.statusbar.IStatusBarService
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
@@ -35,6 +35,8 @@
 import org.junit.Before
 import org.junit.Test
 import org.mockito.Mock
+import org.mockito.Mockito.anyBoolean
+import org.mockito.Mockito.anyString
 import org.mockito.Mockito.inOrder
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
@@ -57,6 +59,7 @@
     @Mock private lateinit var mFlagManager: FlagManager
     @Mock private lateinit var mMockContext: Context
     @Mock private lateinit var mSecureSettings: SecureSettings
+    @Mock private lateinit var mSystemProperties: SystemPropertiesHelper
     @Mock private lateinit var mResources: Resources
     @Mock private lateinit var mDumpManager: DumpManager
     @Mock private lateinit var mBarService: IStatusBarService
@@ -71,12 +74,13 @@
             mFlagManager,
             mMockContext,
             mSecureSettings,
+            mSystemProperties,
             mResources,
             mDumpManager,
             { mFlagMap },
             mBarService
         )
-        verify(mFlagManager).restartAction = any()
+        verify(mFlagManager).onSettingsChangedAction = any()
         mBroadcastReceiver = withArgCaptor {
             verify(mMockContext).registerReceiver(capture(), any(), nullable(), nullable(),
                 any())
@@ -123,6 +127,22 @@
     }
 
     @Test
+    fun testReadSysPropBooleanFlag() {
+        whenever(mSystemProperties.getBoolean(anyString(), anyBoolean())).thenAnswer {
+            if ("b".equals(it.getArgument<String?>(0))) {
+                return@thenAnswer true
+            }
+            return@thenAnswer it.getArgument(1)
+        }
+
+        assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a"))).isFalse()
+        assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b"))).isTrue()
+        assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", true))).isTrue()
+        assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(4, "d", false))).isFalse()
+        assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e"))).isFalse()
+    }
+
+    @Test
     fun testReadStringFlag() {
         whenever(mFlagManager.readFlagValue<String>(eq(3), any())).thenReturn("foo")
         whenever(mFlagManager.readFlagValue<String>(eq(4), any())).thenReturn("bar")
@@ -259,7 +279,7 @@
             verify(mFlagManager, times(numReads)).readFlagValue(eq(id), any<FlagSerializer<*>>())
             verify(mFlagManager).idToSettingsKey(eq(id))
             verify(mSecureSettings).putString(eq("key-$id"), eq(data))
-            verify(mFlagManager).dispatchListenersAndMaybeRestart(eq(id))
+            verify(mFlagManager).dispatchListenersAndMaybeRestart(eq(id), any())
         }.verifyNoMoreInteractions()
         verifyNoMoreInteractions(mFlagManager, mSecureSettings)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
index b5e6602..b5deb0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
@@ -17,11 +17,10 @@
 
 import android.content.pm.PackageManager.NameNotFoundException
 import android.content.res.Resources
-import androidx.test.filters.SmallTest
+import android.test.suitebuilder.annotation.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import org.junit.After
 import org.junit.Assert.assertThrows
@@ -31,8 +30,6 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 import org.mockito.MockitoAnnotations
-import java.io.PrintWriter
-import java.io.StringWriter
 import org.mockito.Mockito.`when` as whenever
 
 /**
@@ -44,12 +41,13 @@
     private lateinit var mFeatureFlagsRelease: FeatureFlagsRelease
 
     @Mock private lateinit var mResources: Resources
+    @Mock private lateinit var mSystemProperties: SystemPropertiesHelper
     @Mock private lateinit var mDumpManager: DumpManager
 
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        mFeatureFlagsRelease = FeatureFlagsRelease(mResources, mDumpManager)
+        mFeatureFlagsRelease = FeatureFlagsRelease(mResources, mSystemProperties, mDumpManager)
     }
 
     @After
@@ -87,41 +85,13 @@
     }
 
     @Test
-    fun testDump() {
-        val flag1 = BooleanFlag(1, true)
-        val flag2 = ResourceBooleanFlag(2, 1002)
-        val flag3 = BooleanFlag(3, false)
-        val flag4 = StringFlag(4, "")
-        val flag5 = StringFlag(5, "flag5default")
-        val flag6 = ResourceStringFlag(6, 1006)
+    fun testSysPropBooleanFlag() {
+        val flagId = 213
+        val flagName = "sys_prop_flag"
+        val flagDefault = true
 
-        whenever(mResources.getBoolean(1002)).thenReturn(true)
-        whenever(mResources.getString(1006)).thenReturn("resource1006")
-        whenever(mResources.getString(1007)).thenReturn("resource1007")
-
-        // WHEN the flags have been accessed
-        assertThat(mFeatureFlagsRelease.isEnabled(flag1)).isTrue()
-        assertThat(mFeatureFlagsRelease.isEnabled(flag2)).isTrue()
-        assertThat(mFeatureFlagsRelease.isEnabled(flag3)).isFalse()
-        assertThat(mFeatureFlagsRelease.getString(flag4)).isEmpty()
-        assertThat(mFeatureFlagsRelease.getString(flag5)).isEqualTo("flag5default")
-        assertThat(mFeatureFlagsRelease.getString(flag6)).isEqualTo("resource1006")
-
-        // THEN the dump contains the flags and the default values
-        val dump = dumpToString()
-        assertThat(dump).contains(" sysui_flag_1: true\n")
-        assertThat(dump).contains(" sysui_flag_2: true\n")
-        assertThat(dump).contains(" sysui_flag_3: false\n")
-        assertThat(dump).contains(" sysui_flag_4: [length=0] \"\"\n")
-        assertThat(dump).contains(" sysui_flag_5: [length=12] \"flag5default\"\n")
-        assertThat(dump).contains(" sysui_flag_6: [length=12] \"resource1006\"\n")
-    }
-
-    private fun dumpToString(): String {
-        val sw = StringWriter()
-        val pw = PrintWriter(sw)
-        mFeatureFlagsRelease.dump(mock(), pw, emptyArray())
-        pw.flush()
-        return sw.toString()
+        val flag = SysPropBooleanFlag(flagId, flagName, flagDefault)
+        whenever(mSystemProperties.getBoolean(flagName, flagDefault)).thenReturn(flagDefault)
+        assertThat(mFeatureFlagsRelease.isEnabled(flag)).isEqualTo(flagDefault)
     }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
index 644bd21..a2eca81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
@@ -19,7 +19,7 @@
 import android.database.ContentObserver
 import android.net.Uri
 import android.os.Handler
-import androidx.test.filters.SmallTest
+import android.test.suitebuilder.annotation.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -130,14 +130,14 @@
         mFlagManager.addListener(BooleanFlag(1, true), listener1)
         mFlagManager.addListener(BooleanFlag(10, true), listener10)
 
-        mFlagManager.dispatchListenersAndMaybeRestart(1)
+        mFlagManager.dispatchListenersAndMaybeRestart(1, null)
         val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> {
             verify(listener1).onFlagChanged(capture())
         }
         assertThat(flagEvent1.flagId).isEqualTo(1)
         verifyNoMoreInteractions(listener1, listener10)
 
-        mFlagManager.dispatchListenersAndMaybeRestart(10)
+        mFlagManager.dispatchListenersAndMaybeRestart(10, null)
         val flagEvent10 = withArgCaptor<FlagListenable.FlagEvent> {
             verify(listener10).onFlagChanged(capture())
         }
@@ -151,14 +151,14 @@
         mFlagManager.addListener(BooleanFlag(1, true), listener)
         mFlagManager.addListener(BooleanFlag(10, true), listener)
 
-        mFlagManager.dispatchListenersAndMaybeRestart(1)
+        mFlagManager.dispatchListenersAndMaybeRestart(1, null)
         val flagEvent1 = withArgCaptor<FlagListenable.FlagEvent> {
             verify(listener).onFlagChanged(capture())
         }
         assertThat(flagEvent1.flagId).isEqualTo(1)
         verifyNoMoreInteractions(listener)
 
-        mFlagManager.dispatchListenersAndMaybeRestart(10)
+        mFlagManager.dispatchListenersAndMaybeRestart(10, null)
         val flagEvent10 = withArgCaptor<FlagListenable.FlagEvent> {
             verify(listener, times(2)).onFlagChanged(capture())
         }
@@ -169,8 +169,7 @@
     @Test
     fun testRestartWithNoListeners() {
         val restartAction = mock<Consumer<Boolean>>()
-        mFlagManager.restartAction = restartAction
-        mFlagManager.dispatchListenersAndMaybeRestart(1)
+        mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
         verify(restartAction).accept(eq(false))
         verifyNoMoreInteractions(restartAction)
     }
@@ -178,11 +177,10 @@
     @Test
     fun testListenerCanSuppressRestart() {
         val restartAction = mock<Consumer<Boolean>>()
-        mFlagManager.restartAction = restartAction
         mFlagManager.addListener(BooleanFlag(1, true)) { event ->
             event.requestNoRestart()
         }
-        mFlagManager.dispatchListenersAndMaybeRestart(1)
+        mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
         verify(restartAction).accept(eq(true))
         verifyNoMoreInteractions(restartAction)
     }
@@ -190,11 +188,10 @@
     @Test
     fun testListenerOnlySuppressesRestartForOwnFlag() {
         val restartAction = mock<Consumer<Boolean>>()
-        mFlagManager.restartAction = restartAction
         mFlagManager.addListener(BooleanFlag(10, true)) { event ->
             event.requestNoRestart()
         }
-        mFlagManager.dispatchListenersAndMaybeRestart(1)
+        mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
         verify(restartAction).accept(eq(false))
         verifyNoMoreInteractions(restartAction)
     }
@@ -202,14 +199,13 @@
     @Test
     fun testRestartWhenNotAllListenersRequestSuppress() {
         val restartAction = mock<Consumer<Boolean>>()
-        mFlagManager.restartAction = restartAction
         mFlagManager.addListener(BooleanFlag(10, true)) { event ->
             event.requestNoRestart()
         }
         mFlagManager.addListener(BooleanFlag(10, true)) {
             // do not request
         }
-        mFlagManager.dispatchListenersAndMaybeRestart(1)
+        mFlagManager.dispatchListenersAndMaybeRestart(1, restartAction)
         verify(restartAction).accept(eq(false))
         verifyNoMoreInteractions(restartAction)
     }
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 953be7d..f00fbe6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -60,7 +60,7 @@
 import com.android.systemui.settings.UserContextProvider;
 import com.android.systemui.statusbar.NotificationShadeWindowController;
 import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.telephony.TelephonyListenerManager;
@@ -113,7 +113,7 @@
     @Mock private Handler mHandler;
     @Mock private UserContextProvider mUserContextProvider;
     @Mock private VibratorHelper mVibratorHelper;
-    @Mock private StatusBar mStatusBar;
+    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock private DialogLaunchAnimator mDialogLaunchAnimator;
 
@@ -158,7 +158,7 @@
                 mRingerModeTracker,
                 mHandler,
                 mPackageManager,
-                Optional.of(mStatusBar),
+                Optional.of(mCentralSurfaces),
                 mKeyguardUpdateMonitor,
                 mDialogLaunchAnimator);
         mGlobalActionsDialogLite.setZeroDialogPressDelayForTesting();
@@ -227,7 +227,7 @@
         doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
         doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
         doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
-        doReturn(true).when(mStatusBar).isKeyguardShowing();
+        doReturn(true).when(mCentralSurfaces).isKeyguardShowing();
         String[] actions = {
                 GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                 GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN,
@@ -242,7 +242,7 @@
         MotionEvent end = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 500, 0);
         gestureListener.onFling(start, end, 0, 1000);
         verifyLogPosted(GlobalActionsDialogLite.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
-        verify(mStatusBar).animateExpandSettingsPanel(null);
+        verify(mCentralSurfaces).animateExpandSettingsPanel(null);
     }
 
     @Test
@@ -251,7 +251,7 @@
         doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
         doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
         doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
-        doReturn(false).when(mStatusBar).isKeyguardShowing();
+        doReturn(false).when(mCentralSurfaces).isKeyguardShowing();
         String[] actions = {
                 GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                 GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN,
@@ -266,7 +266,7 @@
         MotionEvent end = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 500, 0);
         gestureListener.onFling(start, end, 0, 1000);
         verifyLogPosted(GlobalActionsDialogLite.GlobalActionsEvent.GA_CLOSE_TAP_OUTSIDE);
-        verify(mStatusBar).animateExpandNotificationsPanel();
+        verify(mCentralSurfaces).animateExpandNotificationsPanel();
     }
 
     @Test
@@ -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();
@@ -432,7 +461,7 @@
         doReturn(4).when(mGlobalActionsDialogLite).getMaxShownPowerItems();
         doReturn(true).when(mGlobalActionsDialogLite).shouldDisplayLockdown(any());
         doReturn(true).when(mGlobalActionsDialogLite).shouldShowAction(any());
-        doReturn(false).when(mStatusBar).isKeyguardShowing();
+        doReturn(false).when(mCentralSurfaces).isKeyguardShowing();
         String[] actions = {
                 GlobalActionsDialogLite.GLOBAL_ACTION_KEY_EMERGENCY,
                 GlobalActionsDialogLite.GLOBAL_ACTION_KEY_LOCKDOWN,
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 e606be1..b359ae5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -33,10 +33,11 @@
 import com.android.systemui.statusbar.StatusBarState
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.FakeConfigurationController
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.util.animation.UniqueObjectHostView
-import junit.framework.Assert
+import com.android.systemui.util.mockito.any
+import com.google.common.truth.Truth.assertThat
 import org.junit.Assert.assertNotNull
 import org.junit.Before
 import org.junit.Rule
@@ -44,16 +45,16 @@
 import org.junit.runner.RunWith
 import org.mockito.ArgumentCaptor
 import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.ArgumentMatchers.anyLong
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
-import org.mockito.Mockito.any
-import org.mockito.Mockito.anyBoolean
-import org.mockito.Mockito.anyLong
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.junit.MockitoJUnit
+import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -83,8 +84,6 @@
     @Mock
     private lateinit var keyguardViewController: KeyguardViewController
     @Mock
-    private lateinit var configurationController: ConfigurationController
-    @Mock
     private lateinit var uniqueObjectHostView: UniqueObjectHostView
     @Mock
     private lateinit var dreamOverlayStateController: DreamOverlayStateController
@@ -97,6 +96,7 @@
     val mockito = MockitoJUnit.rule()
     private lateinit var mediaHiearchyManager: MediaHierarchyManager
     private lateinit var mediaFrame: ViewGroup
+    private val configurationController = FakeConfigurationController()
 
     @Before
     fun setup() {
@@ -176,12 +176,7 @@
 
     @Test
     fun testGoingToFullShade() {
-        // Let's set it onto Lock screen
-        `when`(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
-        `when`(notificationLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(
-            true)
-        statusBarCallback.value.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD)
-        clearInvocations(mediaCarouselController)
+        goToLockscreen()
 
         // Let's transition all the way to full shade
         mediaHiearchyManager.setTransitionToFullShadeAmount(100000f)
@@ -204,41 +199,48 @@
 
         // Let's make sure alpha is set
         mediaHiearchyManager.setTransitionToFullShadeAmount(2.0f)
-        Assert.assertTrue("alpha should not be 1.0f when cross fading", mediaFrame.alpha != 1.0f)
+        assertThat(mediaFrame.alpha).isNotEqualTo(1.0f)
     }
 
     @Test
     fun testTransformationOnLockScreenIsFading() {
-        // Let's set it onto Lock screen
-        `when`(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
-        `when`(notificationLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(
-            true)
-        statusBarCallback.value.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD)
-        clearInvocations(mediaCarouselController)
+        goToLockscreen()
+        expandQS()
 
-        // Let's transition from lockscreen to qs
-        mediaHiearchyManager.qsExpansion = 1.0f
         val transformType = mediaHiearchyManager.calculateTransformationType()
-        Assert.assertTrue("media isn't transforming to qs with a fade",
-            transformType == MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
+        assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
+    }
+
+    @Test
+    fun calculateTransformationType_onLockShade_inSplitShade_goingToFullShade_returnsTransition() {
+        enableSplitShade()
+        goToLockscreen()
+        expandQS()
+        mediaHiearchyManager.setTransitionToFullShadeAmount(10000f)
+
+        val transformType = mediaHiearchyManager.calculateTransformationType()
+        assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_TRANSITION)
+    }
+
+    @Test
+    fun calculateTransformationType_onLockShade_inSplitShade_notExpanding_returnsFade() {
+        enableSplitShade()
+        goToLockscreen()
+        goToLockedShade()
+        expandQS()
+        mediaHiearchyManager.setTransitionToFullShadeAmount(0f)
+
+        val transformType = mediaHiearchyManager.calculateTransformationType()
+        assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
     }
 
     @Test
     fun testTransformationOnLockScreenToQQSisFading() {
-        // Let's set it onto Lock screen
-        `when`(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
-        `when`(notificationLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(
-            true)
-        statusBarCallback.value.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD)
-        clearInvocations(mediaCarouselController)
+        goToLockscreen()
+        goToLockedShade()
 
-        // Let's transition from lockscreen to qs
-        `when`(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
-        statusBarCallback.value.onStatePreChange(StatusBarState.KEYGUARD,
-            StatusBarState.SHADE_LOCKED)
         val transformType = mediaHiearchyManager.calculateTransformationType()
-        Assert.assertTrue("media isn't transforming to qqswith a fade",
-            transformType == MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
+        assertThat(transformType).isEqualTo(MediaHierarchyManager.TRANSFORMATION_TYPE_FADE)
     }
 
     @Test
@@ -254,4 +256,32 @@
 
         verify(mediaCarouselController).closeGuts()
     }
-}
\ No newline at end of file
+
+    private fun enableSplitShade() {
+        context.getOrCreateTestableResources().addOverride(
+            R.bool.config_use_split_notification_shade, true
+        )
+        configurationController.notifyConfigurationChanged()
+    }
+
+    private fun goToLockscreen() {
+        whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
+        whenever(notificationLockscreenUserManager.shouldShowLockscreenNotifications()).thenReturn(
+            true
+        )
+        statusBarCallback.value.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD)
+        clearInvocations(mediaCarouselController)
+    }
+
+    private fun goToLockedShade() {
+        whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
+        statusBarCallback.value.onStatePreChange(
+            StatusBarState.KEYGUARD,
+            StatusBarState.SHADE_LOCKED
+        )
+    }
+
+    private fun expandQS() {
+        mediaHiearchyManager.qsExpansion = 1.0f
+    }
+}
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..13e5821 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
@@ -42,6 +42,7 @@
 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.NotificationEntryManager;
 import com.android.systemui.statusbar.phone.ShadeController;
@@ -50,6 +51,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Optional;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -66,6 +69,8 @@
     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;
@@ -80,7 +85,8 @@
     public void setUp() {
         mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
                 mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
         mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext,
                 mMediaOutputController);
         mMediaOutputBaseDialogImpl.onCreate(new Bundle());
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..6230700 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;
@@ -51,17 +53,21 @@
 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;
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -86,6 +92,8 @@
     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);
@@ -93,12 +101,15 @@
     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<>();
 
@@ -115,7 +126,8 @@
 
         mMediaOutputController = new MediaOutputController(mSpyContext, TEST_PACKAGE_NAME, false,
                 mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
         mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         MediaDescription.Builder builder = new MediaDescription.Builder();
@@ -127,6 +139,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
@@ -159,7 +178,8 @@
     public void start_withoutPackageName_verifyMediaControllerInit() {
         mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
                 mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
 
         mMediaOutputController.start(mCb);
 
@@ -167,6 +187,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);
@@ -180,7 +207,8 @@
     public void stop_withoutPackageName_verifyMediaControllerDeinit() {
         mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
                 mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
 
         mMediaOutputController.start(mCb);
 
@@ -189,6 +217,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);
@@ -451,7 +512,8 @@
     public void getNotificationLargeIcon_withoutPackageName_returnsNull() {
         mMediaOutputController = new MediaOutputController(mSpyContext, null, false,
                 mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotifCollection, mUiEventLogger, mDialogLaunchAnimator);
+                mNotifCollection, mUiEventLogger, 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..cb52e7c 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,6 +37,7 @@
 import com.android.settingslib.media.MediaDevice;
 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.NotificationEntryManager;
 import com.android.systemui.statusbar.phone.ShadeController;
@@ -48,6 +49,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -67,6 +69,8 @@
             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;
@@ -76,7 +80,8 @@
     public void setUp() {
         mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
                 mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         mMediaOutputDialog = new MediaOutputDialog(mContext, false,
                 mMediaOutputController, mUiEventLogger);
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..f186f57 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
@@ -35,6 +35,7 @@
 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.NotificationEntryManager;
 import com.android.systemui.statusbar.phone.ShadeController;
@@ -46,6 +47,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
@@ -66,6 +68,8 @@
             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;
@@ -75,7 +79,8 @@
     public void setUp() {
         mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE, false,
                 mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter,
-                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator);
+                mNotificationEntryManager, mUiEventLogger, mDialogLaunchAnimator,
+                Optional.of(mNearbyMediaDevicesManager));
         mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
         mMediaOutputGroupDialog = new MediaOutputGroupDialog(mContext, false,
                 mMediaOutputController);
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 ea0a5a4..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,11 @@
 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
 import android.view.WindowManager
@@ -26,73 +30,107 @@
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.gesture.TapGestureDetector
 import com.android.systemui.util.concurrency.DelayableExecutor
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.view.ViewUtil
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 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
+import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
 
 @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
     private lateinit var windowManager: WindowManager
+    @Mock
+    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, windowManager, fakeExecutor)
+        controllerCommon = TestControllerCommon(
+            context, logger, windowManager, viewUtil, fakeExecutor, tapGestureDetector, powerManager
+        )
     }
 
     @Test
-    fun displayChip_chipAdded() {
+    fun displayChip_chipAddedAndGestureDetectionStartedAndScreenOn() {
         controllerCommon.displayChip(getState())
 
         verify(windowManager).addView(any(), any())
+        verify(tapGestureDetector).addOnGestureDetectedCallback(any(), any())
+        verify(powerManager).wakeUp(any(), any(), any())
     }
 
     @Test
-    fun displayChip_twice_chipNotAddedTwice() {
+    fun displayChip_twice_chipAndGestureDetectionNotAddedTwice() {
         controllerCommon.displayChip(getState())
         reset(windowManager)
+        reset(tapGestureDetector)
 
         controllerCommon.displayChip(getState())
         verify(windowManager, never()).addView(any(), any())
+        verify(tapGestureDetector, never()).addOnGestureDetectedCallback(any(), any())
     }
 
     @Test
     fun displayChip_chipDoesNotDisappearsBeforeTimeout() {
-        controllerCommon.displayChip(getState())
+        val state = getState()
+        controllerCommon.displayChip(state)
         reset(windowManager)
 
-        fakeClock.advanceTime(TIMEOUT_MILLIS - 1)
+        fakeClock.advanceTime(TIMEOUT_MS - 1)
 
         verify(windowManager, never()).removeView(any())
     }
 
     @Test
     fun displayChip_chipDisappearsAfterTimeout() {
-        controllerCommon.displayChip(getState())
+        val state = getState()
+        controllerCommon.displayChip(state)
         reset(windowManager)
 
-        fakeClock.advanceTime(TIMEOUT_MILLIS + 1)
+        fakeClock.advanceTime(TIMEOUT_MS + 1)
 
         verify(windowManager).removeView(any())
     }
@@ -100,7 +138,8 @@
     @Test
     fun displayChip_calledAgainBeforeTimeout_timeoutReset() {
         // First, display the chip
-        controllerCommon.displayChip(getState())
+        val state = getState()
+        controllerCommon.displayChip(state)
 
         // After some time, re-display the chip
         val waitTime = 1000L
@@ -108,7 +147,7 @@
         controllerCommon.displayChip(getState())
 
         // Wait until the timeout for the first display would've happened
-        fakeClock.advanceTime(TIMEOUT_MILLIS - waitTime + 1)
+        fakeClock.advanceTime(TIMEOUT_MS - waitTime + 1)
 
         // Verify we didn't hide the chip
         verify(windowManager, never()).removeView(any())
@@ -117,50 +156,117 @@
     @Test
     fun displayChip_calledAgainBeforeTimeout_eventuallyTimesOut() {
         // First, display the chip
-        controllerCommon.displayChip(getState())
+        val state = getState()
+        controllerCommon.displayChip(state)
 
         // After some time, re-display the chip
         fakeClock.advanceTime(1000L)
         controllerCommon.displayChip(getState())
 
         // Ensure we still hide the chip eventually
-        fakeClock.advanceTime(TIMEOUT_MILLIS + 1)
+        fakeClock.advanceTime(TIMEOUT_MS + 1)
 
         verify(windowManager).removeView(any())
     }
 
     @Test
-    fun removeChip_chipRemoved() {
+    fun removeChip_chipRemovedAndGestureDetectionStoppedAndRemovalLogged() {
         // First, add the chip
         controllerCommon.displayChip(getState())
 
         // Then, remove it
-        controllerCommon.removeChip()
+        val reason = "test reason"
+        controllerCommon.removeChip(reason)
 
         verify(windowManager).removeView(any())
+        verify(tapGestureDetector).removeOnGestureDetectedCallback(any())
+        verify(logger).logChipRemoval(reason)
     }
 
     @Test
     fun removeChip_noAdd_viewNotRemoved() {
-        controllerCommon.removeChip()
+        controllerCommon.removeChip("reason")
 
         verify(windowManager, never()).removeView(any())
     }
 
     @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)
     }
 
-    private fun getState() = MediaTttChipState(PACKAGE_NAME)
+    @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
+    fun tapGestureDetected_outsideViewBounds_viewHidden() {
+        controllerCommon.displayChip(getState())
+        whenever(viewUtil.touchIsWithinView(any(), any(), any())).thenReturn(false)
+        val gestureCallbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
+        verify(tapGestureDetector).addOnGestureDetectedCallback(
+            any(), capture(gestureCallbackCaptor)
+        )
+        val callback = gestureCallbackCaptor.value!!
+
+        callback.invoke(
+            MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+        )
+
+        verify(windowManager).removeView(any())
+    }
+
+    @Test
+    fun tapGestureDetected_insideViewBounds_viewNotHidden() {
+        controllerCommon.displayChip(getState())
+        whenever(viewUtil.touchIsWithinView(any(), any(), any())).thenReturn(true)
+        val gestureCallbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
+        verify(tapGestureDetector).addOnGestureDetectedCallback(
+            any(), capture(gestureCallbackCaptor)
+        )
+        val callback = gestureCallbackCaptor.value!!
+
+        callback.invoke(
+            MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+        )
+
+        verify(windowManager, never()).removeView(any())
+    }
+
+    private fun getState() = ChipInfo()
 
     private fun getChipView(): ViewGroup {
         val viewCaptor = ArgumentCaptor.forClass(View::class.java)
@@ -172,18 +278,32 @@
 
     inner class TestControllerCommon(
         context: Context,
+        logger: MediaTttLogger,
         windowManager: WindowManager,
+        viewUtil: ViewUtil,
         @Main mainExecutor: DelayableExecutor,
-        ) : MediaTttChipControllerCommon<MediaTttChipState>(
-        context, windowManager, mainExecutor, R.layout.media_ttt_chip
+        tapGestureDetector: TapGestureDetector,
+        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/common/MediaTttLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
new file mode 100644
index 0000000..d95e5c4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.common
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.log.LogBuffer
+import com.android.systemui.log.LogBufferFactory
+import com.android.systemui.log.LogcatEchoTracker
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.mock
+import java.io.PrintWriter
+import java.io.StringWriter
+
+@SmallTest
+class MediaTttLoggerTest : SysuiTestCase() {
+
+    private lateinit var buffer: LogBuffer
+    private lateinit var logger: MediaTttLogger
+
+    @Before
+    fun setUp () {
+        buffer = LogBufferFactory(DumpManager(), mock(LogcatEchoTracker::class.java))
+            .create("buffer", 10)
+        logger = MediaTttLogger(DEVICE_TYPE_TAG, buffer)
+    }
+
+    @Test
+    fun logStateChange_bufferHasDeviceTypeTagAndStateNameAndId() {
+        val stateName = "test state name"
+        val id = "test id"
+
+        logger.logStateChange(stateName, id)
+
+        val stringWriter = StringWriter()
+        buffer.dump(PrintWriter(stringWriter), tailLength = 0)
+        val actualString = stringWriter.toString()
+
+        assertThat(actualString).contains(DEVICE_TYPE_TAG)
+        assertThat(actualString).contains(stateName)
+        assertThat(actualString).contains(id)
+    }
+
+    @Test
+    fun logChipRemoval_bufferHasDeviceTypeAndReason() {
+        val reason = "test reason"
+        logger.logChipRemoval(reason)
+
+        val stringWriter = StringWriter()
+        buffer.dump(PrintWriter(stringWriter), tailLength = 0)
+        val actualString = stringWriter.toString()
+
+        assertThat(actualString).contains(DEVICE_TYPE_TAG)
+        assertThat(actualString).contains(reason)
+    }
+}
+
+private const val DEVICE_TYPE_TAG = "TEST TYPE"
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 117a6c8..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,21 +22,29 @@
 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
 import android.view.ViewGroup
 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
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.gesture.TapGestureDetector
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.view.ViewUtil
 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.never
@@ -45,6 +53,8 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
 class MediaTttChipControllerReceiverTest : SysuiTestCase() {
     private lateinit var controllerReceiver: MediaTttChipControllerReceiver
 
@@ -53,11 +63,19 @@
     @Mock
     private lateinit var applicationInfo: ApplicationInfo
     @Mock
+    private lateinit var logger: MediaTttLogger
+    @Mock
+    private lateinit var powerManager: PowerManager
+    @Mock
     private lateinit var windowManager: WindowManager
     @Mock
+    private lateinit var viewUtil: ViewUtil
+    @Mock
     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() {
@@ -71,12 +89,20 @@
         )).thenReturn(applicationInfo)
         context.setMockPackageManager(packageManager)
 
+        uiEventLoggerFake = UiEventLoggerFake()
+        receiverUiEventLogger = MediaTttReceiverUiEventLogger(uiEventLoggerFake)
+
         controllerReceiver = MediaTttChipControllerReceiver(
             commandQueue,
             context,
+            logger,
             windowManager,
+            viewUtil,
             FakeExecutor(FakeSystemClock()),
-            Handler.getMain()
+            TapGestureDetector(context),
+            powerManager,
+            Handler.getMain(),
+            receiverUiEventLogger,
         )
 
         val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -95,6 +121,9 @@
         )
 
         assertThat(getChipView().getAppIconView().contentDescription).isEqualTo(appName)
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_CLOSE_TO_SENDER.id
+        )
     }
 
     @Test
@@ -107,6 +136,9 @@
         )
 
         verify(windowManager, never()).addView(any(), any())
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttReceiverUiEvents.MEDIA_TTT_RECEIVER_FAR_FROM_SENDER.id
+        )
     }
 
     @Test
@@ -131,41 +163,15 @@
     }
 
     @Test
-    fun displayChip_nullAppIconDrawable_iconIsFromPackageName() {
-        val state = ChipStateReceiver(PACKAGE_NAME, appIconDrawable = null, "appName")
+    fun receivesNewStateFromCommandQueue_isLogged() {
+        commandQueueCallback.updateMediaTapToTransferReceiverDisplay(
+            StatusBarManager.MEDIA_TRANSFER_RECEIVER_STATE_CLOSE_TO_SENDER,
+            routeInfo,
+            null,
+            null
+        )
 
-        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)
+        verify(logger).logStateChange(any(), any())
     }
 
     private fun getChipView(): ViewGroup {
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 b440064..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,23 +21,32 @@
 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
 import android.view.WindowManager
 import android.widget.ImageView
 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
+import com.android.systemui.media.taptotransfer.common.MediaTttLogger
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.statusbar.gesture.TapGestureDetector
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
+import com.android.systemui.util.view.ViewUtil
+
 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.never
@@ -46,6 +55,8 @@
 import org.mockito.MockitoAnnotations
 
 @SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
 class MediaTttChipControllerSenderTest : SysuiTestCase() {
     private lateinit var controllerSender: MediaTttChipControllerSender
 
@@ -54,11 +65,21 @@
     @Mock
     private lateinit var applicationInfo: ApplicationInfo
     @Mock
+    private lateinit var logger: MediaTttLogger
+    @Mock
+    private lateinit var powerManager: PowerManager
+    @Mock
     private lateinit var windowManager: WindowManager
     @Mock
+    private lateinit var viewUtil: ViewUtil
+    @Mock
     private lateinit var commandQueue: CommandQueue
     private lateinit var commandQueueCallback: CommandQueue.Callbacks
     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() {
@@ -72,8 +93,21 @@
         )).thenReturn(applicationInfo)
         context.setMockPackageManager(packageManager)
 
+        fakeClock = FakeSystemClock()
+        fakeExecutor = FakeExecutor(fakeClock)
+        uiEventLoggerFake = UiEventLoggerFake()
+        senderUiEventLogger = MediaTttSenderUiEventLogger(uiEventLoggerFake)
+
         controllerSender = MediaTttChipControllerSender(
-            commandQueue, context, windowManager, FakeExecutor(FakeSystemClock())
+            commandQueue,
+            context,
+            logger,
+            windowManager,
+            viewUtil,
+            fakeExecutor,
+            TapGestureDetector(context),
+            powerManager,
+            senderUiEventLogger
         )
 
         val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -89,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
@@ -101,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
@@ -113,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
@@ -125,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
@@ -137,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
@@ -149,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
@@ -161,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
@@ -173,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
@@ -186,6 +252,9 @@
         )
 
         verify(windowManager, never()).addView(any(), any())
+        assertThat(uiEventLoggerFake.eventId(0)).isEqualTo(
+            MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER.id
+        )
     }
 
     @Test
@@ -208,6 +277,17 @@
     }
 
     @Test
+    fun receivesNewStateFromCommandQueue_isLogged() {
+        commandQueueCallback.updateMediaTapToTransferSenderDisplay(
+            StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST,
+            routeInfo,
+            null
+        )
+
+        verify(logger).logStateChange(any(), any())
+    }
+
+    @Test
     fun almostCloseToStartCast_appIcon_deviceName_noLoadingIcon_noUndo_noFailureIcon() {
         val state = almostCloseToStartCast()
         controllerSender.displayChip(state)
@@ -215,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)
@@ -229,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)
@@ -243,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)
@@ -257,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)
@@ -271,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)
     }
@@ -320,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
@@ -332,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)
     }
@@ -381,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)
@@ -440,11 +558,57 @@
     @Test
     fun changeFromTransferTriggeredToTransferFailed_failureIconAppears() {
         controllerSender.displayChip(transferToReceiverTriggered())
-        controllerSender.displayChip(transferFailed())
+        controllerSender.displayChip(transferToReceiverFailed())
 
         assertThat(getChipView().getFailureIcon().visibility).isEqualTo(View.VISIBLE)
     }
 
+    @Test
+    fun transferToReceiverTriggeredThenRemoveChip_chipStillDisplayed() {
+        controllerSender.displayChip(transferToReceiverTriggered())
+        fakeClock.advanceTime(1000L)
+
+        controllerSender.removeChip("fakeRemovalReason")
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+    }
+
+    @Test
+    fun transferToReceiverTriggeredThenFarFromReceiver_eventuallyTimesOut() {
+        val state = transferToReceiverTriggered()
+        controllerSender.displayChip(state)
+        fakeClock.advanceTime(1000L)
+        controllerSender.removeChip("fakeRemovalReason")
+
+        fakeClock.advanceTime(state.state.timeout + 1)
+
+        verify(windowManager).removeView(any())
+    }
+
+    @Test
+    fun transferToThisDeviceTriggeredThenRemoveChip_chipStillDisplayed() {
+        controllerSender.displayChip(transferToThisDeviceTriggered())
+        fakeClock.advanceTime(1000L)
+
+        controllerSender.removeChip("fakeRemovalReason")
+        fakeExecutor.runAllReady()
+
+        verify(windowManager, never()).removeView(any())
+    }
+
+    @Test
+    fun transferToThisDeviceTriggeredThenFarFromReceiver_eventuallyTimesOut() {
+        val state = transferToThisDeviceTriggered()
+        controllerSender.displayChip(state)
+        fakeClock.advanceTime(1000L)
+        controllerSender.removeChip("fakeRemovalReason")
+
+        fakeClock.advanceTime(state.state.timeout + 1)
+
+        verify(windowManager).removeView(any())
+    }
+
     private fun LinearLayout.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
 
     private fun LinearLayout.getChipText(): String =
@@ -465,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/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
index 3a95ed3..634d9e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
@@ -37,8 +37,7 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.settings.UserTracker;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -91,7 +90,7 @@
         mNavBarHelper = new NavBarHelper(mContext, mAccessibilityManager,
                 mAccessibilityButtonModeObserver, mAccessibilityButtonTargetObserver,
                 mSystemActions, mOverviewProxyService, mAssistManagerLazy,
-                () -> Optional.of(mock(StatusBar.class)),
+                () -> Optional.of(mock(CentralSurfaces.class)),
                 mNavigationModeController, mUserTracker, mDumpManager);
 
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
index 48d3857..eb1e1a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarTest.java
@@ -28,6 +28,7 @@
 
 import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.HOME_BUTTON_LONG_PRESS_DURATION_MS;
 import static com.android.systemui.navigationbar.NavigationBar.NavBarActionEvent.NAVBAR_ASSIST_LONGPRESS;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
@@ -93,13 +94,11 @@
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 import com.android.wm.shell.back.BackAnimation;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.pip.Pip;
 
 import org.junit.After;
@@ -161,7 +160,7 @@
     @Mock
     private AssistManager mAssistManager;
     @Mock
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
 
     @Rule
     public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
@@ -190,7 +189,7 @@
                     mock(AccessibilityButtonModeObserver.class),
                     mock(AccessibilityButtonTargetsObserver.class),
                     mSystemActions, mOverviewProxyService,
-                    () -> mock(AssistManager.class), () -> Optional.of(mStatusBar),
+                    () -> mock(AssistManager.class), () -> Optional.of(mCentralSurfaces),
                     mock(NavigationModeController.class), mock(UserTracker.class),
                     mock(DumpManager.class)));
             mNavigationBar = createNavBar(mContext);
@@ -283,7 +282,7 @@
         NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
         WindowInsets windowInsets = new WindowInsets.Builder().setVisible(ime(), false).build();
         doReturn(windowInsets).when(mockShadeWindowView).getRootWindowInsets();
-        doReturn(mockShadeWindowView).when(mStatusBar).getNotificationShadeWindowView();
+        doReturn(mockShadeWindowView).when(mCentralSurfaces).getNotificationShadeWindowView();
         doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
         doNothing().when(defaultNavBar).checkNavBarModes();
         doNothing().when(externalNavBar).checkNavBarModes();
@@ -319,7 +318,7 @@
     @Test
     public void testSetImeWindowStatusWhenKeyguardLockingAndImeInsetsChange() {
         NotificationShadeWindowView mockShadeWindowView = mock(NotificationShadeWindowView.class);
-        doReturn(mockShadeWindowView).when(mStatusBar).getNotificationShadeWindowView();
+        doReturn(mockShadeWindowView).when(mCentralSurfaces).getNotificationShadeWindowView();
         doReturn(true).when(mockShadeWindowView).isAttachedToWindow();
         doNothing().when(mNavigationBar).checkNavBarModes();
         mNavigationBar.createView(null, /* initialVisibility= */ true);
@@ -336,7 +335,7 @@
 
         // Verify navbar didn't alter and showing back icon when the keyguard is showing without
         // requesting IME insets visible.
-        doReturn(true).when(mStatusBar).isKeyguardShowing();
+        doReturn(true).when(mCentralSurfaces).isKeyguardShowing();
         mNavigationBar.setImeWindowStatus(DEFAULT_DISPLAY, null, IME_VISIBLE,
                 BACK_DISPOSITION_DEFAULT, true);
         assertFalse((mNavigationBar.getNavigationIconHints() & NAVIGATION_HINT_BACK_ALT) != 0);
@@ -401,9 +400,8 @@
                 mBroadcastDispatcher,
                 mCommandQueue,
                 Optional.of(mock(Pip.class)),
-                Optional.of(mock(LegacySplitScreen.class)),
                 Optional.of(mock(Recents.class)),
-                () -> Optional.of(mStatusBar),
+                () -> Optional.of(mCentralSurfaces),
                 mock(ShadeController.class),
                 mock(NotificationRemoteInputManager.class),
                 mock(NotificationShadeDepthController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index 721809c..91f8a40 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -48,7 +48,7 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.power.PowerUI.WarningsUI;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -89,14 +89,14 @@
     private IThermalEventListener mSkinThermalEventListener;
     @Mock private BroadcastDispatcher mBroadcastDispatcher;
     @Mock private CommandQueue mCommandQueue;
-    @Mock private Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
-    @Mock private StatusBar mStatusBar;
+    @Mock private Lazy<Optional<CentralSurfaces>> mCentralSurfacesOptionalLazy;
+    @Mock private CentralSurfaces mCentralSurfaces;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
 
-        when(mStatusBarOptionalLazy.get()).thenReturn(Optional.of(mStatusBar));
+        when(mCentralSurfacesOptionalLazy.get()).thenReturn(Optional.of(mCentralSurfaces));
 
         createPowerUi();
         mSkinThermalEventListener = mPowerUI.new SkinThermalEventListener();
@@ -430,12 +430,6 @@
         state.mIsPowerSaver = true;
         shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
         assertThat(shouldShow).isFalse();
-
-        state.mIsPowerSaver = false;
-        // if disabled we should not show the low warning.
-        state.mIsLowLevelWarningEnabled = false;
-        shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
-        assertThat(shouldShow).isFalse();
     }
 
     @Test
@@ -685,7 +679,7 @@
 
     private void createPowerUi() {
         mPowerUI = new PowerUI(
-                mContext, mBroadcastDispatcher, mCommandQueue, mStatusBarOptionalLazy,
+                mContext, mBroadcastDispatcher, mCommandQueue, mCentralSurfacesOptionalLazy,
                 mMockWarnings, mEnhancedEstimates, mPowerManager);
         mPowerUI.mThermalService = mThermalServiceMock;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
index 8ce50a6..7b17c36 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
@@ -33,12 +33,15 @@
 import org.mockito.ArgumentMatchers.anyBoolean
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.Mockito.never
+import org.mockito.Mockito.reset
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import javax.inject.Provider
 import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 @RunWith(AndroidTestingRunner::class)
 class FooterActionsControllerTest : LeakCheckedTest() {
     @Mock
@@ -56,6 +59,8 @@
     @Mock
     private lateinit var multiUserSwitchController: MultiUserSwitchController
     @Mock
+    private lateinit var globalActionsDialogProvider: Provider<GlobalActionsDialogLite>
+    @Mock
     private lateinit var globalActionsDialog: GlobalActionsDialogLite
     @Mock
     private lateinit var uiEventLogger: UiEventLogger
@@ -83,15 +88,11 @@
         whenever(multiUserSwitchControllerFactory.create(any()))
                 .thenReturn(multiUserSwitchController)
         whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(false)
+        whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
 
-        view = LayoutInflater.from(context)
-                .inflate(R.layout.footer_actions, null) as FooterActionsView
+        view = inflateView()
 
-        controller = FooterActionsController(view, multiUserSwitchControllerFactory,
-                activityStarter, userManager, userTracker, userInfoController,
-                deviceProvisionedController, securityFooterController, fgsManagerController,
-                falsingManager, metricsLogger, globalActionsDialog, uiEventLogger,
-                showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper), featureFlags)
+        controller = constructFooterActionsController(view)
         controller.init()
         ViewUtils.attachView(view)
         // View looper is the testable looper associated with the test
@@ -100,7 +101,9 @@
 
     @After
     fun tearDown() {
-        ViewUtils.detachView(view)
+        if (view.isAttachedToWindow) {
+            ViewUtils.detachView(view)
+        }
     }
 
     @Test
@@ -139,8 +142,7 @@
 
     @Test
     fun testMultiUserSwitchUpdatedWhenSettingChanged() {
-        // When expanded, listening is true
-        controller.setListening(true)
+        // Always listening to setting while View is attached
         testableLooper.processAllMessages()
 
         val multiUserSwitch = view.requireViewById<View>(R.id.multi_user_switch)
@@ -156,4 +158,56 @@
 
         assertThat(multiUserSwitch.visibility).isEqualTo(View.VISIBLE)
     }
+
+    @Test
+    fun testMultiUserSettingNotListenedAfterDetach() {
+        testableLooper.processAllMessages()
+
+        val multiUserSwitch = view.requireViewById<View>(R.id.multi_user_switch)
+        assertThat(multiUserSwitch.visibility).isNotEqualTo(View.VISIBLE)
+
+        ViewUtils.detachView(view)
+
+        // The setting is only used as an indicator for whether the view should refresh. The actual
+        // value of the setting is ignored; isMultiUserEnabled is the source of truth
+        whenever(multiUserSwitchController.isMultiUserEnabled).thenReturn(true)
+
+        // Changing the value of USER_SWITCHER_ENABLED should cause the view to update
+        fakeSettings.putIntForUser(Settings.Global.USER_SWITCHER_ENABLED, 1, userTracker.userId)
+        testableLooper.processAllMessages()
+
+        assertThat(multiUserSwitch.visibility).isNotEqualTo(View.VISIBLE)
+    }
+
+    @Test
+    fun testCleanUpGAD() {
+        reset(globalActionsDialogProvider)
+        whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
+        val view = inflateView()
+        controller = constructFooterActionsController(view)
+        controller.init()
+        verify(globalActionsDialogProvider, never()).get()
+
+        // GAD is constructed during attachment
+        ViewUtils.attachView(view)
+        testableLooper.processAllMessages()
+        verify(globalActionsDialogProvider).get()
+
+        ViewUtils.detachView(view)
+        testableLooper.processAllMessages()
+        verify(globalActionsDialog).destroy()
+    }
+
+    private fun inflateView(): FooterActionsView {
+        return LayoutInflater.from(context)
+                .inflate(R.layout.footer_actions, null) as FooterActionsView
+    }
+
+    private fun constructFooterActionsController(view: FooterActionsView): FooterActionsController {
+        return FooterActionsController(view, multiUserSwitchControllerFactory,
+                activityStarter, userManager, userTracker, userInfoController,
+                deviceProvisionedController, securityFooterController, fgsManagerController,
+                falsingManager, metricsLogger, globalActionsDialogProvider, uiEventLogger,
+                showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper), featureFlags)
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 4ab3926..534c7e7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -56,7 +56,7 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoTileManager;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.Clock;
 import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -142,7 +142,7 @@
                 mock(QSFactoryImpl.class), new Handler(), Looper.myLooper(),
                 mock(PluginManager.class), mock(TunerService.class),
                 () -> mock(AutoTileManager.class), mock(DumpManager.class),
-                mock(BroadcastDispatcher.class), Optional.of(mock(StatusBar.class)),
+                mock(BroadcastDispatcher.class), Optional.of(mock(CentralSurfaces.class)),
                 mock(QSLogger.class), mock(UiEventLogger.class), mock(UserTracker.class),
                 mock(SecureSettings.class), mock(CustomTileStatePersister.class),
                 mTileServiceRequestControllerBuilder, mock(TileLifecycleManager.Factory.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
new file mode 100644
index 0000000..ac1e86f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
@@ -0,0 +1,136 @@
+package com.android.systemui.qs
+
+import android.test.suitebuilder.annotation.SmallTest
+import android.testing.AndroidTestingRunner
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.media.MediaFlags
+import com.android.systemui.media.MediaHost
+import com.android.systemui.media.MediaHostState
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.qs.customize.QSCustomizerController
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.settings.brightness.BrightnessController
+import com.android.systemui.settings.brightness.BrightnessSliderController
+import com.android.systemui.tuner.TunerService
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.any
+import org.mockito.Mockito.reset
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class QSPanelControllerTest : SysuiTestCase() {
+
+    @Mock private lateinit var qsPanel: QSPanel
+    @Mock private lateinit var qsFgsManagerFooter: QSFgsManagerFooter
+    @Mock private lateinit var qsSecurityFooter: QSSecurityFooter
+    @Mock private lateinit var tunerService: TunerService
+    @Mock private lateinit var qsTileHost: QSTileHost
+    @Mock private lateinit var qsCustomizerController: QSCustomizerController
+    @Mock private lateinit var qsTileRevealControllerFactory: QSTileRevealController.Factory
+    @Mock private lateinit var dumpManager: DumpManager
+    @Mock private lateinit var metricsLogger: MetricsLogger
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+    @Mock private lateinit var qsLogger: QSLogger
+    @Mock private lateinit var brightnessControllerFactory: BrightnessController.Factory
+    @Mock private lateinit var brightnessController: BrightnessController
+    @Mock private lateinit var brightnessSlider: BrightnessSliderController
+    @Mock private lateinit var brightnessSliderFactory: BrightnessSliderController.Factory
+    @Mock private lateinit var falsingManager: FalsingManager
+    @Mock private lateinit var featureFlags: FeatureFlags
+    @Mock private lateinit var mediaFlags: MediaFlags
+    @Mock private lateinit var mediaHost: MediaHost
+
+    private lateinit var controller: QSPanelController
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        whenever(brightnessSliderFactory.create(any(), any())).thenReturn(brightnessSlider)
+        whenever(brightnessControllerFactory.create(any())).thenReturn(brightnessController)
+        whenever(qsPanel.resources).thenReturn(mContext.orCreateTestableResources.resources)
+
+        controller = QSPanelController(
+            qsPanel,
+            qsFgsManagerFooter,
+            qsSecurityFooter,
+            tunerService,
+            qsTileHost,
+            qsCustomizerController,
+            /* usingMediaPlayer= */ true,
+            mediaHost,
+            qsTileRevealControllerFactory,
+            dumpManager,
+            metricsLogger,
+            uiEventLogger,
+            qsLogger,
+            brightnessControllerFactory,
+            brightnessSliderFactory,
+            falsingManager,
+            featureFlags,
+            mediaFlags
+        )
+    }
+
+    @After
+    fun tearDown() {
+        reset(mediaHost)
+    }
+
+    @Test
+    fun onInit_notSplitShade_newMediaLayoutAvailable_setsMediaAsExpanded() {
+        setSplitShadeEnabled(false)
+        whenever(mediaFlags.useMediaSessionLayout()).thenReturn(true)
+
+        controller.onInit()
+
+        verify(mediaHost).expansion = MediaHostState.EXPANDED
+    }
+
+    @Test
+    fun onInit_notSplitShade_newMediaLayoutNotAvailable_setsMediaAsExpanded() {
+        setSplitShadeEnabled(false)
+        whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false)
+
+        controller.onInit()
+
+        verify(mediaHost).expansion = MediaHostState.EXPANDED
+    }
+
+    @Test
+    fun onInit_inSplitShade_newMediaLayoutAvailable_setsMediaAsExpanded() {
+        setSplitShadeEnabled(true)
+        whenever(mediaFlags.useMediaSessionLayout()).thenReturn(true)
+
+        controller.onInit()
+
+        verify(mediaHost).expansion = MediaHostState.EXPANDED
+    }
+
+    @Test
+    fun onInit_inSplitShade_newMediaLayoutNotAvailable_setsMediaAsCollapsed() {
+        setSplitShadeEnabled(true)
+        whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false)
+
+        controller.onInit()
+
+        verify(mediaHost).expansion = MediaHostState.COLLAPSED
+    }
+
+    private fun setSplitShadeEnabled(enabled: Boolean) {
+        mContext.orCreateTestableResources
+            .addOverride(R.bool.config_use_split_notification_shade, enabled)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
index 2b7fa42..1501346 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSSecurityFooterTest.java
@@ -53,6 +53,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogLaunchAnimator;
+import com.android.systemui.flags.FeatureFlags;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.statusbar.policy.SecurityController;
@@ -102,6 +103,8 @@
     private ActivityStarter mActivityStarter;
     @Mock
     private DialogLaunchAnimator mDialogLaunchAnimator;
+    @Mock
+    private FeatureFlags mFeatureFlags;
 
     private TestableLooper mTestableLooper;
 
@@ -115,7 +118,8 @@
                 .replace("ImageView", TestableImageView.class)
                 .build().inflate(R.layout.quick_settings_security_footer, null, false);
         mFooter = new QSSecurityFooter(mRootView, mUserTracker, new Handler(looper),
-                mActivityStarter, mSecurityController, mDialogLaunchAnimator, looper);
+                mActivityStarter, mSecurityController, mDialogLaunchAnimator, looper,
+                mFeatureFlags);
         mFooterText = mRootView.findViewById(R.id.footer_text);
         mPrimaryFooterIcon = mRootView.findViewById(R.id.primary_footer_icon);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
index 8872e28..e67d37ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -65,7 +65,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.settings.FakeSettings;
@@ -112,7 +112,7 @@
     @Mock
     private QSTile.State mMockState;
     @Mock
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     @Mock
     private QSLogger mQSLogger;
     @Mock
@@ -152,7 +152,7 @@
                 QSTileHost.TILES_SETTING, "", "", false, mUserTracker.getUserId(), false);
         mQSTileHost = new TestQSTileHost(mContext, mIconController, mDefaultFactory, mHandler,
                 mLooper.getLooper(), mPluginManager, mTunerService, mAutoTiles, mDumpManager,
-                mBroadcastDispatcher, mStatusBar, mQSLogger, mUiEventLogger, mUserTracker,
+                mBroadcastDispatcher, mCentralSurfaces, mQSLogger, mUiEventLogger, mUserTracker,
                 mSecureSettings, mCustomTileStatePersister, mTileServiceRequestControllerBuilder,
                 mTileLifecycleManagerFactory);
         setUpTileFactory();
@@ -437,15 +437,15 @@
                 QSFactory defaultFactory, Handler mainHandler, Looper bgLooper,
                 PluginManager pluginManager, TunerService tunerService,
                 Provider<AutoTileManager> autoTiles, DumpManager dumpManager,
-                BroadcastDispatcher broadcastDispatcher, StatusBar statusBar, QSLogger qsLogger,
-                UiEventLogger uiEventLogger, UserTracker userTracker,
+                BroadcastDispatcher broadcastDispatcher, CentralSurfaces centralSurfaces,
+                QSLogger qsLogger, UiEventLogger uiEventLogger, UserTracker userTracker,
                 SecureSettings secureSettings, CustomTileStatePersister customTileStatePersister,
                 TileServiceRequestController.Builder tileServiceRequestControllerBuilder,
                 TileLifecycleManager.Factory tileLifecycleManagerFactory) {
             super(context, iconController, defaultFactory, mainHandler, bgLooper, pluginManager,
                     tunerService, autoTiles, dumpManager, broadcastDispatcher,
-                    Optional.of(statusBar), qsLogger, uiEventLogger, userTracker, secureSettings,
-                    customTileStatePersister, tileServiceRequestControllerBuilder,
+                    Optional.of(centralSurfaces), qsLogger, uiEventLogger, userTracker,
+                    secureSettings, customTileStatePersister, tileServiceRequestControllerBuilder,
                     tileLifecycleManagerFactory);
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
index b559d18..04b50d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -34,6 +35,7 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
 import android.content.pm.PackageInfo;
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
@@ -56,7 +58,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
+import org.mockito.ArgumentCaptor;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -64,10 +66,10 @@
     private static final int TEST_FAIL_TIMEOUT = 5000;
 
     private final PackageManagerAdapter mMockPackageManagerAdapter =
-            Mockito.mock(PackageManagerAdapter.class);
+            mock(PackageManagerAdapter.class);
     private final BroadcastDispatcher mMockBroadcastDispatcher =
-            Mockito.mock(BroadcastDispatcher.class);
-    private final IQSTileService.Stub mMockTileService = Mockito.mock(IQSTileService.Stub.class);
+            mock(BroadcastDispatcher.class);
+    private final IQSTileService.Stub mMockTileService = mock(IQSTileService.Stub.class);
     private ComponentName mTileServiceComponentName;
     private Intent mTileServiceIntent;
     private UserHandle mUser;
@@ -95,7 +97,7 @@
         mThread.start();
         mHandler = Handler.createAsync(mThread.getLooper());
         mStateManager = new TileLifecycleManager(mHandler, mWrappedContext,
-                Mockito.mock(IQSService.class),
+                mock(IQSService.class),
                 mMockPackageManagerAdapter,
                 mMockBroadcastDispatcher,
                 mTileServiceIntent,
@@ -269,6 +271,25 @@
         assertTrue(mStateManager.isToggleableTile());
     }
 
+    @Test
+    public void testFalseBindCallsUnbind() {
+        Context falseContext = mock(Context.class);
+        when(falseContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(false);
+        TileLifecycleManager manager = new TileLifecycleManager(mHandler, falseContext,
+                mock(IQSService.class),
+                mMockPackageManagerAdapter,
+                mMockBroadcastDispatcher,
+                mTileServiceIntent,
+                mUser);
+
+        manager.setBindService(true);
+
+        ArgumentCaptor<ServiceConnection> captor = ArgumentCaptor.forClass(ServiceConnection.class);
+        verify(falseContext).bindServiceAsUser(any(), captor.capture(), anyInt(), any());
+
+        verify(falseContext).unbindService(captor.getValue());
+    }
+
     private static class TestContextWrapper extends ContextWrapper {
         private IntentFilter mLastIntentFilter;
         private int mLastFlag;
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 e39d6a1..19a9863 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
@@ -50,7 +50,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.AutoTileManager;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.BluetoothController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -91,7 +91,7 @@
     @Mock
     private DumpManager mDumpManager;
     @Mock
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     @Mock
     private QSLogger mQSLogger;
     @Mock
@@ -132,7 +132,7 @@
                 () -> mAutoTileManager,
                 mDumpManager,
                 mock(BroadcastDispatcher.class),
-                Optional.of(mStatusBar),
+                Optional.of(mCentralSurfaces),
                 mQSLogger,
                 mUiEventLogger,
                 mUserTracker,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
index ea4d7cc..c5bc68d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileImplTest.java
@@ -45,6 +45,7 @@
 import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.Looper;
+import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -58,6 +59,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.testing.UiEventLoggerFake;
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
@@ -101,6 +103,7 @@
     private StatusBarStateController mStatusBarStateController;
     @Mock
     private ActivityStarter mActivityStarter;
+
     private UiEventLoggerFake mUiEventLoggerFake;
     private InstanceId mInstanceId = InstanceId.fakeInstanceId(5);
 
@@ -113,7 +116,7 @@
         mTestableLooper = TestableLooper.get(this);
         mUiEventLoggerFake = new UiEventLoggerFake();
         when(mHost.indexOf(SPEC)).thenReturn(POSITION);
-        when(mHost.getContext()).thenReturn(mContext.getBaseContext());
+        when(mHost.getContext()).thenReturn(mContext);
         when(mHost.getUiEventLogger()).thenReturn(mUiEventLoggerFake);
         when(mHost.getNewInstanceId()).thenReturn(mInstanceId);
 
@@ -342,6 +345,22 @@
         mTestableLooper.processAllMessages();
     }
 
+    @Test
+    public void testClickOnDisabledByPolicyDoesntClickLaunchesIntent() {
+        String restriction = "RESTRICTION";
+        mTile.getState().disabledByPolicy = true;
+        EnforcedAdmin admin = EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(restriction);
+        mTile.setEnforcedAdmin(admin);
+
+        mTile.click(null);
+        mTestableLooper.processAllMessages();
+        assertFalse(mTile.mClicked);
+
+        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mActivityStarter).postStartActivityDismissingKeyguard(captor.capture(), anyInt());
+        assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, captor.getValue().getAction());
+    }
+
     private void assertEvent(UiEventLogger.UiEventEnum eventType,
             UiEventLoggerFake.FakeUiEvent fakeEvent) {
         assertEquals(eventType.getId(), fakeEvent.eventId);
@@ -400,6 +419,10 @@
             getState().state = Tile.STATE_ACTIVE;
         }
 
+        public void setEnforcedAdmin(EnforcedAdmin admin) {
+            mEnforcedAdmin = admin;
+        }
+
         @Override
         public BooleanState newTileState() {
             return new BooleanState();
@@ -412,7 +435,6 @@
 
         @Override
         protected void handleUpdateState(BooleanState state, Object arg) {
-
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
new file mode 100644
index 0000000..cc47248
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
@@ -0,0 +1,117 @@
+package com.android.systemui.qs.tiles
+
+import android.content.Context
+import android.os.Handler
+import android.os.Looper
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.MetricsLogger
+import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.plugins.qs.QSTile
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.statusbar.policy.BluetoothController
+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.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class BluetoothTileTest : SysuiTestCase() {
+
+    @Mock
+    private lateinit var mockContext: Context
+    @Mock
+    private lateinit var qsLogger: QSLogger
+    @Mock
+    private lateinit var qsHost: QSTileHost
+    @Mock
+    private lateinit var metricsLogger: MetricsLogger
+    private val falsingManager = FalsingManagerFake()
+    @Mock
+    private lateinit var statusBarStateController: StatusBarStateController
+    @Mock
+    private lateinit var activityStarter: ActivityStarter
+    @Mock
+    private lateinit var bluetoothController: BluetoothController
+
+    private val uiEventLogger = UiEventLoggerFake()
+    private lateinit var testableLooper: TestableLooper
+    private lateinit var tile: FakeBluetoothTile
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        testableLooper = TestableLooper.get(this)
+
+        Mockito.`when`(qsHost.context).thenReturn(mockContext)
+        Mockito.`when`(qsHost.uiEventLogger).thenReturn(uiEventLogger)
+
+        tile = FakeBluetoothTile(
+            qsHost,
+            testableLooper.looper,
+            Handler(testableLooper.looper),
+            falsingManager,
+            metricsLogger,
+            statusBarStateController,
+            activityStarter,
+            qsLogger,
+            bluetoothController
+        )
+
+        tile.initialize()
+        testableLooper.processAllMessages()
+    }
+
+    @Test
+    fun testRestrictionChecked() {
+        tile.refreshState()
+        testableLooper.processAllMessages()
+
+        assertThat(tile.restrictionChecked).isEqualTo(UserManager.DISALLOW_BLUETOOTH)
+    }
+
+    private class FakeBluetoothTile(
+        qsTileHost: QSTileHost,
+        backgroundLooper: Looper,
+        mainHandler: Handler,
+        falsingManager: FalsingManager,
+        metricsLogger: MetricsLogger,
+        statusBarStateController: StatusBarStateController,
+        activityStarter: ActivityStarter,
+        qsLogger: QSLogger,
+        bluetoothController: BluetoothController
+    ) : BluetoothTile(
+        qsTileHost,
+        backgroundLooper,
+        mainHandler,
+        falsingManager,
+        metricsLogger,
+        statusBarStateController,
+        activityStarter,
+        qsLogger,
+        bluetoothController
+    ) {
+        var restrictionChecked: String? = null
+
+        override fun checkIfRestrictionEnforcedByAdminOnly(
+            state: QSTile.State?,
+            userRestriction: String?
+        ) {
+            restrictionChecked = userRestriction
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
index bfe875c..7ab49584f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ActionProxyReceiverTest.java
@@ -19,7 +19,7 @@
 import static com.android.systemui.screenshot.ScreenshotController.ACTION_TYPE_SHARE;
 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_ID;
 import static com.android.systemui.screenshot.ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED;
-import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_SCREENSHOT;
+import static com.android.systemui.statusbar.phone.CentralSurfaces.SYSTEM_DIALOG_REASON_SCREENSHOT;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -41,7 +41,7 @@
 
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -59,7 +59,7 @@
 public class ActionProxyReceiverTest extends SysuiTestCase {
 
     @Mock
-    private StatusBar mMockStatusBar;
+    private CentralSurfaces mMockCentralSurfaces;
     @Mock
     private ActivityManagerWrapper mMockActivityManagerWrapper;
     @Mock
@@ -83,7 +83,7 @@
         actionProxyReceiver.onReceive(mContext, mIntent);
 
         verify(mMockActivityManagerWrapper).closeSystemWindows(SYSTEM_DIALOG_REASON_SCREENSHOT);
-        verify(mMockStatusBar, never()).executeRunnableDismissingKeyguard(
+        verify(mMockCentralSurfaces, never()).executeRunnableDismissingKeyguard(
                 any(Runnable.class), any(Runnable.class), anyBoolean(), anyBoolean(), anyBoolean());
         verify(mMockPendingIntent).send(
                 eq(mContext), anyInt(), isNull(), isNull(), isNull(), isNull(), any(Bundle.class));
@@ -96,13 +96,13 @@
         doAnswer((Answer<Object>) invocation -> {
             ((Runnable) invocation.getArgument(0)).run();
             return null;
-        }).when(mMockStatusBar).executeRunnableDismissingKeyguard(
+        }).when(mMockCentralSurfaces).executeRunnableDismissingKeyguard(
                 any(Runnable.class), isNull(), anyBoolean(), anyBoolean(), anyBoolean());
 
         actionProxyReceiver.onReceive(mContext, mIntent);
 
         verify(mMockActivityManagerWrapper).closeSystemWindows(SYSTEM_DIALOG_REASON_SCREENSHOT);
-        verify(mMockStatusBar).executeRunnableDismissingKeyguard(
+        verify(mMockCentralSurfaces).executeRunnableDismissingKeyguard(
                 any(Runnable.class), isNull(), eq(true), eq(true), eq(true));
         verify(mMockPendingIntent).send(
                 eq(mContext), anyInt(), isNull(), isNull(), isNull(), isNull(), any(Bundle.class));
@@ -135,7 +135,7 @@
     private ActionProxyReceiver constructActionProxyReceiver(boolean withStatusBar) {
         if (withStatusBar) {
             return new ActionProxyReceiver(
-                    Optional.of(mMockStatusBar), mMockActivityManagerWrapper,
+                    Optional.of(mMockCentralSurfaces), mMockActivityManagerWrapper,
                     mMockScreenshotSmartActions);
         } else {
             return new ActionProxyReceiver(
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/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 6c29ecc..11f76a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -448,9 +448,10 @@
 
     @Test
     public void testOnBiometricAuthenticated() {
-        mCommandQueue.onBiometricAuthenticated();
+        final int id = 12;
+        mCommandQueue.onBiometricAuthenticated(id);
         waitForIdleSync();
-        verify(mCallbacks).onBiometricAuthenticated();
+        verify(mCallbacks).onBiometricAuthenticated(eq(id));
     }
 
     @Test
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 466d954..3c1a73e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -45,7 +45,6 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -66,15 +65,17 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
 import android.view.ViewGroup;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
@@ -106,7 +107,8 @@
 import java.util.Collections;
 
 @SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
 public class KeyguardIndicationControllerTest extends SysuiTestCase {
 
     private static final String ORGANIZATION_NAME = "organization";
@@ -164,11 +166,15 @@
     @Captor
     private ArgumentCaptor<KeyguardIndication> mKeyguardIndicationCaptor;
     @Captor
+    private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
+    @Captor
     private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallbackCaptor;
     private KeyguardStateController.Callback mKeyguardStateControllerCallback;
+    private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
     private StatusBarStateController.StateListener mStatusBarStateListener;
     private BroadcastReceiver mBroadcastReceiver;
     private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+    private TestableLooper mTestableLooper;
 
     private KeyguardIndicationTextView mTextView; // AOD text
 
@@ -181,6 +187,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mTestableLooper = TestableLooper.get(this);
         mTextView = new KeyguardIndicationTextView(mContext);
         mTextView.setAnimationsEnabled(false);
 
@@ -226,7 +233,10 @@
             Looper.prepare();
         }
 
-        mController = new KeyguardIndicationController(mContext, mWakeLockBuilder,
+        mController = new KeyguardIndicationController(
+                mContext,
+                mTestableLooper.getLooper(),
+                mWakeLockBuilder,
                 mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
                 mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
                 mUserManager, mExecutor, mExecutor,  mFalsingManager, mLockPatternUtils,
@@ -245,6 +255,10 @@
                 mKeyguardStateControllerCallbackCaptor.capture());
         mKeyguardStateControllerCallback = mKeyguardStateControllerCallbackCaptor.getValue();
 
+        verify(mKeyguardUpdateMonitor).registerCallback(
+                mKeyguardUpdateMonitorCallbackCaptor.capture());
+        mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue();
+
         mExecutor.runAllReady();
         reset(mRotateTextViewController);
     }
@@ -267,7 +281,7 @@
             mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_POOR);
         });
         mInstrumentation.waitForIdleSync();
-
+        mTestableLooper.processAllMessages();
 
         verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT,
                 mContext.getResources().getString(R.string.dock_alignment_slow_charging));
@@ -285,6 +299,7 @@
             mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE);
         });
         mInstrumentation.waitForIdleSync();
+        mTestableLooper.processAllMessages();
 
         verifyIndicationMessage(INDICATION_TYPE_ALIGNMENT,
                 mContext.getResources().getString(R.string.dock_alignment_not_charging));
@@ -303,6 +318,7 @@
             mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_POOR);
         });
         mInstrumentation.waitForIdleSync();
+        mTestableLooper.processAllMessages();
 
         assertThat(mTextView.getText()).isEqualTo(
                 mContext.getResources().getString(R.string.dock_alignment_slow_charging));
@@ -321,6 +337,7 @@
             mAlignmentListener.getValue().onAlignmentStateChanged(DockManager.ALIGN_STATE_TERRIBLE);
         });
         mInstrumentation.waitForIdleSync();
+        mTestableLooper.processAllMessages();
 
         assertThat(mTextView.getText()).isEqualTo(
                 mContext.getResources().getString(R.string.dock_alignment_not_charging));
@@ -331,9 +348,12 @@
     @Test
     public void disclosure_unmanaged() {
         createController();
+        mController.setVisible(true);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
         when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(false);
+        reset(mRotateTextViewController);
+
         sendUpdateDisclosureBroadcast();
         mExecutor.runAllReady();
 
@@ -347,6 +367,7 @@
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
         sendUpdateDisclosureBroadcast();
+        mController.setVisible(true);
         mExecutor.runAllReady();
 
         verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mDisclosureGeneric);
@@ -355,6 +376,7 @@
     @Test
     public void disclosure_orgOwnedDeviceWithManagedProfile_noOrganizationName() {
         createController();
+        mController.setVisible(true);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
         when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList(
@@ -369,6 +391,7 @@
     @Test
     public void disclosure_deviceOwner_withOrganizationName() {
         createController();
+        mController.setVisible(true);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
@@ -381,6 +404,7 @@
     @Test
     public void disclosure_orgOwnedDeviceWithManagedProfile_withOrganizationName() {
         createController();
+        mController.setVisible(true);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mDevicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile()).thenReturn(true);
         when(mUserManager.getProfiles(anyInt())).thenReturn(Collections.singletonList(
@@ -397,6 +421,7 @@
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
         createController();
+        mController.setVisible(true);
 
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
@@ -424,7 +449,7 @@
     @Test
     public void disclosure_deviceOwner_financedDeviceWithOrganizationName() {
         createController();
-
+        mController.setVisible(true);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
         when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
@@ -432,6 +457,7 @@
                 .thenReturn(DEVICE_OWNER_TYPE_FINANCED);
         sendUpdateDisclosureBroadcast();
         mExecutor.runAllReady();
+        mController.setVisible(true);
 
         verifyIndicationMessage(INDICATION_TYPE_DISCLOSURE, mFinancedDisclosureWithOrganization);
     }
@@ -469,10 +495,10 @@
     @Test
     public void transientIndication_visibleWhenDozing() {
         createController();
-
         mController.setVisible(true);
-        mController.showTransientIndication(TEST_STRING_RES);
+
         mStatusBarStateListener.onDozingChanged(true);
+        mController.showTransientIndication(TEST_STRING_RES);
 
         assertThat(mTextView.getText()).isEqualTo(
                 mContext.getResources().getString(TEST_STRING_RES));
@@ -493,7 +519,7 @@
         reset(mRotateTextViewController);
         mStatusBarStateListener.onDozingChanged(true);
 
-        verifyHideIndication(INDICATION_TYPE_BIOMETRIC_MESSAGE);
+        assertThat(mTextView.getText()).isNotEqualTo(message);
     }
 
     @Test
@@ -604,10 +630,9 @@
     }
 
     @Test
-    public void updateMonitor_listener() {
+    public void registersKeyguardStateCallback() {
         createController();
         verify(mKeyguardStateController).addCallback(any());
-        verify(mKeyguardUpdateMonitor, times(2)).registerCallback(any());
     }
 
     @Test
@@ -695,13 +720,13 @@
     @Test
     public void onRefreshBatteryInfo_dozing_dischargingWithOverheat_presentBatteryPercentage() {
         createController();
+        mController.setVisible(true);
         BatteryStatus status = new BatteryStatus(BatteryManager.BATTERY_STATUS_DISCHARGING,
                 90 /* level */, 0 /* plugged */, BatteryManager.BATTERY_HEALTH_OVERHEAT,
                 0 /* maxChargingWattage */, true /* present */);
 
         mController.getKeyguardCallback().onRefreshBatteryInfo(status);
         mStatusBarStateListener.onDozingChanged(true);
-        mController.setVisible(true);
 
         String percentage = NumberFormat.getPercentInstance().format(90 / 100f);
         assertThat(mTextView.getText()).isEqualTo(percentage);
@@ -710,9 +735,9 @@
     @Test
     public void onRequireUnlockForNfc_showsRequireUnlockForNfcIndication() {
         createController();
+        mController.setVisible(true);
         String message = mContext.getString(R.string.require_unlock_for_nfc);
         mController.getKeyguardCallback().onRequireUnlockForNfc();
-        mController.setVisible(true);
 
         verifyTransientMessage(message);
     }
@@ -778,6 +803,9 @@
     @Test
     public void testOnKeyguardShowingChanged_showing_updatesPersistentMessages() {
         createController();
+        mController.setVisible(true);
+        mExecutor.runAllReady();
+        reset(mRotateTextViewController);
 
         // GIVEN keyguard is showing
         when(mKeyguardStateController.isShowing()).thenReturn(true);
@@ -799,6 +827,8 @@
     @Test
     public void onTrustGrantedMessageDoesNotShowUntilTrustGranted() {
         createController();
+        mController.setVisible(true);
+        reset(mRotateTextViewController);
 
         // GIVEN a trust granted message but trust isn't granted
         final String trustGrantedMsg = "testing trust granted message";
@@ -808,7 +838,7 @@
 
         // WHEN trust is granted
         when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
-        mController.setVisible(true);
+        mKeyguardUpdateMonitorCallback.onTrustChanged(KeyguardUpdateMonitor.getCurrentUser());
 
         // THEN verify the trust granted message shows
         verifyIndicationMessage(
@@ -819,6 +849,7 @@
     @Test
     public void onTrustGrantedMessageDoesShowsOnTrustGranted() {
         createController();
+        mController.setVisible(true);
 
         // GIVEN trust is granted
         when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
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 9076e16..067caa9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
@@ -22,8 +22,8 @@
 import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
 import com.android.systemui.statusbar.phone.NotificationPanelViewController
 import com.android.systemui.statusbar.phone.ScrimController
-import com.android.systemui.statusbar.phone.StatusBar
-import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.policy.FakeConfigurationController
 import org.junit.After
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertNotNull
@@ -66,17 +66,18 @@
     @Mock lateinit var wakefulnessLifecycle: WakefulnessLifecycle
     @Mock lateinit var mediaHierarchyManager: MediaHierarchyManager
     @Mock lateinit var scrimController: ScrimController
-    @Mock lateinit var configurationController: ConfigurationController
     @Mock lateinit var falsingManager: FalsingManager
     @Mock lateinit var notificationPanelController: NotificationPanelViewController
     @Mock lateinit var nsslController: NotificationStackScrollLayoutController
     @Mock lateinit var depthController: NotificationShadeDepthController
     @Mock lateinit var stackscroller: NotificationStackScrollLayout
     @Mock lateinit var expandHelperCallback: ExpandHelper.Callback
-    @Mock lateinit var statusbar: StatusBar
+    @Mock lateinit var mCentralSurfaces: CentralSurfaces
     @Mock lateinit var qS: QS
     @JvmField @Rule val mockito = MockitoJUnit.rule()
 
+    private val configurationController = FakeConfigurationController()
+
     @Before
     fun setup() {
         val helper = NotificationTestHelper(
@@ -86,6 +87,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,
@@ -105,7 +108,7 @@
         whenever(nsslController.view).thenReturn(stackscroller)
         whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
         transitionController.notificationPanelController = notificationPanelController
-        transitionController.statusbar = statusbar
+        transitionController.centralSurfaces = mCentralSurfaces
         transitionController.qS = qS
         transitionController.setStackScroller(nsslController)
         whenever(statusbarStateController.state).thenReturn(StatusBarState.KEYGUARD)
@@ -117,7 +120,7 @@
         whenever(lockScreenUserManager.isLockscreenPublicMode(anyInt())).thenReturn(true)
         whenever(falsingCollector.shouldEnforceBouncer()).thenReturn(false)
         whenever(keyguardBypassController.bypassEnabled).thenReturn(false)
-        clearInvocations(statusbar)
+        clearInvocations(mCentralSurfaces)
     }
 
     @After
@@ -174,7 +177,7 @@
 
     @Test
     fun testDontGoWhenShadeDisabled() {
-        whenever(statusbar.isShadeDisabled).thenReturn(true)
+        whenever(mCentralSurfaces.isShadeDisabled).thenReturn(true)
         transitionController.goToLockedShade(null)
         verify(statusbarStateController, never()).setState(anyInt())
     }
@@ -193,7 +196,7 @@
         transitionController.goToLockedShade(null)
         verify(statusbarStateController, never()).setState(anyInt())
         verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
-        verify(statusbar).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
+        verify(mCentralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
     }
 
     @Test
@@ -202,7 +205,7 @@
         transitionController.goToLockedShade(null)
         verify(statusbarStateController, never()).setState(anyInt())
         verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
-        verify(statusbar).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
+        verify(mCentralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
     }
 
     @Test
@@ -244,4 +247,38 @@
         verify(qS).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
         verify(depthController).transitionToFullShadeProgress = anyFloat()
     }
+
+    @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 setDragDownAmount_setsValueOnMediaHierarchyManager() {
+        transitionController.dragDownAmount = 10f
+
+        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
+    }
+
+    @Test
+    fun setDragDownAmount_inSplitShade_setsValueOnMediaHierarchyManager() {
+        enableSplitShade()
+
+        transitionController.dragDownAmount = 10f
+
+        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
+    }
+
+    private fun enableSplitShade() {
+        context.getOrCreateTestableResources().addOverride(
+            R.bool.config_use_split_notification_shade, true
+        )
+        configurationController.notifyConfigurationChanged()
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
index 4213b07..a4ce9cd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
@@ -47,8 +47,8 @@
 
 /**
  * Verifies that particular sets of dependencies don't have dependencies on others. For example,
- * code managing notifications shouldn't directly depend on StatusBar, since there are platforms
- * which want to manage notifications, but don't use StatusBar.
+ * code managing notifications shouldn't directly depend on CentralSurfaces, since there are
+ * platforms which want to manage notifications, but don't use CentralSurfaces.
  */
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index bd9f91f..2691ff9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -49,7 +49,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 
 import com.google.android.collect.Sets;
@@ -105,7 +105,7 @@
                 mVisibilityProvider,
                 mEntryManager,
                 mock(RemoteInputNotificationRebuilder.class),
-                () -> Optional.of(mock(StatusBar.class)),
+                () -> Optional.of(mock(CentralSurfaces.class)),
                 mStateController,
                 Handler.createAsync(Looper.myLooper()),
                 mRemoteInputUriController,
@@ -196,7 +196,7 @@
                 NotificationVisibilityProvider visibilityProvider,
                 NotificationEntryManager notificationEntryManager,
                 RemoteInputNotificationRebuilder rebuilder,
-                Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+                Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
                 StatusBarStateController statusBarStateController,
                 Handler mainHandler,
                 RemoteInputUriController remoteInputUriController,
@@ -211,7 +211,7 @@
                     visibilityProvider,
                     notificationEntryManager,
                     rebuilder,
-                    statusBarOptionalLazy,
+                    centralSurfacesOptionalLazy,
                     statusBarStateController,
                     mainHandler,
                     remoteInputUriController,
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/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 7fafb24..407044b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -54,7 +54,6 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
-import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -121,7 +120,6 @@
                 mock(KeyguardBypassController.class),
                 Optional.of(mock(Bubbles.class)),
                 mock(DynamicPrivacyController.class),
-                mock(ForegroundServiceSectionController.class),
                 mock(DynamicChildBindController.class),
                 mock(LowPriorityInflationHelper.class),
                 mock(AssistantFeedbackController.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index e0689f3..3500e4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -45,7 +45,7 @@
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
-import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.RemoteInputUriController;
 
 import org.junit.Before;
@@ -103,7 +103,7 @@
                 mVisibilityProvider,
                 mNotificationEntryManager,
                 new RemoteInputNotificationRebuilder(mContext),
-                () -> Optional.of(mock(StatusBar.class)),
+                () -> Optional.of(mock(CentralSurfaces.class)),
                 mStatusBarStateController,
                 Handler.createAsync(Looper.myLooper()),
                 mRemoteInputUriController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
index eef9dd4..ca8a20a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerBaseTest.java
@@ -125,6 +125,7 @@
     protected DemoModeController mDemoModeController;
     protected CarrierConfigTracker mCarrierConfigTracker;
     protected FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+    protected Handler mMainHandler;
     protected FeatureFlags mFeatureFlags;
 
     protected int mSubId;
@@ -174,9 +175,15 @@
         mMockNsm = mock(NetworkScoreManager.class);
         mMockSubDefaults = mock(SubscriptionDefaults.class);
         mCarrierConfigTracker = mock(CarrierConfigTracker.class);
+        mMainHandler = mock(Handler.class);
         mNetCapabilities = new NetworkCapabilities();
         when(mMockTm.isDataCapable()).thenReturn(true);
         when(mMockTm.createForSubscriptionId(anyInt())).thenReturn(mMockTm);
+
+        doAnswer(invocation -> {
+            ((Runnable) invocation.getArgument(0)).run();
+            return null;
+        }).when(mMainHandler).post(any());
         doAnswer(invocation -> {
             int rssi = invocation.getArgument(0);
             if (rssi < -88) return 0;
@@ -231,6 +238,7 @@
                 mMockBd,
                 mDemoModeController,
                 mCarrierConfigTracker,
+                mMainHandler,
                 mFeatureFlags,
                 mock(DumpManager.class)
         );
@@ -291,24 +299,6 @@
         mNetworkController.doUpdateMobileControllers();
     }
 
-    protected NetworkControllerImpl setUpNoMobileData() {
-        when(mMockTm.isDataCapable()).thenReturn(false);
-        NetworkControllerImpl networkControllerNoMobile =
-                new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager,
-                        mMockWm, mMockNsm, mMockSm,
-                        mConfig, TestableLooper.get(this).getLooper(), mFakeExecutor,
-                        mCallbackHandler,
-                        mock(AccessPointControllerImpl.class),
-                        mock(DataUsageController.class), mMockSubDefaults,
-                        mock(DeviceProvisionedController.class), mMockBd, mDemoModeController,
-                        mCarrierConfigTracker, mFeatureFlags,
-                        mock(DumpManager.class));
-
-        setupNetworkController();
-
-        return networkControllerNoMobile;
-    }
-
     // 2 Bars 3G GSM.
     public void setupDefaultSignal() {
         setIsGsm(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
index 138881a..ccfa1b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerDataTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.when;
 
 import android.net.NetworkCapabilities;
+import android.os.Handler;
 import android.os.Looper;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
@@ -130,8 +131,8 @@
                 mock(AccessPointControllerImpl.class),
                 mock(DataUsageController.class), mMockSubDefaults,
                 mock(DeviceProvisionedController.class), mMockBd, mDemoModeController,
-                mock(CarrierConfigTracker.class), mFeatureFlags,
-                mock(DumpManager.class));
+                mock(CarrierConfigTracker.class), new Handler(TestableLooper.get(this).getLooper()),
+                mFeatureFlags, mock(DumpManager.class));
         setupNetworkController();
 
         setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
index 6262a9b6..b84750a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerSignalTest.java
@@ -84,6 +84,7 @@
                 mMockBd,
                 mDemoModeController,
                 mCarrierConfigTracker,
+                mMainHandler,
                 mFeatureFlags,
                 mock(DumpManager.class)
         );
@@ -117,6 +118,7 @@
                 mMockBd,
                 mDemoModeController,
                 mCarrierConfigTracker,
+                mMainHandler,
                 mFeatureFlags,
                 mock(DumpManager.class)
         );
@@ -136,7 +138,8 @@
                 Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
-                mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
+                mDemoModeController, mock(CarrierConfigTracker.class),
+                mMainHandler, mFeatureFlags,
                 mock(DumpManager.class));
         setupNetworkController();
 
@@ -157,8 +160,8 @@
                 Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
-                mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
-                mock(DumpManager.class));
+                mDemoModeController, mock(CarrierConfigTracker.class),
+                mMainHandler, mFeatureFlags, mock(DumpManager.class));
         mNetworkController.registerListeners();
 
         // Wait for the main looper to execute the previous command
@@ -226,8 +229,8 @@
                 Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
                 mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
                 mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
-                mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
-                mock(DumpManager.class));
+                mDemoModeController, mock(CarrierConfigTracker.class),
+                mMainHandler, mFeatureFlags, mock(DumpManager.class));
         setupNetworkController();
 
         // No Subscriptions.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
index b7b3088..3f71491 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/NetworkControllerWifiTest.java
@@ -31,10 +31,11 @@
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.telephony.CellSignalStrength;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.settingslib.mobile.TelephonyIcons;
 
 import org.junit.Before;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
new file mode 100644
index 0000000..ea06647
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
@@ -0,0 +1,130 @@
+package com.android.systemui.statusbar.gesture
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.InputEvent
+import android.view.MotionEvent
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class GenericGestureDetectorTest : SysuiTestCase() {
+
+    private lateinit var gestureDetector: TestGestureDetector
+
+    @Before
+    fun setUp() {
+        gestureDetector = TestGestureDetector()
+    }
+
+    @Test
+    fun noCallbacksRegistered_notGestureListening() {
+        assertThat(gestureDetector.isGestureListening).isFalse()
+    }
+
+    @Test
+    fun callbackRegistered_isGestureListening() {
+        gestureDetector.addOnGestureDetectedCallback("tag"){}
+
+        assertThat(gestureDetector.isGestureListening).isTrue()
+    }
+
+    @Test
+    fun multipleCallbacksRegistered_isGestureListening() {
+        gestureDetector.addOnGestureDetectedCallback("tag"){}
+        gestureDetector.addOnGestureDetectedCallback("tag2"){}
+
+        assertThat(gestureDetector.isGestureListening).isTrue()
+    }
+
+    @Test
+    fun allCallbacksUnregistered_notGestureListening() {
+        gestureDetector.addOnGestureDetectedCallback("tag"){}
+        gestureDetector.addOnGestureDetectedCallback("tag2"){}
+
+        gestureDetector.removeOnGestureDetectedCallback("tag")
+        gestureDetector.removeOnGestureDetectedCallback("tag2")
+
+        assertThat(gestureDetector.isGestureListening).isFalse()
+    }
+
+    @Test
+    fun someButNotAllCallbacksUnregistered_isGestureListening() {
+        gestureDetector.addOnGestureDetectedCallback("tag"){}
+        gestureDetector.addOnGestureDetectedCallback("tag2"){}
+
+        gestureDetector.removeOnGestureDetectedCallback("tag2")
+
+        assertThat(gestureDetector.isGestureListening).isTrue()
+    }
+
+    @Test
+    fun onInputEvent_meetsGestureCriteria_allCallbacksNotified() {
+        var callbackNotified = false
+        gestureDetector.addOnGestureDetectedCallback("tag"){
+            callbackNotified = true
+        }
+
+        gestureDetector.onInputEvent(
+            MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X, 0f, 0)
+        )
+
+        assertThat(callbackNotified).isTrue()
+    }
+
+    @Test
+    fun onInputEvent_doesNotMeetGestureCriteria_callbackNotNotified() {
+        var callbackNotified = false
+        gestureDetector.addOnGestureDetectedCallback("tag"){
+            callbackNotified = true
+        }
+
+        gestureDetector.onInputEvent(
+            MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X - 5, 0f, 0)
+        )
+
+        assertThat(callbackNotified).isFalse()
+    }
+
+    @Test
+    fun callbackUnregisteredThenGestureDetected_oldCallbackNotNotified() {
+        var oldCallbackNotified = false
+        gestureDetector.addOnGestureDetectedCallback("tag"){
+            oldCallbackNotified = true
+        }
+        gestureDetector.addOnGestureDetectedCallback("tag2"){}
+
+        gestureDetector.removeOnGestureDetectedCallback("tag")
+        gestureDetector.onInputEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, CORRECT_X, 0f, 0))
+
+        assertThat(oldCallbackNotified).isFalse()
+    }
+
+    inner class TestGestureDetector : GenericGestureDetector("fakeTag") {
+        var isGestureListening = false
+
+        override fun onInputEvent(ev: InputEvent) {
+            if (ev is MotionEvent && ev.x == CORRECT_X) {
+                onGestureDetected(ev)
+            }
+        }
+
+        override fun startGestureListening() {
+            super.startGestureListening()
+            isGestureListening = true
+        }
+
+        override fun stopGestureListening() {
+            super.stopGestureListening()
+            isGestureListening = false
+        }
+    }
+}
+
+private const val CORRECT_X = 1234f
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index f2b7bf5..0fff5f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -201,7 +201,6 @@
                 () -> mNotificationRowBinder,
                 () -> mRemoteInputManager,
                 mLeakDetector,
-                mock(ForegroundServiceDismissalFeatureController.class),
                 mock(IStatusBarService.class),
                 NotifLiveDataStoreMocksKt.createNotifLiveDataStoreImplMock(),
                 mock(DumpManager.class)
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/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/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
index 4e309d4..0e18658 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
@@ -46,6 +46,7 @@
     private val sectionsFeatureManager: NotificationSectionsFeatureManager = mock()
     private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider = mock()
     private val viewBarn: NotifViewBarn = mock()
+    private val logger: NodeSpecBuilderLogger = mock()
 
     private var rootController: NodeController = buildFakeController("rootController")
     private var headerController0: NodeController = buildFakeController("header0")
@@ -75,7 +76,7 @@
         }
 
         specBuilder = NodeSpecBuilder(mediaContainerController, sectionsFeatureManager,
-                sectionHeaderVisibilityProvider, viewBarn)
+                sectionHeaderVisibilityProvider, viewBarn, logger)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index 52189e4..7fc5ece 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -61,7 +61,6 @@
 import com.android.systemui.statusbar.SbnBuilder;
 import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.notification.ConversationNotificationProcessor;
-import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationClicker;
 import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -191,7 +190,6 @@
                 () -> mRowBinder,
                 () -> mRemoteInputManager,
                 mLeakDetector,
-                mock(ForegroundServiceDismissalFeatureController.class),
                 mock(IStatusBarService.class),
                 NotifLiveDataStoreMocksKt.createNotifLiveDataStoreImplMock(),
                 mock(DumpManager.class)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 7d8e0d2..e9d8f58 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -82,8 +82,8 @@
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.wmshell.BubblesManager;
 
@@ -124,7 +124,7 @@
     @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener;
     @Mock private OnSettingsClickListener mOnSettingsClickListener;
     @Mock private DeviceProvisionedController mDeviceProvisionedController;
-    @Mock private StatusBar mStatusBar;
+    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private AccessibilityManager mAccessibilityManager;
     @Mock private HighPriorityProvider mHighPriorityProvider;
     @Mock private INotificationManager mINotificationManager;
@@ -155,7 +155,7 @@
         when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
 
         mGutsManager = new NotificationGutsManager(mContext,
-                () -> Optional.of(mStatusBar), mHandler, mHandler, mAccessibilityManager,
+                () -> Optional.of(mCentralSurfaces), mHandler, mHandler, mAccessibilityManager,
                 mHighPriorityProvider, mINotificationManager, mNotificationEntryManager,
                 mPeopleSpaceWidgetManager, mLauncherApps, mShortcutManager,
                 mChannelEditorDialogController, mContextTracker, mAssistantFeedbackController,
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 c4f954f..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
@@ -58,7 +58,6 @@
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.notification.DynamicPrivacyController;
-import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
 import com.android.systemui.statusbar.notification.NotifPipelineFlags;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
@@ -68,14 +67,13 @@
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.ForegroundServiceDungeonView;
 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.StatusBar;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -118,7 +116,7 @@
     @Mock(answer = Answers.RETURNS_SELF)
     private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
     @Mock private NotificationSwipeHelper mNotificationSwipeHelper;
-    @Mock private StatusBar mStatusBar;
+    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private ScrimController mScrimController;
     @Mock private NotificationGroupManagerLegacy mLegacyGroupManager;
     @Mock private SectionHeaderController mSilentHeaderController;
@@ -129,9 +127,6 @@
     @Mock private IStatusBarService mIStatusBarService;
     @Mock private UiEventLogger mUiEventLogger;
     @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
-    @Mock private ForegroundServiceDismissalFeatureController mFgFeatureController;
-    @Mock private ForegroundServiceSectionController mFgServicesSectionController;
-    @Mock private ForegroundServiceDungeonView mForegroundServiceDungeonView;
     @Mock private LayoutInflater mLayoutInflater;
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private VisualStabilityManager mVisualStabilityManager;
@@ -151,8 +146,6 @@
 
         when(mNotificationSwipeHelperBuilder.build()).thenReturn(mNotificationSwipeHelper);
         when(mNotifPipelineFlags.isNewPipelineEnabled()).thenReturn(false);
-        when(mFgServicesSectionController.createView(mLayoutInflater))
-                .thenReturn(mForegroundServiceDungeonView);
 
         mController = new NotificationStackScrollLayoutController(
                 true,
@@ -175,7 +168,7 @@
                 new FalsingManagerFake(),
                 mResources,
                 mNotificationSwipeHelperBuilder,
-                mStatusBar,
+                mCentralSurfaces,
                 mScrimController,
                 mLegacyGroupManager,
                 mLegacyGroupManager,
@@ -187,8 +180,6 @@
                 mLockscreenShadeTransitionController,
                 mIStatusBarService,
                 mUiEventLogger,
-                mFgFeatureController,
-                mFgServicesSectionController,
                 mLayoutInflater,
                 mRemoteInputManager,
                 mVisualStabilityManager,
@@ -287,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(
@@ -399,22 +389,6 @@
     }
 
     @Test
-    public void testForegroundDismissEnabled() {
-        when(mFgFeatureController.isForegroundServiceDismissalEnabled()).thenReturn(true);
-        mController.attach(mNotificationStackScrollLayout);
-        verify(mNotificationStackScrollLayout).initializeForegroundServiceSection(
-                mForegroundServiceDungeonView);
-    }
-
-    @Test
-    public void testForegroundDismissaDisabled() {
-        when(mFgFeatureController.isForegroundServiceDismissalEnabled()).thenReturn(false);
-        mController.attach(mNotificationStackScrollLayout);
-        verify(mNotificationStackScrollLayout, never()).initializeForegroundServiceSection(
-                any(ForegroundServiceDungeonView.class));
-    }
-
-    @Test
     public void testUpdateFooter_remoteInput() {
         ArgumentCaptor<RemoteInputController.Callback> callbackCaptor =
                 ArgumentCaptor.forClass(RemoteInputController.Callback.class);
@@ -436,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/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 4f731ed..eafcc35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -61,9 +61,9 @@
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.FooterView;
+import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.ShadeController;
-import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
 
 import org.junit.Assert;
@@ -89,7 +89,7 @@
     private AmbientState mAmbientState;
 
     @Rule public MockitoRule mockito = MockitoJUnit.rule();
-    @Mock private StatusBar mBar;
+    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private SysuiStatusBarStateController mBarState;
     @Mock private NotificationGroupManagerLegacy mGroupMembershipManger;
     @Mock private NotificationGroupManagerLegacy mGroupExpansionManager;
@@ -141,7 +141,7 @@
         mStackScrollerInternal.initView(getContext(), mNotificationSwipeHelper);
         mStackScroller = spy(mStackScrollerInternal);
         mStackScroller.setShelfController(notificationShelfController);
-        mStackScroller.setStatusBar(mBar);
+        mStackScroller.setCentralSurfaces(mCentralSurfaces);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
         when(mStackScrollLayoutController.isHistoryEnabled()).thenReturn(true);
         when(mStackScrollLayoutController.getNoticationRoundessManager())
@@ -149,7 +149,7 @@
         mStackScroller.setController(mStackScrollLayoutController);
 
         // Stub out functionality that isn't necessary to test.
-        doNothing().when(mBar)
+        doNothing().when(mCentralSurfaces)
                 .executeRunnableDismissingKeyguard(any(Runnable.class),
                         any(Runnable.class),
                         anyBoolean(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 2289936..0e12c2a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -52,6 +52,7 @@
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.qs.ReduceBrightColorsController;
 import com.android.systemui.qs.SettingObserver;
+import com.android.systemui.qs.external.CustomTile;
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.DataSaverController;
@@ -85,6 +86,7 @@
     private static final String TEST_SETTING_COMPONENT = "setting_component";
     private static final String TEST_COMPONENT = "test_pkg/test_cls";
     private static final String TEST_CUSTOM_SPEC = "custom(" + TEST_COMPONENT + ")";
+    private static final String TEST_CUSTOM_SAFETY_SPEC = "custom(safety_pkg/safety_cls)";
     private static final String SEPARATOR = AutoTileManager.SETTING_SEPARATOR;
 
     private static final int USER = 0;
@@ -121,6 +123,8 @@
         );
         mContext.getOrCreateTestableResources().addOverride(
                 com.android.internal.R.bool.config_nightDisplayAvailable, true);
+        mContext.getOrCreateTestableResources().addOverride(
+                R.string.safety_quick_settings_tile, TEST_CUSTOM_SAFETY_SPEC);
 
         when(mAutoAddTrackerBuilder.build()).thenReturn(mAutoAddTracker);
         when(mQsTileHost.getUserContext()).thenReturn(mUserContext);
@@ -435,6 +439,25 @@
     }
 
     @Test
+    public void testSafetyTileNotAdded_ifPreviouslyAdded() {
+        ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
+        mAutoTileManager.init();
+        verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+        when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(true);
+        mAutoTileManager.init();
+        verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+    }
+
+    @Test
+    public void testSafetyTileAdded_onUserChange() {
+        ComponentName safetyComponent = CustomTile.getComponentFromSpec(TEST_CUSTOM_SAFETY_SPEC);
+        mAutoTileManager.init();
+        verify(mQsTileHost, times(1)).addTile(safetyComponent, true);
+        when(mAutoAddTracker.isAdded(TEST_CUSTOM_SAFETY_SPEC)).thenReturn(false);
+        mAutoTileManager.changeUser(UserHandle.of(USER + 1));
+        verify(mQsTileHost, times(2)).addTile(safetyComponent, true);
+    }
+    @Test
     public void testEmptyArray_doesNotCrash() {
         mContext.getOrCreateTestableResources().addOverride(
                 R.array.config_quickSettingsAutoAdd, new String[0]);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
similarity index 86%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacksTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index aabf923..9bfb2c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -45,7 +45,6 @@
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -58,12 +57,11 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-public class StatusBarCommandQueueCallbacksTest extends SysuiTestCase {
-    @Mock private StatusBar mStatusBar;
+public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
+    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private ShadeController mShadeController;
     @Mock private CommandQueue mCommandQueue;
     @Mock private NotificationPanelViewController mNotificationPanelViewController;
-    @Mock private LegacySplitScreen mLegacySplitScreen;
     @Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
     private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
     @Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -83,20 +81,19 @@
     @Mock private LightBarController mLightBarController;
     @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
 
-    StatusBarCommandQueueCallbacks mSbcqCallbacks;
+    CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
 
-        mSbcqCallbacks = new StatusBarCommandQueueCallbacks(
-                mStatusBar,
+        mSbcqCallbacks = new CentralSurfacesCommandQueueCallbacks(
+                mCentralSurfaces,
                 mContext,
                 mContext.getResources(),
                 mShadeController,
                 mCommandQueue,
                 mNotificationPanelViewController,
-                Optional.of(mLegacySplitScreen),
                 mRemoteInputQuickSettingsDisabler,
                 mMetricsLogger,
                 mKeyguardUpdateMonitor,
@@ -125,13 +122,13 @@
 
     @Test
     public void testDisableNotificationShade() {
-        when(mStatusBar.getDisabled1()).thenReturn(StatusBarManager.DISABLE_NONE);
-        when(mStatusBar.getDisabled2()).thenReturn(StatusBarManager.DISABLE_NONE);
+        when(mCentralSurfaces.getDisabled1()).thenReturn(StatusBarManager.DISABLE_NONE);
+        when(mCentralSurfaces.getDisabled2()).thenReturn(StatusBarManager.DISABLE_NONE);
         when(mCommandQueue.panelsEnabled()).thenReturn(false);
         mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE,
                 StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false);
 
-        verify(mStatusBar).updateQsExpansionEnabled();
+        verify(mCentralSurfaces).updateQsExpansionEnabled();
         verify(mShadeController).animateCollapsePanels();
 
         // Trying to open it does nothing.
@@ -143,12 +140,13 @@
 
     @Test
     public void testEnableNotificationShade() {
-        when(mStatusBar.getDisabled1()).thenReturn(StatusBarManager.DISABLE_NONE);
-        when(mStatusBar.getDisabled2()).thenReturn(StatusBarManager.DISABLE2_NOTIFICATION_SHADE);
+        when(mCentralSurfaces.getDisabled1()).thenReturn(StatusBarManager.DISABLE_NONE);
+        when(mCentralSurfaces.getDisabled2())
+                .thenReturn(StatusBarManager.DISABLE2_NOTIFICATION_SHADE);
         when(mCommandQueue.panelsEnabled()).thenReturn(true);
         mSbcqCallbacks.disable(DEFAULT_DISPLAY, StatusBarManager.DISABLE_NONE,
                 StatusBarManager.DISABLE2_NONE, false);
-        verify(mStatusBar).updateQsExpansionEnabled();
+        verify(mCentralSurfaces).updateQsExpansionEnabled();
         verify(mShadeController, never()).animateCollapsePanels();
 
         // Can now be opened.
@@ -161,13 +159,13 @@
     @Test
     public void testSuppressAmbientDisplay_suppress() {
         mSbcqCallbacks.suppressAmbientDisplay(true);
-        verify(mDozeServiceHost).setDozeSuppressed(true);
+        verify(mDozeServiceHost).setAlwaysOnSuppressed(true);
     }
 
     @Test
     public void testSuppressAmbientDisplay_unsuppress() {
         mSbcqCallbacks.suppressAmbientDisplay(false);
-        verify(mDozeServiceHost).setDozeSuppressed(false);
+        verify(mDozeServiceHost).setAlwaysOnSuppressed(false);
     }
 
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
similarity index 90%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
index c7db9e4..3810783 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesTest.java
@@ -139,7 +139,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -159,7 +159,6 @@
 import com.android.systemui.volume.VolumeComponent;
 import com.android.systemui.wmshell.BubblesManager;
 import com.android.wm.shell.bubbles.Bubbles;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.startingsurface.StartingSurface;
 
 import org.junit.Before;
@@ -178,12 +177,12 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper(setAsMainLooper = true)
-public class StatusBarTest extends SysuiTestCase {
+public class CentralSurfacesTest extends SysuiTestCase {
 
     private static final int FOLD_STATE_FOLDED = 0;
     private static final int FOLD_STATE_UNFOLDED = 1;
 
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     private FakeMetricsLogger mMetricsLogger;
     private PowerManager mPowerManager;
     private TestableNotificationInterruptStateProviderImpl mNotificationInterruptStateProvider;
@@ -253,15 +252,12 @@
     @Mock private ViewMediatorCallback mKeyguardVieMediatorCallback;
     @Mock private VolumeComponent mVolumeComponent;
     @Mock private CommandQueue mCommandQueue;
-    @Mock private StatusBarComponent.Factory mStatusBarComponentFactory;
-    @Mock private StatusBarComponent mStatusBarComponent;
+    @Mock private CentralSurfacesComponent.Factory mStatusBarComponentFactory;
+    @Mock private CentralSurfacesComponent mCentralSurfacesComponent;
     @Mock private PluginManager mPluginManager;
-    @Mock private LegacySplitScreen mLegacySplitScreen;
     @Mock private ViewMediatorCallback mViewMediatorCallback;
     @Mock private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
     @Mock private ScreenPinningRequest mScreenPinningRequest;
-    @Mock private StatusBarNotificationActivityStarter.Builder
-            mStatusBarNotificationActivityStarterBuilder;
     @Mock private PluginDependencyProvider mPluginDependencyProvider;
     @Mock private KeyguardDismissUtil mKeyguardDismissUtil;
     @Mock private ExtensionController mExtensionController;
@@ -338,8 +334,6 @@
         mContext.setTheme(R.style.Theme_SystemUI_LightWallpaper);
 
         when(mStackScrollerController.getView()).thenReturn(mStackScroller);
-        when(mStackScrollerController.getNotificationListContainer()).thenReturn(
-                mNotificationListContainer);
         when(mStackScroller.generateLayoutParams(any())).thenReturn(new LayoutParams(0, 0));
         when(mNotificationPanelViewController.getView()).thenReturn(mNotificationPanelView);
         when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
@@ -370,8 +364,8 @@
         when(mLockscreenWallpaperLazy.get()).thenReturn(mLockscreenWallpaper);
         when(mBiometricUnlockControllerLazy.get()).thenReturn(mBiometricUnlockController);
 
-        when(mStatusBarComponentFactory.create()).thenReturn(mStatusBarComponent);
-        when(mStatusBarComponent.getNotificationShadeWindowViewController()).thenReturn(
+        when(mStatusBarComponentFactory.create()).thenReturn(mCentralSurfacesComponent);
+        when(mCentralSurfacesComponent.getNotificationShadeWindowViewController()).thenReturn(
                 mNotificationShadeWindowViewController);
         doAnswer(invocation -> {
             ((Runnable) invocation.getArgument(0)).run();
@@ -381,12 +375,12 @@
         mShadeController = new ShadeControllerImpl(mCommandQueue,
                 mStatusBarStateController, mNotificationShadeWindowController,
                 mStatusBarKeyguardViewManager, mContext.getSystemService(WindowManager.class),
-                () -> Optional.of(mStatusBar), () -> mAssistManager, Optional.of(mBubbles));
+                () -> Optional.of(mCentralSurfaces), () -> mAssistManager);
 
         when(mOperatorNameViewControllerFactory.create(any()))
                 .thenReturn(mOperatorNameViewController);
 
-        mStatusBar = new StatusBar(
+        mCentralSurfaces = new CentralSurfaces(
                 mContext,
                 mNotificationsController,
                 mock(FragmentService.class),
@@ -447,8 +441,6 @@
                 mCommandQueue,
                 mStatusBarComponentFactory,
                 mPluginManager,
-                Optional.of(mLegacySplitScreen),
-                mStatusBarNotificationActivityStarterBuilder,
                 mShadeController,
                 mStatusBarKeyguardViewManager,
                 mViewMediatorCallback,
@@ -483,8 +475,8 @@
                 mDeviceStateManager,
                 mDreamOverlayStateController,
                 mWiredChargingRippleController);
-        when(mKeyguardViewMediator.registerStatusBar(
-                any(StatusBar.class),
+        when(mKeyguardViewMediator.registerCentralSurfaces(
+                any(CentralSurfaces.class),
                 any(NotificationPanelViewController.class),
                 any(PanelExpansionStateManager.class),
                 any(BiometricUnlockController.class),
@@ -495,23 +487,23 @@
         when(mKeyguardViewMediator.getViewMediatorCallback()).thenReturn(
                 mKeyguardVieMediatorCallback);
 
-        // TODO: we should be able to call mStatusBar.start() and have all the below values
+        // TODO: we should be able to call mCentralSurfaces.start() and have all the below values
         // initialized automatically.
-        mStatusBar.mNotificationShadeWindowView = mNotificationShadeWindowView;
-        mStatusBar.mNotificationPanelViewController = mNotificationPanelViewController;
-        mStatusBar.mDozeScrimController = mDozeScrimController;
-        mStatusBar.mPresenter = mNotificationPresenter;
-        mStatusBar.mKeyguardIndicationController = mKeyguardIndicationController;
-        mStatusBar.mBarService = mBarService;
-        mStatusBar.mStackScroller = mStackScroller;
-        mStatusBar.startKeyguard();
+        mCentralSurfaces.mNotificationShadeWindowView = mNotificationShadeWindowView;
+        mCentralSurfaces.mNotificationPanelViewController = mNotificationPanelViewController;
+        mCentralSurfaces.mDozeScrimController = mDozeScrimController;
+        mCentralSurfaces.mPresenter = mNotificationPresenter;
+        mCentralSurfaces.mKeyguardIndicationController = mKeyguardIndicationController;
+        mCentralSurfaces.mBarService = mBarService;
+        mCentralSurfaces.mStackScroller = mStackScroller;
+        mCentralSurfaces.startKeyguard();
         mInitController.executePostInitTasks();
         notificationLogger.setUpWithContainer(mNotificationListContainer);
     }
 
     @Test
     public void testSetBouncerShowing_noCrash() {
-        mStatusBar.setBouncerShowing(true);
+        mCentralSurfaces.setBouncerShowing(true);
     }
 
     @Test
@@ -519,7 +511,7 @@
         when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
         when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(true);
 
-        mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
+        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, false, false, false);
     }
 
     @Test
@@ -527,7 +519,7 @@
         when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
         when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
 
-        mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
+        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, false, false, false);
     }
 
     @Test
@@ -535,7 +527,7 @@
         when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
         when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
 
-        mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
+        mCentralSurfaces.executeRunnableDismissingKeyguard(null, null, false, false, false);
     }
 
     @Test
@@ -547,7 +539,7 @@
         when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
         when(mKeyguardStateController.isMethodSecure()).thenReturn(false);
-        mStatusBar.onKeyguardViewManagerStatesUpdated();
+        mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
 
         MetricsAsserts.assertHasLog("missing hidden insecure lockscreen log",
                 mMetricsLogger.getLogs(),
@@ -566,7 +558,7 @@
         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
         when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
 
-        mStatusBar.onKeyguardViewManagerStatesUpdated();
+        mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
 
         MetricsAsserts.assertHasLog("missing hidden secure lockscreen log",
                 mMetricsLogger.getLogs(),
@@ -585,7 +577,7 @@
         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
         when(mKeyguardStateController.isMethodSecure()).thenReturn(false);
 
-        mStatusBar.onKeyguardViewManagerStatesUpdated();
+        mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
 
         MetricsAsserts.assertHasLog("missing insecure lockscreen showing",
                 mMetricsLogger.getLogs(),
@@ -604,7 +596,7 @@
         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
         when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
 
-        mStatusBar.onKeyguardViewManagerStatesUpdated();
+        mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
 
         MetricsAsserts.assertHasLog("missing secure lockscreen showing log",
                 mMetricsLogger.getLogs(),
@@ -623,7 +615,7 @@
         when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
         when(mKeyguardStateController.isMethodSecure()).thenReturn(true);
 
-        mStatusBar.onKeyguardViewManagerStatesUpdated();
+        mCentralSurfaces.onKeyguardViewManagerStatesUpdated();
 
         MetricsAsserts.assertHasLog("missing bouncer log",
                 mMetricsLogger.getLogs(),
@@ -724,7 +716,7 @@
     @Test
     public void testLogHidden() {
         try {
-            mStatusBar.handleVisibleToUserChanged(false);
+            mCentralSurfaces.handleVisibleToUserChanged(false);
             mUiBgExecutor.runAllReady();
             verify(mBarService, times(1)).onPanelHidden();
             verify(mBarService, never()).onPanelRevealed(anyBoolean(), anyInt());
@@ -739,10 +731,10 @@
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
         when(mNotificationsController.getActiveNotificationsCount()).thenReturn(5);
         when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(true);
-        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
 
         try {
-            mStatusBar.handleVisibleToUserChanged(true);
+            mCentralSurfaces.handleVisibleToUserChanged(true);
             mUiBgExecutor.runAllReady();
             verify(mBarService, never()).onPanelHidden();
             verify(mBarService, times(1)).onPanelRevealed(false, 1);
@@ -758,10 +750,10 @@
         when(mNotificationsController.getActiveNotificationsCount()).thenReturn(5);
 
         when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(false);
-        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
 
         try {
-            mStatusBar.handleVisibleToUserChanged(true);
+            mCentralSurfaces.handleVisibleToUserChanged(true);
             mUiBgExecutor.runAllReady();
             verify(mBarService, never()).onPanelHidden();
             verify(mBarService, times(1)).onPanelRevealed(true, 5);
@@ -776,10 +768,10 @@
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
         when(mNotificationsController.getActiveNotificationsCount()).thenReturn(5);
         when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(false);
-        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
+        mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
 
         try {
-            mStatusBar.handleVisibleToUserChanged(true);
+            mCentralSurfaces.handleVisibleToUserChanged(true);
             mUiBgExecutor.runAllReady();
             verify(mBarService, never()).onPanelHidden();
             verify(mBarService, times(1)).onPanelRevealed(false, 5);
@@ -791,18 +783,18 @@
 
     @Test
     public void testDump_DoesNotCrash() {
-        mStatusBar.dump(null, new PrintWriter(new ByteArrayOutputStream()), null);
+        mCentralSurfaces.dump(null, new PrintWriter(new ByteArrayOutputStream()), null);
     }
 
     @Test
     public void testDumpBarTransitions_DoesNotCrash() {
-        StatusBar.dumpBarTransitions(
+        CentralSurfaces.dumpBarTransitions(
                 new PrintWriter(new ByteArrayOutputStream()), "var", /* transitions= */ null);
     }
 
     @Test
     public void testFingerprintNotification_UpdatesScrims() {
-        mStatusBar.notifyBiometricAuthModeChanged();
+        mCentralSurfaces.notifyBiometricAuthModeChanged();
         verify(mScrimController).transitionTo(any(), any());
     }
 
@@ -811,81 +803,83 @@
         // Simulate unlocking from AoD with fingerprint.
         when(mBiometricUnlockController.getMode())
                 .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).transitionTo(eq(ScrimState.UNLOCKED), any());
     }
 
     @Test
     public void testTransitionLaunch_goesToUnlocked() {
-        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
-        mStatusBar.showKeyguardImpl();
+        mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
+        mCentralSurfaces.showKeyguardImpl();
 
         // Starting a pulse should change the scrim controller to the pulsing state
         when(mNotificationPanelViewController.isLaunchTransitionRunning()).thenReturn(true);
         when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(true);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).transitionTo(eq(ScrimState.UNLOCKED), any());
     }
 
     @Test
     public void testSetExpansionAffectsAlpha_whenKeyguardShowingButGoingAwayForAnyReason() {
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).setExpansionAffectsAlpha(eq(true));
 
         clearInvocations(mScrimController);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).setExpansionAffectsAlpha(eq(true));
 
         clearInvocations(mScrimController);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).setExpansionAffectsAlpha(eq(false));
 
         clearInvocations(mScrimController);
         when(mKeyguardStateController.isShowing()).thenReturn(true);
         when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).setExpansionAffectsAlpha(eq(false));
     }
 
     @Test
     public void testTransitionLaunch_noPreview_doesntGoUnlocked() {
-        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
-        mStatusBar.showKeyguardImpl();
+        mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        mCentralSurfaces.showKeyguardImpl();
 
         // Starting a pulse should change the scrim controller to the pulsing state
         when(mNotificationPanelViewController.isLaunchTransitionRunning()).thenReturn(true);
         when(mNotificationPanelViewController.isLaunchingAffordanceWithPreview()).thenReturn(false);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).transitionTo(eq(ScrimState.KEYGUARD));
     }
 
     @Test
     public void testSetOccluded_propagatesToScrimController() {
-        mStatusBar.setOccluded(true);
+        mCentralSurfaces.setOccluded(true);
         verify(mScrimController).setKeyguardOccluded(eq(true));
 
         reset(mScrimController);
-        mStatusBar.setOccluded(false);
+        mCentralSurfaces.setOccluded(false);
         verify(mScrimController).setKeyguardOccluded(eq(false));
     }
 
     @Test
     public void testPulseWhileDozing_updatesScrimController() {
-        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
-        mStatusBar.showKeyguardImpl();
+        mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
+        when(mKeyguardStateController.isShowing()).thenReturn(true);
+        mCentralSurfaces.showKeyguardImpl();
 
         // Starting a pulse should change the scrim controller to the pulsing state
         when(mDozeServiceHost.isPulsing()).thenReturn(true);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).transitionTo(eq(ScrimState.PULSING), any());
 
         // Ending a pulse should take it back to keyguard state
         when(mDozeServiceHost.isPulsing()).thenReturn(false);
-        mStatusBar.updateScrimController();
+        mCentralSurfaces.updateScrimController();
         verify(mScrimController).transitionTo(eq(ScrimState.KEYGUARD));
     }
 
@@ -893,45 +887,45 @@
     public void testShowKeyguardImplementation_setsState() {
         when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(new SparseArray<>());
 
-        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+        mCentralSurfaces.setBarStateForTest(StatusBarState.SHADE);
 
         // By default, showKeyguardImpl sets state to KEYGUARD.
-        mStatusBar.showKeyguardImpl();
+        mCentralSurfaces.showKeyguardImpl();
         verify(mStatusBarStateController).setState(
                 eq(StatusBarState.KEYGUARD), eq(false) /* force */);
     }
 
     @Test
     public void testOnStartedWakingUp_isNotDozing() {
-        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
+        mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
         when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true);
         when(mDozeServiceHost.getDozingRequested()).thenReturn(true);
-        mStatusBar.updateIsKeyguard();
+        mCentralSurfaces.updateIsKeyguard();
         // TODO: mNotificationPanelView.expand(false) gets called twice. Should be once.
         verify(mNotificationPanelViewController, times(2)).expand(eq(false));
         clearInvocations(mNotificationPanelViewController);
 
-        mStatusBar.mWakefulnessObserver.onStartedWakingUp();
+        mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
         verify(mDozeServiceHost).stopDozing();
         verify(mNotificationPanelViewController).expand(eq(false));
     }
 
     @Test
     public void testOnStartedWakingUp_doesNotDismissBouncer_whenPulsing() {
-        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
+        mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
         when(mStatusBarStateController.isKeyguardRequested()).thenReturn(true);
         when(mDozeServiceHost.getDozingRequested()).thenReturn(true);
-        mStatusBar.updateIsKeyguard();
+        mCentralSurfaces.updateIsKeyguard();
         clearInvocations(mNotificationPanelViewController);
 
-        mStatusBar.setBouncerShowing(true);
-        mStatusBar.mWakefulnessObserver.onStartedWakingUp();
+        mCentralSurfaces.setBouncerShowing(true);
+        mCentralSurfaces.mWakefulnessObserver.onStartedWakingUp();
         verify(mNotificationPanelViewController, never()).expand(anyBoolean());
     }
 
     @Test
     public void testRegisterBroadcastsonDispatcher() {
-        mStatusBar.registerBroadcastReceiver();
+        mCentralSurfaces.registerBroadcastReceiver();
         verify(mBroadcastDispatcher).registerReceiver(
                 any(BroadcastReceiver.class),
                 any(IntentFilter.class),
@@ -941,7 +935,7 @@
 
     @Test
     public void testUpdateResources_updatesBouncer() {
-        mStatusBar.updateResources();
+        mCentralSurfaces.updateResources();
 
         verify(mStatusBarKeyguardViewManager).updateResources();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index a14ea54..5f2bbd3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -27,6 +27,7 @@
 
 import android.content.res.Resources;
 import android.hardware.display.AmbientDisplayConfiguration;
+import android.os.Handler;
 import android.os.PowerManager;
 import android.provider.Settings;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -61,6 +62,7 @@
 public class DozeParametersTest extends SysuiTestCase {
     private DozeParameters mDozeParameters;
 
+    @Mock Handler mHandler;
     @Mock Resources mResources;
     @Mock private AmbientDisplayConfiguration mAmbientDisplayConfiguration;
     @Mock private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
@@ -102,6 +104,8 @@
                 .thenReturn(mFoldAodAnimationController);
 
         mDozeParameters = new DozeParameters(
+            mContext,
+            mHandler,
             mResources,
             mAmbientDisplayConfiguration,
             mAlwaysOnDisplayPolicy,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 6ce3b4b..26ac70c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -82,7 +82,7 @@
     @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock private PowerManager mPowerManager;
     @Mock private WakefulnessLifecycle mWakefullnessLifecycle;
-    @Mock private StatusBar mStatusBar;
+    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private NotificationIconAreaController mNotificationIconAreaController;
     @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -103,7 +103,7 @@
                 mAuthController, mNotificationIconAreaController);
 
         mDozeServiceHost.initialize(
-                mStatusBar,
+                mCentralSurfaces,
                 mStatusBarKeyguardViewManager,
                 mNotificationShadeWindowViewController,
                 mNotificationPanel,
@@ -119,7 +119,7 @@
 
         mDozeServiceHost.startDozing();
         verify(mStatusBarStateController).setIsDozing(eq(true));
-        verify(mStatusBar).updateIsKeyguard();
+        verify(mCentralSurfaces).updateIsKeyguard();
 
         mDozeServiceHost.stopDozing();
         verify(mStatusBarStateController).setIsDozing(eq(false));
@@ -128,8 +128,8 @@
 
     @Test
     public void testPulseWhileDozing_updatesScrimController() {
-        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
-        mStatusBar.showKeyguardImpl();
+        mCentralSurfaces.setBarStateForTest(StatusBarState.KEYGUARD);
+        mCentralSurfaces.showKeyguardImpl();
 
         // Keep track of callback to be able to stop the pulse
 //        DozeHost.PulseCallback[] pulseCallback = new DozeHost.PulseCallback[1];
@@ -154,12 +154,12 @@
 
         verify(mDozeScrimController).pulse(
                 pulseCallbackArgumentCaptor.capture(), eq(DozeLog.PULSE_REASON_NOTIFICATION));
-        verify(mStatusBar).updateScrimController();
-        reset(mStatusBar);
+        verify(mCentralSurfaces).updateScrimController();
+        reset(mCentralSurfaces);
 
         pulseCallbackArgumentCaptor.getValue().onPulseFinished();
         assertFalse(mDozeScrimController.isPulsing());
-        verify(mStatusBar).updateScrimController();
+        verify(mCentralSurfaces).updateScrimController();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 421d8f6a..db5741c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -63,7 +63,6 @@
     @Mock private NotificationGroupManagerLegacy mGroupManager;
     @Mock private View mNotificationShadeWindowView;
     @Mock private VisualStabilityProvider mVSProvider;
-    @Mock private StatusBar mBar;
     @Mock private StatusBarStateController mStatusBarStateController;
     @Mock private KeyguardBypassController mBypassController;
     @Mock private ConfigurationControllerImpl mConfigurationController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
index 3257a84..31465f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
@@ -25,7 +25,7 @@
 class KeyguardBottomAreaTest : SysuiTestCase() {
 
     @Mock
-    private lateinit var mStatusBar: StatusBar
+    private lateinit var mCentralSurfaces: CentralSurfaces
     private lateinit var mKeyguardBottomArea: KeyguardBottomAreaView
 
     @Before
@@ -42,7 +42,7 @@
 
         mKeyguardBottomArea = LayoutInflater.from(mContext).inflate(
                 R.layout.keyguard_bottom_area, null, false) as KeyguardBottomAreaView
-        mKeyguardBottomArea.setStatusBar(mStatusBar)
+        mKeyguardBottomArea.setCentralSurfaces(mCentralSurfaces)
     }
 
     @Test
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 479c271..6842295 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;
@@ -88,12 +87,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;
@@ -130,6 +123,7 @@
 import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
 import com.android.systemui.statusbar.notification.collection.legacy.NotificationGroupManagerLegacy;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
@@ -156,7 +150,6 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.stubbing.Answer;
 
-import java.lang.ref.WeakReference;
 import java.util.List;
 import java.util.Optional;
 
@@ -168,7 +161,7 @@
     private static final int NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE = 50;
 
     @Mock
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     @Mock
     private NotificationStackScrollLayout mNotificationStackScrollLayout;
     @Mock
@@ -270,21 +263,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;
@@ -358,6 +336,9 @@
     private NotificationShadeWindowController mNotificationShadeWindowController;
     @Mock
     private SysUiState mSysUiState;
+    @Mock
+    private NotificationListContainer mNotificationListContainer;
+    private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
     private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
     private SysuiStatusBarStateController mStatusBarStateController;
     private NotificationPanelViewController mNotificationPanelViewController;
@@ -387,8 +368,8 @@
         when(mResources.getBoolean(R.bool.config_enableNotificationShadeDrag)).thenReturn(true);
         when(mResources.getDimensionPixelSize(R.dimen.notifications_top_padding_split_shade))
                 .thenReturn(NOTIFICATION_SCRIM_TOP_PADDING_IN_SPLIT_SHADE);
-        when(mResources.getDimensionPixelSize(R.dimen.qs_panel_width)).thenReturn(400);
-        when(mResources.getDimensionPixelSize(R.dimen.notification_panel_width)).thenReturn(400);
+        when(mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_horizontal))
+                .thenReturn(10);
         when(mView.getContext()).thenReturn(getContext());
         when(mView.findViewById(R.id.keyguard_header)).thenReturn(mKeyguardStatusBar);
         when(mView.findViewById(R.id.keyguard_user_switcher_view)).thenReturn(mUserSwitcherView);
@@ -397,7 +378,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);
@@ -463,10 +443,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()))
@@ -485,6 +461,7 @@
         }).when(mNotificationShadeWindowController).batchApplyWindowLayoutParams(any());
 
         mMainHandler = new Handler(Looper.getMainLooper());
+        mPanelEventsEmitter = new NotificationPanelViewController.PanelEventsEmitter();
 
         mNotificationPanelViewController = new NotificationPanelViewController(mView,
                 mResources,
@@ -494,13 +471,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,
@@ -510,7 +487,6 @@
                 mKeyguardQsUserSwitchComponentFactory,
                 mKeyguardUserSwitcherComponentFactory,
                 mKeyguardStatusBarViewComponentFactory,
-                mCommunalViewComponentFactory,
                 mLockscreenShadeTransitionController,
                 mGroupManager,
                 mNotificationAreaController,
@@ -542,9 +518,11 @@
                 mInteractionJankMonitor,
                 mQsFrameTranslateController,
                 mSysUiState,
-                mKeyguardUnlockAnimationController);
+                mKeyguardUnlockAnimationController,
+                mNotificationListContainer,
+                mPanelEventsEmitter);
         mNotificationPanelViewController.initDependencies(
-                mStatusBar,
+                mCentralSurfaces,
                 () -> {},
                 mNotificationShelfController);
         mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
@@ -786,25 +764,31 @@
     }
 
     @Test
-    public void testSinglePaneShadeLayout_childrenHaveConstantWidth() {
-        enableSplitShade(/* enabled= */ false);
-
-        mNotificationPanelViewController.updateResources();
-
-        assertThat(getConstraintSetLayout(R.id.qs_frame).mWidth)
-                .isEqualTo(mResources.getDimensionPixelSize(R.dimen.qs_panel_width));
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).mWidth)
-                .isEqualTo(mResources.getDimensionPixelSize(R.dimen.notification_panel_width));
-    }
-
-    @Test
-    public void testSplitShadeLayout_childrenHaveZeroWidth() {
+    public void testSplitShadeLayout_childrenHaveInsideMarginsOfZero() {
         enableSplitShade(/* enabled= */ true);
 
         mNotificationPanelViewController.updateResources();
 
-        assertThat(getConstraintSetLayout(R.id.qs_frame).mWidth).isEqualTo(0);
-        assertThat(getConstraintSetLayout(R.id.notification_stack_scroller).mWidth).isEqualTo(0);
+        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
@@ -904,6 +888,7 @@
     public void testSwitchesToCorrectClockInSplitShade() {
         mStatusBarStateController.setState(KEYGUARD);
         enableSplitShade(/* enabled= */ true);
+        clearInvocations(mKeyguardStatusViewController);
 
         when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(0);
         triggerPositionClockAndNotifications();
@@ -918,11 +903,56 @@
     }
 
     @Test
+    public void testHasNotifications_switchesToLargeClockWhenEnteringSplitShade() {
+        mStatusBarStateController.setState(KEYGUARD);
+        when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(1);
+
+        enableSplitShade(/* enabled= */ true);
+
+        verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
+    }
+
+    @Test
+    public void testNoNotifications_switchesToLargeClockWhenEnteringSplitShade() {
+        mStatusBarStateController.setState(KEYGUARD);
+        when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(0);
+
+        enableSplitShade(/* enabled= */ true);
+
+        verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
+    }
+
+    @Test
+    public void testHasNotifications_switchesToSmallClockWhenExitingSplitShade() {
+        mStatusBarStateController.setState(KEYGUARD);
+        enableSplitShade(/* enabled= */ true);
+        clearInvocations(mKeyguardStatusViewController);
+        when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(1);
+
+        enableSplitShade(/* enabled= */ false);
+
+        verify(mKeyguardStatusViewController).displayClock(SMALL, /* animate */ true);
+    }
+
+    @Test
+    public void testNoNotifications_switchesToLargeClockWhenExitingSplitShade() {
+        mStatusBarStateController.setState(KEYGUARD);
+        enableSplitShade(/* enabled= */ true);
+        clearInvocations(mKeyguardStatusViewController);
+        when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(0);
+
+        enableSplitShade(/* enabled= */ false);
+
+        verify(mKeyguardStatusViewController).displayClock(LARGE, /* animate */ true);
+    }
+
+    @Test
     public void testSwitchesToBigClockInSplitShadeOnAod() {
         mStatusBarStateController.setState(KEYGUARD);
         enableSplitShade(/* enabled= */ true);
         when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
         when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(2);
+        clearInvocations(mKeyguardStatusViewController);
 
         mNotificationPanelViewController.setDozing(true, false, null);
 
@@ -934,6 +964,7 @@
         when(mScreenOffAnimationController.shouldAnimateClockChange()).thenReturn(false);
         mStatusBarStateController.setState(KEYGUARD);
         enableSplitShade(/* enabled= */ true);
+        clearInvocations(mKeyguardStatusViewController);
         when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
         when(mNotificationStackScrollLayoutController.getVisibleNotificationCount()).thenReturn(2);
 
@@ -946,6 +977,7 @@
     public void testDisplaysSmallClockOnLockscreenInSplitShadeWhenMediaIsPlaying() {
         mStatusBarStateController.setState(KEYGUARD);
         enableSplitShade(/* enabled= */ true);
+        clearInvocations(mKeyguardStatusViewController);
         when(mMediaDataManager.hasActiveMedia()).thenReturn(true);
 
         // one notification + media player visible
@@ -960,81 +992,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();
     }
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..5fb4144 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
@@ -5,6 +5,7 @@
 import android.view.WindowInsets
 import android.view.WindowManagerPolicyConstants
 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
@@ -40,6 +41,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
@@ -65,12 +67,18 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
+        mContext.ensureTestableResources()
+        whenever(notificationsQSContainer.resources).thenReturn(mContext.resources)
         notificationsQSContainerController = NotificationsQSContainerController(
                 notificationsQSContainer,
                 navigationModeController,
                 overviewProxyService,
                 featureFlags
         )
+
+        mContext.orCreateTestableResources
+            .addOverride(R.dimen.split_shade_notifications_scrim_margin_bottom, SCRIM_MARGIN)
+
         whenever(notificationsQSContainer.defaultNotificationsMarginBottom)
                 .thenReturn(NOTIFICATIONS_MARGIN)
         whenever(navigationModeController.addListener(navigationModeCaptor.capture()))
@@ -115,14 +123,14 @@
                 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
@@ -153,14 +161,14 @@
                 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
@@ -188,14 +196,15 @@
         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
@@ -392,6 +401,7 @@
 
     @Test
     fun testNotificationsMarginBottomIsUpdated() {
+        Mockito.clearInvocations(notificationsQSContainer)
         notificationsQSContainerController.splitShadeEnabled = true
         verify(notificationsQSContainer).setNotificationsMarginBottom(NOTIFICATIONS_MARGIN)
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index 671ab59..c797bc8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -32,6 +32,8 @@
 import static org.mockito.Mockito.when;
 
 import android.app.IActivityManager;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
@@ -228,6 +230,36 @@
     }
 
     @Test
+    public void rotationBecameAllowed_layoutParamsUpdated() {
+        mNotificationShadeWindowController.setKeyguardShowing(true);
+        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(false);
+        mNotificationShadeWindowController.onConfigChanged(new Configuration());
+        clearInvocations(mWindowManager);
+
+        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(true);
+        mNotificationShadeWindowController.onConfigChanged(new Configuration());
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat(mLayoutParameters.getValue().screenOrientation)
+                .isEqualTo(ActivityInfo.SCREEN_ORIENTATION_USER);
+    }
+
+    @Test
+    public void rotationBecameNotAllowed_layoutParamsUpdated() {
+        mNotificationShadeWindowController.setKeyguardShowing(true);
+        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(true);
+        mNotificationShadeWindowController.onConfigChanged(new Configuration());
+        clearInvocations(mWindowManager);
+
+        when(mKeyguardStateController.isKeyguardScreenRotationAllowed()).thenReturn(false);
+        mNotificationShadeWindowController.onConfigChanged(new Configuration());
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat(mLayoutParameters.getValue().screenOrientation)
+                .isEqualTo(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
+    }
+
+    @Test
     public void batchApplyWindowLayoutParams_doesNotDispatchEvents() {
         mNotificationShadeWindowController.setForceDozeBrightness(true);
         verify(mWindowManager).updateViewLayout(any(), any());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
index 34a5d4b..093f926 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewControllerTest.kt
@@ -61,7 +61,7 @@
     @Mock
     private lateinit var mStatusBarStateController: SysuiStatusBarStateController
     @Mock
-    private lateinit var mStatusBar: StatusBar
+    private lateinit var mCentralSurfaces: CentralSurfaces
     @Mock
     private lateinit var mDockManager: DockManager
     @Mock
@@ -107,10 +107,11 @@
             mStatusBarKeyguardViewManager,
             mStatusBarWindowStateController,
             mLockIconViewController,
-            Optional.of(mLowLightClockController)
+            Optional.of(mLowLightClockController),
+            mCentralSurfaces,
+            mNotificationShadeWindowController
         )
         mController.setupExpandedStatusBar()
-        mController.setService(mStatusBar, mNotificationShadeWindowController)
 
         mInteractionEventHandlerCaptor =
             ArgumentCaptor.forClass(InteractionEventHandler::class.java)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index 6c33113..62a1bcd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -71,7 +71,7 @@
     @Mock private DragDownHelper mDragDownHelper;
     @Mock private SysuiStatusBarStateController mStatusBarStateController;
     @Mock private ShadeController mShadeController;
-    @Mock private StatusBar mStatusBar;
+    @Mock private CentralSurfaces mCentralSurfaces;
     @Mock private DockManager mDockManager;
     @Mock private NotificationPanelViewController mNotificationPanelViewController;
     @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
@@ -115,9 +115,10 @@
                 mStatusBarKeyguardViewManager,
                 mStatusBarWindowStateController,
                 mLockIconViewController,
-                Optional.of(mLowLightClockController));
+                Optional.of(mLowLightClockController),
+                mCentralSurfaces,
+                mNotificationShadeWindowController);
         mController.setupExpandedStatusBar();
-        mController.setService(mStatusBar, mNotificationShadeWindowController);
         mController.setDragDownHelper(mDragDownHelper);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 5891161..9ab88dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.unfold.SysUIUnfoldComponent
 import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
+import com.android.systemui.util.view.ViewUtil
 import com.android.systemui.util.mockito.any
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
@@ -63,6 +64,8 @@
     private lateinit var configurationController: ConfigurationController
     @Mock
     private lateinit var userSwitcherController: StatusBarUserSwitcherController
+    @Mock
+    private lateinit var viewUtil: ViewUtil
 
     private lateinit var view: PhoneStatusBarView
     private lateinit var controller: PhoneStatusBarViewController
@@ -80,7 +83,6 @@
             val parent = FrameLayout(mContext) // add parent to keep layout params
             view = LayoutInflater.from(mContext)
                 .inflate(R.layout.status_bar, parent, false) as PhoneStatusBarView
-            view.setLeftTopRightBottom(VIEW_LEFT, VIEW_TOP, VIEW_RIGHT, VIEW_BOTTOM)
         }
 
         controller = createAndInitController(view)
@@ -111,64 +113,6 @@
         verify(moveFromCenterAnimation).onViewsReady(any())
     }
 
-    @Test
-    fun touchIsWithinView_inBounds_returnsTrue() {
-        val view = createViewMockWithScreenLocation()
-        controller = createAndInitController(view)
-
-        assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_TOP + 1f)).isTrue()
-    }
-
-    @Test
-    fun touchIsWithinView_onTopLeftCorner_returnsTrue() {
-        val view = createViewMockWithScreenLocation()
-        controller = createAndInitController(view)
-
-        assertThat(controller.touchIsWithinView(VIEW_LEFT.toFloat(), VIEW_TOP.toFloat())).isTrue()
-    }
-
-    @Test
-    fun touchIsWithinView_onBottomRightCorner_returnsTrue() {
-        val view = createViewMockWithScreenLocation()
-        controller = createAndInitController(view)
-
-        assertThat(controller.touchIsWithinView(
-            VIEW_RIGHT.toFloat(), VIEW_BOTTOM.toFloat())
-        ).isTrue()
-    }
-
-    @Test
-    fun touchIsWithinView_xTooSmall_returnsFalse() {
-        val view = createViewMockWithScreenLocation()
-        controller = createAndInitController(view)
-
-        assertThat(controller.touchIsWithinView(VIEW_LEFT - 1f, VIEW_TOP + 1f)).isFalse()
-    }
-
-    @Test
-    fun touchIsWithinView_xTooLarge_returnsFalse() {
-        val view = createViewMockWithScreenLocation()
-        controller = createAndInitController(view)
-
-        assertThat(controller.touchIsWithinView(VIEW_RIGHT + 1f, VIEW_TOP + 1f)).isFalse()
-    }
-
-    @Test
-    fun touchIsWithinView_yTooSmall_returnsFalse() {
-        val view = createViewMockWithScreenLocation()
-        controller = createAndInitController(view)
-
-        assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_TOP - 1f)).isFalse()
-    }
-
-    @Test
-    fun touchIsWithinView_yTooLarge_returnsFalse() {
-        val view = createViewMockWithScreenLocation()
-        controller = createAndInitController(view)
-
-        assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_BOTTOM + 1f)).isFalse()
-    }
-
     private fun createViewMock(): PhoneStatusBarView {
         val view = spy(view)
         val viewTreeObserver = mock(ViewTreeObserver::class.java)
@@ -177,20 +121,12 @@
         return view
     }
 
-    private fun createViewMockWithScreenLocation(): PhoneStatusBarView {
-        val view = spy(view)
-        val location = IntArray(2)
-        location[0] = VIEW_LEFT
-        location[1] = VIEW_TOP
-        `when`(view.locationOnScreen).thenReturn(location)
-        return view
-    }
-
     private fun createAndInitController(view: PhoneStatusBarView): PhoneStatusBarViewController {
         return PhoneStatusBarViewController.Factory(
             Optional.of(sysuiUnfoldComponent),
             Optional.of(progressProvider),
             userSwitcherController,
+            viewUtil,
             configurationController
         ).create(view, touchEventHandler).also {
             it.init()
@@ -215,8 +151,3 @@
         }
     }
 }
-
-private const val VIEW_LEFT = 30
-private const val VIEW_RIGHT = 100
-private const val VIEW_TOP = 40
-private const val VIEW_BOTTOM = 100
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/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 8b93de5..f4f55cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -75,7 +75,7 @@
     @Mock
     private KeyguardStateController mKeyguardStateController;
     @Mock
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     @Mock
     private ViewGroup mContainer;
     @Mock
@@ -118,7 +118,7 @@
                 any(ViewGroup.class),
                 any(KeyguardBouncer.BouncerExpansionCallback.class)))
                 .thenReturn(mBouncer);
-        when(mStatusBar.getBouncerContainer()).thenReturn(mContainer);
+        when(mCentralSurfaces.getBouncerContainer()).thenReturn(mContainer);
         when(mContainer.findViewById(anyInt())).thenReturn(mKeyguardMessageArea);
         mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(
                 getContext(),
@@ -138,8 +138,8 @@
                 Optional.of(mSysUiUnfoldComponent),
                 () -> mShadeController,
                 mLatencyTracker);
-        mStatusBarKeyguardViewManager.registerStatusBar(
-                mStatusBar,
+        mStatusBarKeyguardViewManager.registerCentralSurfaces(
+                mCentralSurfaces,
                 mNotificationPanelView,
                 new PanelExpansionStateManager(),
                 mBiometricUnlockController,
@@ -261,7 +261,7 @@
 
     @Test
     public void onPanelExpansionChanged_neverTranslatesBouncerWhenLaunchingApp() {
-        when(mStatusBar.isInLaunchTransition()).thenReturn(true);
+        when(mCentralSurfaces.isInLaunchTransition()).thenReturn(true);
         mStatusBarKeyguardViewManager.onPanelExpansionChanged(
                 /* fraction= */ KeyguardBouncer.EXPANSION_VISIBLE,
                 /* expanded= */ true,
@@ -272,12 +272,12 @@
     @Test
     public void setOccluded_animatesPanelExpansion_onlyIfBouncerHidden() {
         mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, true /* animated */);
-        verify(mStatusBar).animateKeyguardUnoccluding();
+        verify(mCentralSurfaces).animateKeyguardUnoccluding();
 
         when(mBouncer.isShowing()).thenReturn(true);
-        clearInvocations(mStatusBar);
+        clearInvocations(mCentralSurfaces);
         mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, true /* animated */);
-        verify(mStatusBar, never()).animateKeyguardUnoccluding();
+        verify(mCentralSurfaces, never()).animateKeyguardUnoccluding();
     }
 
     @Test
@@ -303,7 +303,7 @@
 
     @Test
     public void setOccluded_isInLaunchTransition_onKeyguardOccludedChangedCalled() {
-        when(mStatusBar.isInLaunchTransition()).thenReturn(true);
+        when(mCentralSurfaces.isInLaunchTransition()).thenReturn(true);
         mStatusBarKeyguardViewManager.show(null);
 
         mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
@@ -312,7 +312,7 @@
 
     @Test
     public void setOccluded_isLaunchingActivityOverLockscreen_onKeyguardOccludedChangedCalled() {
-        when(mStatusBar.isLaunchingActivityOverLockscreen()).thenReturn(true);
+        when(mCentralSurfaces.isLaunchingActivityOverLockscreen()).thenReturn(true);
         mStatusBarKeyguardViewManager.show(null);
 
         mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animated */);
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 743311f..27179fd 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;
@@ -113,7 +114,7 @@
     @Mock
     private NotificationRemoteInputManager mRemoteInputManager;
     @Mock
-    private StatusBar mStatusBar;
+    private CentralSurfaces mCentralSurfaces;
     @Mock
     private KeyguardStateController mKeyguardStateController;
     @Mock
@@ -130,7 +131,6 @@
     private NotifPipeline mNotifPipeline;
     @Mock
     private NotificationVisibilityProvider mVisibilityProvider;
-
     @Mock
     private ActivityIntentHelper mActivityIntentHelper;
     @Mock
@@ -145,14 +145,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;
 
@@ -201,9 +201,9 @@
                         NotificationListContainer.class),
                         headsUpManager,
                         mJankMonitor);
-
+        mLaunchEventsEmitter = new StatusBarNotificationActivityStarter.LaunchEventsEmitter();
         mNotificationActivityStarter =
-                new StatusBarNotificationActivityStarter.Builder(
+                new StatusBarNotificationActivityStarter(
                         getContext(),
                         mock(CommandQueue.class),
                         mHandler,
@@ -229,22 +229,21 @@
                         mock(LockPatternUtils.class),
                         mock(StatusBarRemoteInputCallback.class),
                         mActivityIntentHelper,
-
                         mNotifPipelineFlags,
                         mock(MetricsLogger.class),
                         mock(StatusBarNotificationActivityStarterLogger.class),
-                        mOnUserInteractionCallback)
-                        .setStatusBar(mStatusBar)
-                        .setNotificationPresenter(mock(NotificationPresenter.class))
-                        .setNotificationPanelViewController(
-                                mock(NotificationPanelViewController.class))
-                        .setActivityLaunchAnimator(mActivityLaunchAnimator)
-                        .setNotificationAnimatorControllerProvider(notificationAnimationProvider)
-                        .build();
+                        mOnUserInteractionCallback,
+                        mCentralSurfaces,
+                        mock(NotificationPresenter.class),
+                        mock(NotificationPanelViewController.class),
+                        mActivityLaunchAnimator,
+                        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))
@@ -269,7 +268,7 @@
         sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
 
         when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mStatusBar.isOccluded()).thenReturn(true);
+        when(mCentralSurfaces.isOccluded()).thenReturn(true);
 
         // When
         mNotificationActivityStarter.onNotificationClicked(sbn, mNotificationRow);
@@ -328,7 +327,7 @@
         // Given
         sbn.getNotification().contentIntent = null;
         when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mStatusBar.isOccluded()).thenReturn(true);
+        when(mCentralSurfaces.isOccluded()).thenReturn(true);
 
         // When
         mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
@@ -358,7 +357,7 @@
         // Given
         sbn.getNotification().contentIntent = mContentIntent;
         when(mKeyguardStateController.isShowing()).thenReturn(true);
-        when(mStatusBar.isOccluded()).thenReturn(true);
+        when(mCentralSurfaces.isOccluded()).thenReturn(true);
 
         // When
         mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
@@ -402,6 +401,42 @@
         mNotificationActivityStarter.handleFullScreenIntent(entry);
 
         // THEN display should try wake up for the full screen intent
-        verify(mStatusBar).wakeUpForFullScreenIntent();
+        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() {
+        NotifActivityLaunchEvents.Listener listener =
+                mock(NotifActivityLaunchEvents.Listener.class);
+        mLaunchEventsEmitter.registerListener(listener);
+        mNotificationActivityStarter
+                .onNotificationClicked(mNotificationRow.getEntry().getSbn(), mNotificationRow);
+        verify(listener).onFinishLaunchNotifActivity(mNotificationRow.getEntry());
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 7d9e6b4..1a3dd3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -37,6 +37,7 @@
 import com.android.systemui.ForegroundServiceNotificationListener;
 import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -79,7 +80,7 @@
     private CommandQueue mCommandQueue;
     private FakeMetricsLogger mMetricsLogger;
     private ShadeController mShadeController = mock(ShadeController.class);
-    private StatusBar mStatusBar = mock(StatusBar.class);
+    private CentralSurfaces mCentralSurfaces = mock(CentralSurfaces.class);
     private InitController mInitController = new InitController();
 
     @Before
@@ -101,19 +102,24 @@
                 mock(NotificationStackScrollLayoutController.class);
         when(stackScrollLayoutController.getView()).thenReturn(
                 mock(NotificationStackScrollLayout.class));
-        when(stackScrollLayoutController.getNotificationListContainer()).thenReturn(
-                mock(NotificationListContainer.class));
         when(notificationShadeWindowView.getResources()).thenReturn(mContext.getResources());
 
-        mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(mContext,
-                mock(NotificationPanelViewController.class), mock(HeadsUpManagerPhone.class),
-                notificationShadeWindowView, stackScrollLayoutController,
-                mock(DozeScrimController.class), mock(ScrimController.class),
-                mock(NotificationShadeWindowController.class), mock(DynamicPrivacyController.class),
+        mStatusBarNotificationPresenter = new StatusBarNotificationPresenter(
+                mContext,
+                mock(NotificationPanelViewController.class),
+                mock(HeadsUpManagerPhone.class),
+                notificationShadeWindowView,
+                mock(ActivityStarter.class),
+                stackScrollLayoutController,
+                mock(DozeScrimController.class),
+                mock(ScrimController.class),
+                mock(NotificationShadeWindowController.class),
+                mock(DynamicPrivacyController.class),
                 mock(KeyguardStateController.class),
                 mock(KeyguardIndicationController.class),
-                mStatusBar,
-                mock(ShadeControllerImpl.class), mock(LockscreenShadeTransitionController.class),
+                mCentralSurfaces,
+                mock(ShadeControllerImpl.class),
+                mock(LockscreenShadeTransitionController.class),
                 mCommandQueue,
                 mock(NotificationViewHierarchyManager.class),
                 mock(NotificationLockscreenUserManager.class),
@@ -128,7 +134,9 @@
                 mNotificationInterruptStateProvider,
                 mock(NotificationRemoteInputManager.class),
                 mock(ConfigurationController.class),
-                mock(NotifPipelineFlags.class));
+                mock(NotifPipelineFlags.class),
+                mock(NotificationRemoteInputManager.Callback.class),
+                mock(NotificationListContainer.class));
         mInitController.executePostInitTasks();
         ArgumentCaptor<NotificationInterruptSuppressor> suppressorCaptor =
                 ArgumentCaptor.forClass(NotificationInterruptSuppressor.class);
@@ -195,9 +203,9 @@
                 .setTag("a")
                 .setNotification(n)
                 .build();
-        when(mStatusBar.areNotificationAlertsDisabled()).thenReturn(true);
+        when(mCentralSurfaces.areNotificationAlertsDisabled()).thenReturn(true);
 
-        assertTrue("StatusBar alerts disabled shouldn't allow interruptions",
+        assertTrue("CentralSurfaces alerts disabled shouldn't allow interruptions",
                 mInterruptSuppressor.suppressInterruptions(entry));
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
index 71b32c0..050563a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
@@ -61,7 +61,7 @@
     @Mock
     private lateinit var globalSettings: GlobalSettings
     @Mock
-    private lateinit var statusBar: StatusBar
+    private lateinit var mCentralSurfaces: CentralSurfaces
     @Mock
     private lateinit var notificationPanelViewController: NotificationPanelViewController
     @Mock
@@ -93,8 +93,8 @@
                 powerManager,
                 handler = handler
         )
-        controller.initialize(statusBar, lightRevealScrim)
-        `when`(statusBar.notificationPanelViewController).thenReturn(
+        controller.initialize(mCentralSurfaces, lightRevealScrim)
+        `when`(mCentralSurfaces.notificationPanelViewController).thenReturn(
             notificationPanelViewController)
 
         // Screen off does not run if the panel is expanded, so we should say it's collapsed to test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 5861617..5095094 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -17,6 +17,8 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.atLeast;
@@ -27,6 +29,7 @@
 import android.app.StatusBarManager;
 import android.content.Context;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.View;
@@ -56,6 +59,9 @@
 import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
 import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.settings.SecureSettings;
+import com.android.systemui.util.time.FakeSystemClock;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -82,6 +88,8 @@
     private final CommandQueue mCommandQueue = mock(CommandQueue.class);
     private OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
     private OperatorNameViewController mOperatorNameViewController;
+    private SecureSettings mSecureSettings;
+    private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
 
     @Mock
     private StatusBarFragmentComponent.Factory mStatusBarFragmentComponentFactory;
@@ -298,6 +306,40 @@
         assertEquals(mStatusBarFragmentComponent, fragment.getStatusBarFragmentComponent());
     }
 
+    @Test
+    public void testBlockedIcons_obeysSettingForVibrateIcon_settingOff() {
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+        String str = mContext.getString(com.android.internal.R.string.status_bar_volume);
+
+        // GIVEN the setting is off
+        when(mSecureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0))
+                .thenReturn(0);
+
+        // WHEN CollapsedStatusBarFragment builds the blocklist
+        fragment.updateBlockedIcons();
+
+        // THEN status_bar_volume SHOULD be present in the list
+        boolean contains = fragment.getBlockedIcons().contains(str);
+        assertTrue(contains);
+    }
+
+    @Test
+    public void testBlockedIcons_obeysSettingForVibrateIcon_settingOn() {
+        CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+        String str = mContext.getString(com.android.internal.R.string.status_bar_volume);
+
+        // GIVEN the setting is ON
+        when(mSecureSettings.getInt(Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON, 0))
+                .thenReturn(1);
+
+        // WHEN CollapsedStatusBarFragment builds the blocklist
+        fragment.updateBlockedIcons();
+
+        // THEN status_bar_volume SHOULD NOT be present in the list
+        boolean contains = fragment.getBlockedIcons().contains(str);
+        assertFalse(contains);
+    }
+
     @Override
     protected Fragment instantiate(Context context, String className, Bundle arguments) {
         MockitoAnnotations.initMocks(this);
@@ -313,6 +355,7 @@
         mOperatorNameViewControllerFactory = mock(OperatorNameViewController.Factory.class);
         when(mOperatorNameViewControllerFactory.create(any()))
                 .thenReturn(mOperatorNameViewController);
+        mSecureSettings = mock(SecureSettings.class);
 
         setUpNotificationIconAreaController();
         return new CollapsedStatusBarFragment(
@@ -334,7 +377,9 @@
                         new LogBuffer("TEST", 1, 1, mock(LogcatEchoTracker.class)),
                         new DisableFlagsLogger()
                         ),
-                mOperatorNameViewControllerFactory);
+                mOperatorNameViewControllerFactory,
+                mSecureSettings,
+                mExecutor);
     }
 
     private void setUpDaggerComponent() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index 0920cac..d30222f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -22,7 +22,6 @@
 import android.app.Notification
 import android.app.PendingIntent
 import android.app.Person
-import android.content.Intent
 import android.service.notification.NotificationListenerService.REASON_USER_STOPPED
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
@@ -105,6 +104,7 @@
         val notificationCollection = mock(CommonNotifCollection::class.java)
 
         controller = OngoingCallController(
+                context,
                 notificationCollection,
                 mockOngoingCallFlags,
                 clock,
@@ -204,17 +204,48 @@
 
     /** Regression test for b/194731244. */
     @Test
-    fun onEntryUpdated_calledManyTimes_uidObserverUnregisteredManyTimes() {
-        val numCalls = 4
-
-        for (i in 0 until numCalls) {
+    fun onEntryUpdated_calledManyTimes_uidObserverOnlyRegisteredOnce() {
+        for (i in 0 until 4) {
             // Re-create the notification each time so that it's considered a different object and
-            // observers will get re-registered (and hopefully unregistered).
+            // will re-trigger the whole flow.
             notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
         }
 
-        // There should be 1 observer still registered, so we should unregister n-1 times.
-        verify(mockIActivityManager, times(numCalls - 1)).unregisterUidObserver(any())
+        verify(mockIActivityManager, times(1))
+            .registerUidObserver(any(), any(), any(), any())
+    }
+
+    /** Regression test for b/216248574. */
+    @Test
+    fun entryUpdated_getUidProcessStateThrowsException_noCrash() {
+        `when`(mockIActivityManager.getUidProcessState(eq(CALL_UID), nullable(String::class.java)))
+                .thenThrow(SecurityException())
+
+        // No assert required, just check no crash
+        notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
+    }
+
+    /** Regression test for b/216248574. */
+    @Test
+    fun entryUpdated_registerUidObserverThrowsException_noCrash() {
+        `when`(mockIActivityManager.registerUidObserver(
+            any(), any(), any(), nullable(String::class.java)
+        )).thenThrow(SecurityException())
+
+        // No assert required, just check no crash
+        notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
+    }
+
+    /** Regression test for b/216248574. */
+    @Test
+    fun entryUpdated_packageNameProvidedToActivityManager() {
+        notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry())
+
+        val packageNameCaptor = ArgumentCaptor.forClass(String::class.java)
+        verify(mockIActivityManager).registerUidObserver(
+            any(), any(), any(), packageNameCaptor.capture()
+        )
+        assertThat(packageNameCaptor.value).isNotNull()
     }
 
     /**
@@ -428,6 +459,19 @@
                 .isEqualTo(OngoingCallLogger.OngoingCallEvents.ONGOING_CALL_CLICKED.id)
     }
 
+    /** Regression test for b/212467440. */
+    @Test
+    fun chipClicked_activityStarterTriggeredWithUnmodifiedIntent() {
+        val notifEntry = createOngoingCallNotifEntry()
+        val pendingIntent = notifEntry.sbn.notification.contentIntent
+        notifCollectionListener.onEntryUpdated(notifEntry)
+
+        chipView.performClick()
+
+        // Ensure that the sysui didn't modify the notification's intent -- see b/212467440.
+        verify(mockActivityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent), any())
+    }
+
     @Test
     fun notifyChipVisibilityChanged_visibleEventLogged() {
         controller.notifyChipVisibilityChanged(true)
@@ -569,7 +613,6 @@
             notificationEntryBuilder.modifyNotification(context).setContentIntent(null)
         } else {
             val contentIntent = mock(PendingIntent::class.java)
-            `when`(contentIntent.intent).thenReturn(mock(Intent::class.java))
             notificationEntryBuilder.modifyNotification(context).setContentIntent(contentIntent)
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
new file mode 100644
index 0000000..3a5d9ee
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FakeConfigurationController.kt
@@ -0,0 +1,31 @@
+package com.android.systemui.statusbar.policy
+
+import android.content.res.Configuration
+
+/** Fake implementation of [ConfigurationController] for tests. */
+class FakeConfigurationController : ConfigurationController {
+
+    private var listener: ConfigurationController.ConfigurationListener? = null
+
+    override fun addCallback(listener: ConfigurationController.ConfigurationListener) {
+        this.listener = listener
+    }
+
+    override fun removeCallback(listener: ConfigurationController.ConfigurationListener) {
+        this.listener = null
+    }
+
+    override fun onConfigurationChanged(newConfiguration: Configuration?) {
+        listener?.onConfigChanged(newConfiguration)
+    }
+
+    override fun notifyThemeChanged() {
+        listener?.onThemeChanged()
+    }
+
+    fun notifyConfigurationChanged() {
+        onConfigurationChanged(newConfiguration = null)
+    }
+
+    override fun isLayoutRtl(): Boolean = false
+}
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/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
index 9f9cb40..12cfb32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
@@ -14,9 +14,12 @@
 
 package com.android.systemui.statusbar.policy;
 
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -24,6 +27,7 @@
 
 import android.app.AppOpsManager;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.location.LocationManager;
 import android.os.Handler;
@@ -67,6 +71,7 @@
     private DeviceConfigProxy mDeviceConfigProxy;
     private UiEventLoggerFake mUiEventLogger;
 
+    @Mock private PackageManager mPackageManager;
     @Mock private AppOpsController mAppOpsController;
     @Mock private UserTracker mUserTracker;
     @Mock private SecureSettings mSecureSettings;
@@ -82,6 +87,7 @@
         mUiEventLogger = new UiEventLoggerFake();
 
         mTestableLooper = TestableLooper.get(this);
+
         mLocationController = new LocationControllerImpl(mContext,
                 mAppOpsController,
                 mDeviceConfigProxy,
@@ -90,7 +96,7 @@
                 mock(BroadcastDispatcher.class),
                 mock(BootCompleteCache.class),
                 mUserTracker,
-                mContext.getPackageManager(),
+                mPackageManager,
                 mUiEventLogger,
                 mSecureSettings);
 
@@ -178,6 +184,8 @@
 
     @Test
     public void testCallbackNotified_additionalOps() {
+        // Return -1 for non system apps
+        when(mPackageManager.getPermissionFlags(any(), any(), any())).thenReturn(-1);
         LocationChangeCallback callback = mock(LocationChangeCallback.class);
         mLocationController.addCallback(callback);
         mDeviceConfigProxy.setProperty(
@@ -190,10 +198,10 @@
         when(mAppOpsController.getActiveAppOps())
                 .thenReturn(ImmutableList.of(
                         new AppOpItem(AppOpsManager.OP_FINE_LOCATION, 0,
-                                "com.google.android.googlequicksearchbox",
+                                "com.third.party.app",
                                 System.currentTimeMillis())));
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.googlequicksearchbox", true);
+                "ccom.third.party.app", true);
 
         mTestableLooper.processAllMessages();
 
@@ -201,14 +209,14 @@
 
         when(mAppOpsController.getActiveAppOps()).thenReturn(ImmutableList.of());
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.googlequicksearchbox", false);
+                "com.third.party.app", false);
         mTestableLooper.processAllMessages();
 
         verify(callback, times(1)).onLocationActiveChanged(false);
 
         when(mAppOpsController.getActiveAppOps()).thenReturn(ImmutableList.of());
         mLocationController.onActiveStateChanged(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, 0,
-                "com.google.android.googlequicksearchbox", true);
+                "com.third.party.app", true);
         mTestableLooper.processAllMessages();
         verify(callback, times(1)).onLocationActiveChanged(true);
     }
@@ -227,10 +235,10 @@
         when(mAppOpsController.getActiveAppOps())
                 .thenReturn(ImmutableList.of(
                         new AppOpItem(AppOpsManager.OP_FINE_LOCATION, 0,
-                                "com.google.android.gms",
+                                "com.system.app",
                                 System.currentTimeMillis())));
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.gms", true);
+                "com.system.app", true);
 
         mTestableLooper.processAllMessages();
 
@@ -258,10 +266,10 @@
 
         when(mAppOpsController.getActiveAppOps())
                 .thenReturn(ImmutableList.of(
-                        new AppOpItem(AppOpsManager.OP_FINE_LOCATION, 0, "com.google.android.gms",
+                        new AppOpItem(AppOpsManager.OP_FINE_LOCATION, 0, "com.system.app",
                                 System.currentTimeMillis())));
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.gms", true);
+                "com.system.app", true);
 
         mTestableLooper.processAllMessages();
 
@@ -269,7 +277,7 @@
 
         when(mAppOpsController.getActiveAppOps()).thenReturn(ImmutableList.of());
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.gms", false);
+                "com.system.app", false);
         mTestableLooper.processAllMessages();
 
         verify(callback, times(1)).onLocationActiveChanged(false);
@@ -277,7 +285,7 @@
         when(mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0))
                 .thenReturn(0);
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.gms", true);
+                "com.system.app", true);
 
         mTestableLooper.processAllMessages();
 
@@ -287,6 +295,11 @@
 
     @Test
     public void testCallbackNotified_verifyMetrics() {
+        // Return -1 for non system apps and 0 for system apps.
+        when(mPackageManager.getPermissionFlags(any(),
+                eq("com.system.app"), any())).thenReturn(0);
+        when(mPackageManager.getPermissionFlags(any(),
+                eq("com.third.party.app"), any())).thenReturn(-1);
         LocationChangeCallback callback = mock(LocationChangeCallback.class);
         mLocationController.addCallback(callback);
         mDeviceConfigProxy.setProperty(
@@ -298,16 +311,16 @@
 
         when(mAppOpsController.getActiveAppOps())
                 .thenReturn(ImmutableList.of(
-                        new AppOpItem(AppOpsManager.OP_FINE_LOCATION, 0, "com.google.android.gms",
+                        new AppOpItem(AppOpsManager.OP_FINE_LOCATION, 0, "com.system.app",
                                 System.currentTimeMillis()),
                         new AppOpItem(AppOpsManager.OP_COARSE_LOCATION, 0,
-                                "com.google.android.googlequicksearchbox",
+                                "com.third.party.app",
                                 System.currentTimeMillis()),
                         new AppOpItem(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, 0,
-                                "com.google.android.apps.maps",
+                                "com.another.developer.app",
                                 System.currentTimeMillis())));
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.gms", true);
+                "com.system.app", true);
 
         mTestableLooper.processAllMessages();
 
@@ -328,7 +341,7 @@
 
         when(mAppOpsController.getActiveAppOps()).thenReturn(ImmutableList.of());
         mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
-                "com.google.android.gms", false);
+                "com.system.app", false);
         mTestableLooper.processAllMessages();
 
         verify(callback, times(1)).onLocationActiveChanged(false);
@@ -354,4 +367,4 @@
         // No new callbacks
         verify(callback).onLocationSettingsChanged(anyBoolean());
     }
-}
+}
\ No newline at end of file
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 07e0279..91c347f 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
@@ -48,7 +48,6 @@
 import com.android.systemui.qs.user.UserSwitchDialogController
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.phone.NotificationShadeWindowView
-import com.android.systemui.statusbar.phone.ShadeController
 import com.android.systemui.telephony.TelephonyListenerManager
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.settings.SecureSettings
@@ -65,7 +64,6 @@
 import org.mockito.Mock
 import org.mockito.Mockito.`when`
 import org.mockito.Mockito.any
-import org.mockito.Mockito.anyString
 import org.mockito.Mockito.doNothing
 import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
@@ -95,7 +93,6 @@
     @Mock private lateinit var notificationShadeWindowView: NotificationShadeWindowView
     @Mock private lateinit var threadedRenderer: ThreadedRenderer
     @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
-    @Mock private lateinit var shadeController: ShadeController
     private lateinit var testableLooper: TestableLooper
     private lateinit var bgExecutor: FakeExecutor
     private lateinit var uiExecutor: FakeExecutor
@@ -171,7 +168,6 @@
                 interactionJankMonitor,
                 latencyTracker,
                 dumpManager,
-                { shadeController },
                 dialogLaunchAnimator)
         userSwitcherController.init(notificationShadeWindowView)
     }
@@ -210,7 +206,7 @@
         `when`(userTracker.userId).thenReturn(ownerId)
         `when`(userTracker.userInfo).thenReturn(ownerInfo)
 
-        `when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)
+        `when`(userManager.createGuest(any())).thenReturn(guestInfo)
 
         userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, null)
         testableLooper.processAllMessages()
@@ -235,7 +231,7 @@
         `when`(userTracker.userId).thenReturn(ownerId)
         `when`(userTracker.userInfo).thenReturn(ownerInfo)
 
-        `when`(userManager.createGuest(any(), anyString())).thenReturn(guestInfo)
+        `when`(userManager.createGuest(any())).thenReturn(guestInfo)
 
         userSwitcherController.onUserListItemClicked(emptyGuestUserRecord, dialogShower)
         testableLooper.processAllMessages()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
new file mode 100644
index 0000000..14b9bfb
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/touch/TouchInsetManagerTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.touch;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.testing.AndroidTestingRunner;
+import android.view.View;
+import android.view.ViewRootImpl;
+
+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 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;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class TouchInsetManagerTest extends SysuiTestCase {
+    @Mock
+    private View mRootView;
+
+    @Mock
+    private ViewRootImpl mRootViewImpl;
+
+    private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        when(mRootView.getViewRootImpl()).thenReturn(mRootViewImpl);
+    }
+
+    @Test
+    public void testRootViewOnAttachedHandling() {
+        // Create inset manager
+        final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
+                mRootView);
+
+        final ArgumentCaptor<View.OnAttachStateChangeListener> listener =
+                ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+
+        // Ensure manager has registered to listen to attached state of root view.
+        verify(mRootView).addOnAttachStateChangeListener(listener.capture());
+
+        // Trigger attachment and verify touchable region is set.
+        listener.getValue().onViewAttachedToWindow(mRootView);
+        verify(mRootViewImpl).setTouchableRegion(any());
+    }
+
+    @Test
+    public void testInsetRegionPropagation() {
+        // Create inset manager
+        final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
+                mRootView);
+
+        // Create session
+        final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
+
+        // Add a view to the session.
+        final Rect rect = new Rect(0, 0, 2, 2);
+
+        session.addViewToTracking(createView(rect));
+        mFakeExecutor.runAllReady();
+
+        // Check to see if view was properly accounted for.
+        final Region expectedRegion = Region.obtain();
+        expectedRegion.op(rect, Region.Op.UNION);
+        verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+    }
+
+    @Test
+    public void testMultipleRegions() {
+        // Create inset manager
+        final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
+                mRootView);
+
+        // Create session
+        final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
+
+        // Add a view to the session.
+        final Rect firstBounds = new Rect(0, 0, 2, 2);
+        session.addViewToTracking(createView(firstBounds));
+
+        mFakeExecutor.runAllReady();
+        clearInvocations(mRootViewImpl);
+
+        // Create second session
+        final TouchInsetManager.TouchInsetSession secondSession = insetManager.createSession();
+
+        // Add a view to the second session.
+        final Rect secondBounds = new Rect(4, 4, 8, 10);
+        secondSession.addViewToTracking(createView(secondBounds));
+
+        mFakeExecutor.runAllReady();
+
+        // Check to see if all views and sessions was properly accounted for.
+        {
+            final Region expectedRegion = Region.obtain();
+            expectedRegion.op(firstBounds, Region.Op.UNION);
+            expectedRegion.op(secondBounds, Region.Op.UNION);
+            verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+        }
+
+
+        clearInvocations(mRootViewImpl);
+
+        // clear first session, ensure second session is still reflected.
+        session.clear();
+        mFakeExecutor.runAllReady();
+        {
+            final Region expectedRegion = Region.obtain();
+            expectedRegion.op(firstBounds, Region.Op.UNION);
+            verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+        }
+    }
+
+    @Test
+    public void testMultipleViews() {
+        // Create inset manager
+        final TouchInsetManager insetManager = new TouchInsetManager(mFakeExecutor,
+                mRootView);
+
+        // Create session
+        final TouchInsetManager.TouchInsetSession session = insetManager.createSession();
+
+        // Add a view to the session.
+        final Rect firstViewBounds = new Rect(0, 0, 2, 2);
+        session.addViewToTracking(createView(firstViewBounds));
+
+        // only capture second invocation.
+        mFakeExecutor.runAllReady();
+        clearInvocations(mRootViewImpl);
+
+        // Add a second view to the session
+        final Rect secondViewBounds = new Rect(4, 4, 9, 10);
+        final View secondView = createView(secondViewBounds);
+        session.addViewToTracking(secondView);
+
+        mFakeExecutor.runAllReady();
+
+        // Check to see if all views and sessions was properly accounted for.
+        {
+            final Region expectedRegion = Region.obtain();
+            expectedRegion.op(firstViewBounds, Region.Op.UNION);
+            expectedRegion.op(secondViewBounds, Region.Op.UNION);
+            verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+        }
+
+        // Remove second view.
+        session.removeViewFromTracking(secondView);
+
+        clearInvocations(mRootViewImpl);
+        mFakeExecutor.runAllReady();
+
+        // Ensure first view still reflected in touch region.
+        {
+            final Region expectedRegion = Region.obtain();
+            expectedRegion.op(firstViewBounds, Region.Op.UNION);
+            verify(mRootViewImpl).setTouchableRegion(eq(expectedRegion));
+        }
+    }
+
+    private View createView(Rect bounds) {
+        final Rect rect = new Rect(bounds);
+        final View view = Mockito.mock(View.class);
+        doAnswer(invocation -> {
+            ((Rect) invocation.getArgument(0)).set(rect);
+            return null;
+        }).when(view).getBoundsOnScreen(any());
+
+        return view;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
new file mode 100644
index 0000000..d4be881
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.user
+
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.statusbar.phone.ShadeController
+import com.android.systemui.statusbar.policy.UserSwitcherController
+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.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+class UserSwitcherActivityTest : SysuiTestCase() {
+    @Mock
+    private lateinit var activity: UserSwitcherActivity
+    @Mock
+    private lateinit var userSwitcherController: UserSwitcherController
+    @Mock
+    private lateinit var broadcastDispatcher: BroadcastDispatcher
+    @Mock
+    private lateinit var layoutInflater: LayoutInflater
+    @Mock
+    private lateinit var falsingManager: FalsingManager
+    @Mock
+    private lateinit var userManager: UserManager
+    @Mock
+    private lateinit var shadeController: ShadeController
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        activity = UserSwitcherActivity(
+            userSwitcherController,
+            broadcastDispatcher,
+            layoutInflater,
+            falsingManager,
+            userManager,
+            shadeController
+        )
+    }
+
+    @Test
+    fun testMaxColumns() {
+        assertThat(activity.getMaxColumns(3)).isEqualTo(4)
+        assertThat(activity.getMaxColumns(4)).isEqualTo(4)
+        assertThat(activity.getMaxColumns(5)).isEqualTo(3)
+        assertThat(activity.getMaxColumns(6)).isEqualTo(3)
+        assertThat(activity.getMaxColumns(7)).isEqualTo(4)
+        assertThat(activity.getMaxColumns(9)).isEqualTo(5)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/view/ViewUtilTest.kt b/packages/SystemUI/tests/src/com/android/systemui/util/view/ViewUtilTest.kt
new file mode 100644
index 0000000..dead159
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/view/ViewUtilTest.kt
@@ -0,0 +1,72 @@
+package com.android.systemui.util.view
+
+import android.view.View
+import android.widget.TextView
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.`when`
+
+@SmallTest
+class ViewUtilTest : SysuiTestCase() {
+    private val viewUtil = ViewUtil()
+    private lateinit var view: View
+
+    @Before
+    fun setUp() {
+        view = TextView(context)
+        view.setLeftTopRightBottom(VIEW_LEFT, VIEW_TOP, VIEW_RIGHT, VIEW_BOTTOM)
+
+        view = spy(view)
+        val location = IntArray(2)
+        location[0] = VIEW_LEFT
+        location[1] = VIEW_TOP
+        `when`(view.locationOnScreen).thenReturn(location)
+    }
+
+    @Test
+    fun touchIsWithinView_inBounds_returnsTrue() {
+        assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT + 1f, VIEW_TOP + 1f)).isTrue()
+    }
+
+    @Test
+    fun touchIsWithinView_onTopLeftCorner_returnsTrue() {
+        assertThat(viewUtil.touchIsWithinView(
+            view, VIEW_LEFT.toFloat(), VIEW_TOP.toFloat())
+        ).isTrue()
+    }
+
+    @Test
+    fun touchIsWithinView_onBottomRightCorner_returnsTrue() {
+        assertThat(viewUtil.touchIsWithinView(view, VIEW_RIGHT.toFloat(), VIEW_BOTTOM.toFloat()))
+            .isTrue()
+    }
+
+    @Test
+    fun touchIsWithinView_xTooSmall_returnsFalse() {
+        assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT - 1f, VIEW_TOP + 1f)).isFalse()
+    }
+
+    @Test
+    fun touchIsWithinView_xTooLarge_returnsFalse() {
+        assertThat(viewUtil.touchIsWithinView(view, VIEW_RIGHT + 1f, VIEW_TOP + 1f)).isFalse()
+    }
+
+    @Test
+    fun touchIsWithinView_yTooSmall_returnsFalse() {
+        assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT + 1f, VIEW_TOP - 1f)).isFalse()
+    }
+
+    @Test
+    fun touchIsWithinView_yTooLarge_returnsFalse() {
+        assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT + 1f, VIEW_BOTTOM + 1f)).isFalse()
+    }
+}
+
+private const val VIEW_LEFT = 30
+private const val VIEW_RIGHT = 100
+private const val VIEW_TOP = 40
+private const val VIEW_BOTTOM = 100
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
index 8ad6271..2be67ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
@@ -43,6 +43,10 @@
     }
 
     @Override
+    public void refreshIconGroup(IconManager iconManager) {
+    }
+
+    @Override
     public void setExternalIcon(String slot) {
 
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
index b380553..ec619bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogControllerImplTest.java
@@ -36,6 +36,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.CaptioningManager;
 
 import androidx.test.filters.SmallTest;
 
@@ -88,6 +89,8 @@
     private PackageManager mPackageManager;
     @Mock
     private WakefulnessLifecycle mWakefullnessLifcycle;
+    @Mock
+    private CaptioningManager mCaptioningManager;
 
 
     @Before
@@ -109,7 +112,7 @@
         mVolumeController = new TestableVolumeDialogControllerImpl(mContext,
                 mBroadcastDispatcher, mRingerModeTracker, mThreadFactory, mAudioManager,
                 mNotificationManager, mVibrator, mIAudioService, mAccessibilityManager,
-                mPackageManager, mWakefullnessLifcycle, mCallback);
+                mPackageManager, mWakefullnessLifcycle, mCaptioningManager, mCallback);
         mVolumeController.setEnableDialogs(true, true);
     }
 
@@ -184,10 +187,11 @@
                 AccessibilityManager accessibilityManager,
                 PackageManager packageManager,
                 WakefulnessLifecycle wakefulnessLifecycle,
+                CaptioningManager captioningManager,
                 C callback) {
             super(context, broadcastDispatcher, ringerModeTracker, theadFactory, audioManager,
                     notificationManager, optionalVibrator, iAudioService, accessibilityManager,
-                    packageManager, wakefulnessLifecycle);
+                    packageManager, wakefulnessLifecycle, captioningManager);
             mCallbacks = callback;
 
             ArgumentCaptor<WakefulnessLifecycle.Observer> observerCaptor =
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 4bc4e6e..82880fe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -50,8 +50,10 @@
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
@@ -197,6 +199,11 @@
     private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
     @Captor
     private ArgumentCaptor<List<Bubble>> mBubbleListCaptor;
+    @Captor
+    private ArgumentCaptor<IntentFilter> mFilterArgumentCaptor;
+    @Captor
+    private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
+
 
     private BubblesManager mBubblesManager;
     // TODO(178618782): Move tests on the controller directly to the shell
@@ -1214,7 +1221,7 @@
         final Context userContext = setUpContextWithPackageManager(workPkg,
                 mock(ApplicationInfo.class));
 
-        // If things are working correctly, StatusBar.getPackageManagerForUser will call this
+        // If things are working correctly, CentralSurfaces.getPackageManagerForUser will call this
         when(context.createPackageContextAsUser(eq(workPkg), anyInt(), eq(workUser)))
                 .thenReturn(userContext);
 
@@ -1357,6 +1364,66 @@
         assertStackCollapsed();
     }
 
+    @Test
+    public void testRegisterUnregisterBroadcastListener() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+        assertThat(mFilterArgumentCaptor.getValue().getAction(0)).isEqualTo(
+                Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        assertThat(mFilterArgumentCaptor.getValue().getAction(1)).isEqualTo(
+                Intent.ACTION_SCREEN_OFF);
+
+        mBubbleData.dismissBubbleWithKey(mBubbleEntry.getKey(), REASON_APP_CANCEL);
+        // TODO: not certain why this isn't called normally when tests are run, perhaps because
+        // it's after an animation in BSV. This calls BubbleController#removeFromWindowManagerMaybe
+        mBubbleController.onAllBubblesAnimatedOut();
+
+        verify(mContext).unregisterReceiver(eq(mBroadcastReceiverArgumentCaptor.getValue()));
+    }
+
+    @Test
+    public void testBroadcastReceiverCloseDialogs_notGestureNav() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleData.setExpanded(true);
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+        Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+
+        assertStackExpanded();
+    }
+
+    @Test
+    public void testBroadcastReceiverCloseDialogs_reasonGestureNav() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleData.setExpanded(true);
+
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+        Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        i.putExtra("reason", "gestureNav");
+        mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+        assertStackCollapsed();
+    }
+
+    @Test
+    public void testBroadcastReceiver_screenOff() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleData.setExpanded(true);
+
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+
+        Intent i = new Intent(Intent.ACTION_SCREEN_OFF);
+        mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+        assertStackCollapsed();
+    }
+
     /** Creates a bubble using the userId and package. */
     private Bubble createBubble(int userId, String pkg) {
         final UserHandle userHandle = new UserHandle(userId);
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 75d8453..cc848bc3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -46,6 +46,9 @@
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.LauncherApps;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.os.Handler;
@@ -179,6 +182,10 @@
     private ArgumentCaptor<NotifCollectionListener> mNotifListenerCaptor;
     @Captor
     private ArgumentCaptor<List<Bubble>> mBubbleListCaptor;
+    @Captor
+    private ArgumentCaptor<IntentFilter> mFilterArgumentCaptor;
+    @Captor
+    private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
 
     private BubblesManager mBubblesManager;
     private TestableBubbleController mBubbleController;
@@ -1176,6 +1183,67 @@
         assertStackCollapsed();
     }
 
+
+    @Test
+    public void testRegisterUnregisterBroadcastListener() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+        assertThat(mFilterArgumentCaptor.getValue().getAction(0)).isEqualTo(
+                Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        assertThat(mFilterArgumentCaptor.getValue().getAction(1)).isEqualTo(
+                Intent.ACTION_SCREEN_OFF);
+
+        mBubbleData.dismissBubbleWithKey(mBubbleEntry.getKey(), REASON_APP_CANCEL);
+        // TODO: not certain why this isn't called normally when tests are run, perhaps because
+        // it's after an animation in BSV. This calls BubbleController#removeFromWindowManagerMaybe
+        mBubbleController.onAllBubblesAnimatedOut();
+
+        verify(mContext).unregisterReceiver(eq(mBroadcastReceiverArgumentCaptor.getValue()));
+    }
+
+    @Test
+    public void testBroadcastReceiverCloseDialogs_notGestureNav() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleData.setExpanded(true);
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+        Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+
+        assertStackExpanded();
+    }
+
+    @Test
+    public void testBroadcastReceiverCloseDialogs_reasonGestureNav() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleData.setExpanded(true);
+
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+        Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        i.putExtra("reason", "gestureNav");
+        mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+        assertStackCollapsed();
+    }
+
+    @Test
+    public void testBroadcastReceiver_screenOff() {
+        spyOn(mContext);
+        mBubbleController.updateBubble(mBubbleEntry);
+        mBubbleData.setExpanded(true);
+
+        verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
+                mFilterArgumentCaptor.capture());
+
+        Intent i = new Intent(Intent.ACTION_SCREEN_OFF);
+        mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
+        assertStackCollapsed();
+    }
+
     /**
      * Sets the bubble metadata flags for this entry. These flags are normally set by
      * NotificationManagerService when the notification is sent, however, these tests do not
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 6593823..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;
@@ -39,7 +40,6 @@
 import com.android.wm.shell.compatui.CompatUI;
 import com.android.wm.shell.draganddrop.DragAndDrop;
 import com.android.wm.shell.hidedisplaycutout.HideDisplayCutout;
-import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
 import com.android.wm.shell.onehanded.OneHanded;
 import com.android.wm.shell.onehanded.OneHandedEventCallback;
 import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
@@ -67,12 +67,12 @@
 
     @Mock CommandQueue mCommandQueue;
     @Mock ConfigurationController mConfigurationController;
+    @Mock KeyguardStateController mKeyguardStateController;
     @Mock KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     @Mock NavigationModeController mNavigationModeController;
     @Mock ScreenLifecycle mScreenLifecycle;
     @Mock SysUiState mSysUiState;
     @Mock Pip mPip;
-    @Mock LegacySplitScreen mLegacySplitScreen;
     @Mock SplitScreen mSplitScreen;
     @Mock OneHanded mOneHanded;
     @Mock HideDisplayCutout mHideDisplayCutout;
@@ -88,13 +88,13 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mWMShell = new WMShell(mContext, Optional.of(mPip), Optional.of(mLegacySplitScreen),
+        mWMShell = new WMShell(mContext, Optional.of(mPip),
                 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
@@ -105,13 +105,6 @@
     }
 
     @Test
-    public void initLegacySplitScreen_registersCallbacks() {
-        mWMShell.initLegacySplitScreen(mLegacySplitScreen);
-
-        verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
-    }
-
-    @Test
     public void initSplitScreen_registersCallbacks() {
         mWMShell.initSplitScreen(mSplitScreen);
 
@@ -141,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 2d62f32..4082118 100644
--- a/proto/src/camera.proto
+++ b/proto/src/camera.proto
@@ -64,7 +64,7 @@
     repeated int64 histogram_counts = 13;
 
     // The dynamic range profile of the stream
-    optional int32 dynamic_range_profile = 14;
+    optional int64 dynamic_range_profile = 14;
     // The stream use case
     optional int32 stream_use_case = 15;
 }
diff --git a/services/Android.bp b/services/Android.bp
index 2e4405f..1e4ce19 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -88,7 +88,6 @@
         ":services.appwidget-sources",
         ":services.autofill-sources",
         ":services.backup-sources",
-        ":services.bluetooth-sources", // TODO(b/214988855) : Remove once apex/service-bluetooth jar is ready
         ":backuplib-sources",
         ":services.cloudsearch-sources",
         ":services.companion-sources",
@@ -106,7 +105,6 @@
         ":services.selectiontoolbar-sources",
         ":services.smartspace-sources",
         ":services.speech-sources",
-        ":services.startop.iorap-sources",
         ":services.systemcaptions-sources",
         ":services.translation-sources",
         ":services.texttospeech-sources",
@@ -163,7 +161,6 @@
         "services.selectiontoolbar",
         "services.smartspace",
         "services.speech",
-        "services.startop",
         "services.systemcaptions",
         "services.translation",
         "services.texttospeech",
@@ -216,7 +213,6 @@
         " --hide-annotation android.annotation.Hide" +
         " --hide InternalClasses" + // com.android.* classes are okay in this interface
         // TODO: remove the --hide options below
-        " --hide-package com.google.android.startop.iorap" +
         " --hide DeprecationMismatch" +
         " --hide HiddenTypedefConstant",
     visibility: ["//frameworks/base:__subpackages__"],
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 0e99265..0ea087d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2749,6 +2749,9 @@
     }
 
     private void updateWindowMagnificationConnectionIfNeeded(AccessibilityUserState userState) {
+        if (!mMagnificationController.supportWindowMagnification()) {
+            return;
+        }
         final boolean connect = (userState.isShortcutMagnificationEnabledLocked()
                 || userState.isDisplayMagnificationEnabledLocked())
                 && (userState.getMagnificationCapabilitiesLocked()
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 59c1461..aba32ec 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -667,6 +667,10 @@
                 return null;
             }
 
+            // Don't need to add the embedded hierarchy windows into the accessibility windows list.
+            if (mHostEmbeddedMap.size() > 0 && isEmbeddedHierarchyWindowsLocked(windowId)) {
+                return null;
+            }
             final AccessibilityWindowInfo reportedWindow = AccessibilityWindowInfo.obtain();
 
             reportedWindow.setId(windowId);
@@ -699,6 +703,21 @@
             return reportedWindow;
         }
 
+        private boolean isEmbeddedHierarchyWindowsLocked(int windowId) {
+            final IBinder leashToken = mWindowIdMap.get(windowId);
+            if (leashToken == null) {
+                return false;
+            }
+
+            for (int i = 0; i < mHostEmbeddedMap.size(); i++) {
+                if (mHostEmbeddedMap.keyAt(i).equals(leashToken)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
         private int getTypeForWindowManagerWindowType(int windowType) {
             switch (windowType) {
                 case WindowManager.LayoutParams.TYPE_APPLICATION:
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/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index a958209..fa32452 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -303,7 +303,7 @@
         public void onImeWindowVisibilityChanged(boolean shown) {
             final Message m = PooledLambda.obtainMessage(
                     FullScreenMagnificationController::notifyImeWindowVisibilityChanged,
-                    FullScreenMagnificationController.this, shown);
+                    FullScreenMagnificationController.this, mDisplayId, shown);
             mControllerCtx.getHandler().sendMessage(m);
         }
 
@@ -1215,11 +1215,12 @@
     /**
      * Notifies that the IME window visibility changed.
      *
+     * @param displayId the logical display id
      * @param shown {@code true} means the IME window shows on the screen. Otherwise it's
      *                           hidden.
      */
-    void notifyImeWindowVisibilityChanged(boolean shown) {
-        mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(shown);
+    void notifyImeWindowVisibilityChanged(int displayId, boolean shown) {
+        mMagnificationInfoChangedCallback.onImeWindowVisibilityChanged(displayId, shown);
     }
 
     /**
@@ -1609,17 +1610,19 @@
          * Called when the state of the magnification activation is changed.
          * It is for the logging data of the magnification activation state.
          *
-         * @param displayId The logical display id.
+         * @param displayId the logical display id
          * @param activated {@code true} if the magnification is activated, otherwise {@code false}.
          */
         void onFullScreenMagnificationActivationState(int displayId, boolean activated);
 
         /**
          * Called when the IME window visibility changed.
+         *
+         * @param displayId the logical display id
          * @param shown {@code true} means the IME window shows on the screen. Otherwise it's
          *                           hidden.
          */
-        void onImeWindowVisibilityChanged(boolean shown);
+        void onImeWindowVisibilityChanged(int displayId, boolean shown);
 
         /**
          * Called when the magnification spec changed.
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index 09e82c7..62ba0c8 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -17,6 +17,7 @@
 package com.android.server.accessibility.magnification;
 
 import static android.accessibilityservice.MagnificationConfig.MAGNIFICATION_MODE_WINDOW;
+import static android.content.pm.PackageManager.FEATURE_WINDOW_MAGNIFICATION;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
@@ -38,6 +39,7 @@
 import android.provider.Settings;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.view.accessibility.MagnificationAnimationCallback;
 
 import com.android.internal.accessibility.util.AccessibilityStatsLogUtils;
@@ -91,6 +93,8 @@
     private FullScreenMagnificationController mFullScreenMagnificationController;
     private WindowMagnificationManager mWindowMagnificationMgr;
     private int mMagnificationCapabilities = ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+    /** Whether the platform supports window magnification feature. */
+    private final boolean mSupportWindowMagnification;
 
     @GuardedBy("mLock")
     private int mActivatedMode = ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
@@ -99,7 +103,7 @@
     // Track the active user to reset the magnification and get the associated user settings.
     private @UserIdInt int mUserId = UserHandle.USER_SYSTEM;
     @GuardedBy("mLock")
-    private boolean mImeWindowVisible = false;
+    private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray();
     private long mWindowModeEnabledTime = 0;
     private long mFullScreenModeEnabledTime = 0;
 
@@ -129,6 +133,8 @@
         mScaleProvider = scaleProvider;
         LocalServices.getService(WindowManagerInternal.class)
                 .getAccessibilityController().setUiChangesForAccessibilityCallbacks(this);
+        mSupportWindowMagnification = context.getPackageManager().hasSystemFeature(
+                FEATURE_WINDOW_MAGNIFICATION);
     }
 
     @VisibleForTesting
@@ -185,6 +191,11 @@
         }
     }
 
+    /** Returns {@code true} if the platform supports window magnification feature. */
+    public boolean supportWindowMagnification() {
+        return mSupportWindowMagnification;
+    }
+
     /**
      * Transitions to the target Magnification mode with current center of the magnification mode
      * if it is available.
@@ -377,7 +388,7 @@
                 setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
                 mLastActivatedMode = mActivatedMode;
             }
-            logMagnificationModeWithImeOnIfNeeded();
+            logMagnificationModeWithImeOnIfNeeded(displayId);
             disableFullScreenMagnificationIfNeeded(displayId);
         } else {
             logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW,
@@ -432,7 +443,7 @@
                 setActivatedModeAndSwitchDelegate(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
                 mLastActivatedMode = mActivatedMode;
             }
-            logMagnificationModeWithImeOnIfNeeded();
+            logMagnificationModeWithImeOnIfNeeded(displayId);
             disableWindowMagnificationIfNeeded(displayId);
         } else {
             logMagnificationUsageState(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN,
@@ -454,12 +465,12 @@
     }
 
     @Override
-    public void onImeWindowVisibilityChanged(boolean shown) {
+    public void onImeWindowVisibilityChanged(int displayId, boolean shown) {
         synchronized (mLock) {
-            mImeWindowVisible = shown;
+            mIsImeVisibleArray.put(displayId, shown);
         }
-        getWindowMagnificationMgr().onImeWindowVisibilityChanged(shown);
-        logMagnificationModeWithImeOnIfNeeded();
+        getWindowMagnificationMgr().onImeWindowVisibilityChanged(displayId, shown);
+        logMagnificationModeWithImeOnIfNeeded(displayId);
     }
 
     /**
@@ -575,11 +586,12 @@
         }
     }
 
-    private void logMagnificationModeWithImeOnIfNeeded() {
+    private void logMagnificationModeWithImeOnIfNeeded(int displayId) {
         final int mode;
 
         synchronized (mLock) {
-            if (!mImeWindowVisible || mActivatedMode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) {
+            if (!mIsImeVisibleArray.get(displayId, false)
+                    || mActivatedMode == ACCESSIBILITY_MAGNIFICATION_MODE_NONE) {
                 return;
             }
             mode = mActivatedMode;
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
index 175182c..3e07b09 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationProcessor.java
@@ -396,6 +396,10 @@
 
             dumpTrackingTypingFocusEnabledState(pw, displayId, config.getMode());
         }
+        pw.append("    SupportWindowMagnification="
+                + mController.supportWindowMagnification()).println();
+        pw.append("    WindowMagnificationConnectionState="
+                + mController.getWindowMagnificationMgr().getConnectionState()).println();
     }
 
     private int getIdOfLastServiceToMagnify(int mode, int displayId) {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
index 25dcc2a..041eece 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapper.java
@@ -133,6 +133,25 @@
         return true;
     }
 
+    boolean moveWindowMagnifierToPosition(int displayId, float positionX, float positionY,
+            @Nullable MagnificationAnimationCallback callback) {
+        if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
+            mTrace.logTrace(TAG + ".moveWindowMagnifierToPosition",
+                    FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "displayId=" + displayId
+                            + ";positionX=" + positionX + ";positionY=" + positionY);
+        }
+        try {
+            mConnection.moveWindowMagnifierToPosition(displayId, positionX, positionY,
+                    transformToRemoteCallback(callback, mTrace));
+        } catch (RemoteException e) {
+            if (DBG) {
+                Slog.e(TAG, "Error calling moveWindowMagnifierToPosition()", e);
+            }
+            return false;
+        }
+        return true;
+    }
+
     boolean showMagnificationButton(int displayId, int magnificationMode) {
         if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
             mTrace.logTrace(TAG + ".showMagnificationButton",
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index 89910ea..aeb1112 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -36,8 +36,10 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.view.MotionEvent;
 import android.view.accessibility.IWindowMagnificationConnection;
 import android.view.accessibility.IWindowMagnificationConnectionCallback;
@@ -87,6 +89,30 @@
     })
     public @interface WindowPosition {}
 
+    /** Window magnification connection is connecting. */
+    private static final int CONNECTING = 0;
+    /** Window magnification connection is connected. */
+    private static final int CONNECTED = 1;
+    /** Window magnification connection is disconnecting. */
+    private static final int DISCONNECTING = 2;
+    /** Window magnification connection is disconnected. */
+    private static final int DISCONNECTED = 3;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"CONNECTION_STATE"}, value = {
+            CONNECTING,
+            CONNECTED,
+            DISCONNECTING,
+            DISCONNECTED
+    })
+    private @interface ConnectionState {
+    }
+
+    @ConnectionState
+    private int mConnectionState = DISCONNECTED;
+
+    private static final int WAIT_CONNECTION_TIMEOUT_MILLIS = 100;
+
     private final Object mLock;
     private final Context mContext;
     @VisibleForTesting
@@ -99,6 +125,7 @@
     private SparseArray<WindowMagnifier> mWindowMagnifiers = new SparseArray<>();
     // Whether the following typing focus feature for magnification is enabled.
     private boolean mMagnificationFollowTypingEnabled = true;
+    private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray();
 
     private boolean mReceiverRegistered = false;
     @VisibleForTesting
@@ -178,7 +205,7 @@
      */
     public void setConnection(@Nullable IWindowMagnificationConnection connection) {
         if (DBG) {
-            Slog.d(TAG, "setConnection :" + connection);
+            Slog.d(TAG, "setConnection :" + connection + " ,mConnectionState=" + mConnectionState);
         }
         synchronized (mLock) {
             // Reset connectionWrapper.
@@ -189,6 +216,13 @@
                 }
                 mConnectionWrapper.unlinkToDeath(mConnectionCallback);
                 mConnectionWrapper = null;
+                // The connection is still connecting so it is no need to reset the
+                // connection state to disconnected.
+                // TODO b/220086369 will reset the connection immediately when requestConnection
+                //  is called
+                if (mConnectionState != CONNECTING) {
+                    setConnectionState(DISCONNECTED);
+                }
             }
             if (connection != null) {
                 mConnectionWrapper = new WindowMagnificationConnectionWrapper(connection, mTrace);
@@ -199,9 +233,13 @@
                     mConnectionCallback = new ConnectionCallback();
                     mConnectionWrapper.linkToDeath(mConnectionCallback);
                     mConnectionWrapper.setConnectionCallback(mConnectionCallback);
+                    setConnectionState(CONNECTED);
                 } catch (RemoteException e) {
                     Slog.e(TAG, "setConnection failed", e);
                     mConnectionWrapper = null;
+                    setConnectionState(DISCONNECTED);
+                } finally {
+                    mLock.notify();
                 }
             }
         }
@@ -229,10 +267,20 @@
         if (DBG) {
             Slog.d(TAG, "requestConnection :" + connect);
         }
+        if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
+            mTrace.logTrace(TAG + ".requestWindowMagnificationConnection",
+                    FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "connect=" + connect);
+        }
         synchronized (mLock) {
-            if (connect == isConnected()) {
+            if ((connect && (mConnectionState == CONNECTED || mConnectionState == CONNECTING))
+                    || (!connect && (mConnectionState == DISCONNECTED
+                    || mConnectionState == DISCONNECTING))) {
+                Slog.w(TAG,
+                        "requestConnection duplicated request: connect=" + connect
+                                + " ,mConnectionState=" + mConnectionState);
                 return false;
             }
+
             if (connect) {
                 final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
                 if (!mReceiverRegistered) {
@@ -247,19 +295,42 @@
                 }
             }
         }
-        if (mTrace.isA11yTracingEnabledForTypes(FLAGS_WINDOW_MAGNIFICATION_CONNECTION)) {
-            mTrace.logTrace(TAG + ".requestWindowMagnificationConnection",
-                    FLAGS_WINDOW_MAGNIFICATION_CONNECTION, "connect=" + connect);
+        if (requestConnectionInternal(connect)) {
+            setConnectionState(connect ? CONNECTING : DISCONNECTING);
+            return true;
+        } else {
+            setConnectionState(DISCONNECTED);
+            return false;
         }
+    }
+
+    private boolean requestConnectionInternal(boolean connect) {
         final long identity = Binder.clearCallingIdentity();
         try {
             final StatusBarManagerInternal service = LocalServices.getService(
                     StatusBarManagerInternal.class);
-            service.requestWindowMagnificationConnection(connect);
+            if (service != null) {
+                return service.requestWindowMagnificationConnection(connect);
+            }
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
-        return true;
+        return false;
+    }
+
+    /**
+     * Returns window magnification connection state.
+     */
+    public int getConnectionState() {
+        return mConnectionState;
+    }
+
+    private void setConnectionState(@ConnectionState int state) {
+        if (DBG) {
+            Slog.d(TAG, "setConnectionState : state=" + state + " ,mConnectionState="
+                    + mConnectionState);
+        }
+        mConnectionState = state;
     }
 
     /**
@@ -314,9 +385,13 @@
         float toCenterX = (float) (left + right) / 2;
         float toCenterY = (float) (top + bottom) / 2;
 
-        if (!isPositionInSourceBounds(displayId, toCenterX, toCenterY)
-                && isTrackingTypingFocusEnabled(displayId)) {
-            enableWindowMagnification(displayId, Float.NaN, toCenterX, toCenterY);
+        synchronized (mLock) {
+            if (mIsImeVisibleArray.get(displayId, false)
+                    && !isPositionInSourceBounds(displayId, toCenterX, toCenterY)
+                    && isTrackingTypingFocusEnabled(displayId)) {
+                moveWindowMagnifierToPositionInternal(displayId, toCenterX, toCenterY,
+                        STUB_ANIMATION_CALLBACK);
+            }
         }
     }
 
@@ -357,7 +432,7 @@
      * @param displayId The logical display id.
      * @param trackingTypingFocusEnabled Enabled or disable the function of tracking typing focus.
      */
-    private void setTrackingTypingFocusEnabled(int displayId, boolean trackingTypingFocusEnabled) {
+    void setTrackingTypingFocusEnabled(int displayId, boolean trackingTypingFocusEnabled) {
         synchronized (mLock) {
             WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
             if (magnifier == null) {
@@ -384,7 +459,8 @@
      *
      * @param shown {@code true} means the IME window shows on the screen. Otherwise, it's hidden.
      */
-    void onImeWindowVisibilityChanged(boolean shown) {
+    void onImeWindowVisibilityChanged(int displayId, boolean shown) {
+        mIsImeVisibleArray.put(displayId, shown);
         if (shown) {
             enableAllTrackingTypingFocus();
         }
@@ -500,8 +576,11 @@
                     animationCallback, windowPosition, id);
         }
 
-        if (enabled && !previousEnabled) {
-            mCallback.onWindowMagnificationActivationState(displayId, true);
+        if (enabled) {
+            setTrackingTypingFocusEnabled(displayId, true);
+            if (!previousEnabled) {
+                mCallback.onWindowMagnificationActivationState(displayId, true);
+            }
         }
         return enabled;
     }
@@ -563,14 +642,13 @@
         }
     }
 
+    @GuardedBy("mLock")
     boolean isPositionInSourceBounds(int displayId, float x, float y) {
-        synchronized (mLock) {
-            WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
-            if (magnifier == null) {
-                return false;
-            }
-            return magnifier.isPositionInSourceBounds(x, y);
+        WindowMagnifier magnifier = mWindowMagnifiers.get(displayId);
+        if (magnifier == null) {
+            return false;
         }
+        return magnifier.isPositionInSourceBounds(x, y);
     }
 
     /**
@@ -829,10 +907,10 @@
         }
 
         @Override
-        public void onDrag(int displayId) {
+        public void onMove(int displayId) {
             if (mTrace.isA11yTracingEnabledForTypes(
                     FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK)) {
-                mTrace.logTrace(TAG + "ConnectionCallback.onDrag",
+                mTrace.logTrace(TAG + "ConnectionCallback.onMove",
                         FLAGS_WINDOW_MAGNIFICATION_CONNECTION_CALLBACK,
                         "displayId=" + displayId);
             }
@@ -849,6 +927,7 @@
                 mConnectionWrapper.unlinkToDeath(this);
                 mConnectionWrapper = null;
                 mConnectionCallback = null;
+                setConnectionState(DISCONNECTED);
                 resetWindowMagnifiers();
             }
         }
@@ -884,7 +963,6 @@
             mWindowMagnificationManager = windowMagnificationManager;
         }
 
-        @GuardedBy("mLock")
         boolean enableWindowMagnificationInternal(float scale, float centerX, float centerY,
                 @Nullable MagnificationAnimationCallback animationCallback,
                 @WindowPosition int windowPosition, int id) {
@@ -962,7 +1040,6 @@
             return mIdOfLastServiceToControl;
         }
 
-        @GuardedBy("mLock")
         int pointersInWindow(MotionEvent motionEvent) {
             int count = 0;
             final int pointerCount = motionEvent.getPointerCount();
@@ -1025,11 +1102,22 @@
             float centerY, float magnificationFrameOffsetRatioX,
             float magnificationFrameOffsetRatioY,
             MagnificationAnimationCallback animationCallback) {
+        // Wait for the connection with a timeout.
+        final long endMillis = SystemClock.uptimeMillis() + WAIT_CONNECTION_TIMEOUT_MILLIS;
+        while (mConnectionState == CONNECTING && (SystemClock.uptimeMillis() < endMillis)) {
+            try {
+                mLock.wait(endMillis - SystemClock.uptimeMillis());
+            } catch (InterruptedException ie) {
+                /* ignore */
+            }
+        }
         if (mConnectionWrapper == null) {
-            Slog.w(TAG, "enableWindowMagnificationInternal mConnectionWrapper is null");
+            Slog.w(TAG,
+                    "enableWindowMagnificationInternal mConnectionWrapper is null. "
+                            + "mConnectionState=" + mConnectionState);
             return false;
         }
-        return  mConnectionWrapper.enableWindowMagnification(
+        return mConnectionWrapper.enableWindowMagnification(
                 displayId, scale, centerX, centerY,
                 magnificationFrameOffsetRatioX, magnificationFrameOffsetRatioY,
                 animationCallback);
@@ -1050,8 +1138,16 @@
                 displayId, animationCallback);
     }
 
+    @GuardedBy("mLock")
     private boolean moveWindowMagnifierInternal(int displayId, float offsetX, float offsetY) {
         return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifier(
                 displayId, offsetX, offsetY);
     }
+
+    @GuardedBy("mLock")
+    private boolean moveWindowMagnifierToPositionInternal(int displayId, float positionX,
+            float positionY, MagnificationAnimationCallback animationCallback) {
+        return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifierToPosition(
+                displayId, positionX, positionY, animationCallback);
+    }
 }
diff --git a/services/api/current.txt b/services/api/current.txt
index e46c972..45c0059 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -38,12 +38,19 @@
 package com.android.server.am {
 
   public interface ActivityManagerLocal {
-    method public boolean bindSupplementalProcessService(@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, int) throws android.os.RemoteException;
     method public boolean canStartForegroundService(int, int, @NonNull String);
   }
 
 }
 
+package com.android.server.pm {
+
+  public interface PackageManagerLocal {
+  }
+
+}
+
 package com.android.server.role {
 
   public interface RoleServicePlatformHelper {
diff --git a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
index 75d9b7e..f9f5289 100644
--- a/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/DialogFillUi.java
@@ -166,7 +166,9 @@
         window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
         window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
+                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                | WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+        window.setDimAmount(0.6f);
         window.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS);
         window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
         window.setGravity(Gravity.BOTTOM | Gravity.CENTER);
@@ -216,6 +218,8 @@
 
     private void setDismissButton(View decor) {
         final TextView noButton = decor.findViewById(R.id.autofill_dialog_no);
+        // set "No thinks" by default
+        noButton.setText(R.string.autofill_save_no);
         noButton.setOnClickListener((v) -> mCallback.onCanceled());
     }
 
@@ -224,6 +228,7 @@
         // set "Continue" by default
         yesButton.setText(R.string.autofill_continue_yes);
         yesButton.setOnClickListener(listener);
+        yesButton.setVisibility(View.VISIBLE);
     }
 
     private void initialAuthenticationLayout(View decor, FillResponse response) {
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/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerService.java b/services/cloudsearch/java/com/android/server/cloudsearch/CloudSearchManagerService.java
index daead0a..b1f572d 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
@@ -111,19 +131,28 @@
                 @NonNull ICloudSearchManagerCallback callBack) {
             searchRequest.setSource(
                     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/TEST_MAPPING b/services/companion/TEST_MAPPING
index 4a37cb8..38d9372 100644
--- a/services/companion/TEST_MAPPING
+++ b/services/companion/TEST_MAPPING
@@ -7,6 +7,9 @@
       "name": "CtsCompanionDeviceManagerUiAutomationTestCases"
     },
     {
+      "name": "CtsCompanionDeviceManagerNoCompanionServicesTestCases"
+    },
+    {
       "name": "CtsOsTestCases",
       "options": [
         {
diff --git a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
index 2b7b977..bf8b18c 100644
--- a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
+++ b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
@@ -50,6 +50,7 @@
 import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.os.UserHandle;
 import android.util.PackageUtils;
 import android.util.Slog;
 
@@ -201,8 +202,10 @@
             // requests at the same time.
             // If the application already has a pending association request, that PendingIntent
             // will be cancelled.
-            pendingIntent = PendingIntent.getActivity(mContext, /*requestCode */ packageUid, intent,
-                    FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
+            pendingIntent = PendingIntent.getActivityAsUser(
+                    mContext, /*requestCode */ packageUid, intent,
+                    FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE,
+                    /* options= */ null, UserHandle.CURRENT);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/services/companion/java/com/android/server/companion/CompanionApplicationController.java b/services/companion/java/com/android/server/companion/CompanionApplicationController.java
index c39b59a..f32eebc 100644
--- a/services/companion/java/com/android/server/companion/CompanionApplicationController.java
+++ b/services/companion/java/com/android/server/companion/CompanionApplicationController.java
@@ -108,8 +108,16 @@
 
         final List<ComponentName> companionServices =
                 mCompanionServicesRegister.forPackage(userId, packageName);
-        final List<CompanionDeviceServiceConnector> serviceConnectors;
+        if (companionServices.isEmpty()) {
+            Slog.w(TAG, "Can not bind companion applications u" + userId + "/" + packageName + ": "
+                    + "eligible CompanionDeviceService not found.\n"
+                    + "A CompanionDeviceService should declare an intent-filter for "
+                    + "\"android.companion.CompanionDeviceService\" action and require "
+                    + "\"android.permission.BIND_COMPANION_DEVICE_SERVICE\" permission.");
+            return;
+        }
 
+        final List<CompanionDeviceServiceConnector> serviceConnectors;
         synchronized (mBoundCompanionApplications) {
             if (mBoundCompanionApplications.containsValueForPackage(userId, packageName)) {
                 if (DEBUG) Log.e(TAG, "u" + userId + "/" + packageName + " is ALREADY bound.");
@@ -121,12 +129,6 @@
             mBoundCompanionApplications.setValueForPackage(userId, packageName, serviceConnectors);
         }
 
-        if (serviceConnectors.isEmpty()) {
-            Slog.e(TAG, "Can't find CompanionDeviceService implementer in package: "
-                    + packageName + ". Please check if they are correctly declared.");
-            return;
-        }
-
         // The first connector in the list is always the primary connector: set a listener to it.
         serviceConnectors.get(0).setListener(this::onPrimaryServiceBindingDied);
 
@@ -144,7 +146,11 @@
             serviceConnectors = mBoundCompanionApplications.removePackage(userId, packageName);
         }
         if (serviceConnectors == null) {
-            if (DEBUG) Log.e(TAG, "u" + userId + "/" + packageName + " is NOT bound");
+            if (DEBUG) {
+                Log.e(TAG, "unbindCompanionApplication(): "
+                        + "u" + userId + "/" + packageName + " is NOT bound");
+                Log.d(TAG, "Stacktrace", new Throwable());
+            }
             return;
         }
 
@@ -190,7 +196,11 @@
         final CompanionDeviceServiceConnector primaryServiceConnector =
                 getPrimaryServiceConnector(userId, packageName);
         if (primaryServiceConnector == null) {
-            if (DEBUG) Log.e(TAG, "u" + userId + "/" + packageName + " is NOT bound.");
+            if (DEBUG) {
+                Log.e(TAG, "notify_CompanionApplicationDevice_Appeared(): "
+                        + "u" + userId + "/" + packageName + " is NOT bound.");
+                Log.d(TAG, "Stacktrace", new Throwable());
+            }
             return;
         }
 
@@ -208,7 +218,11 @@
         final CompanionDeviceServiceConnector primaryServiceConnector =
                 getPrimaryServiceConnector(userId, packageName);
         if (primaryServiceConnector == null) {
-            if (DEBUG) Log.e(TAG, "u" + userId + "/" + packageName + " is NOT bound.");
+            if (DEBUG) {
+                Log.e(TAG, "notify_CompanionApplicationDevice_Disappeared(): "
+                        + "u" + userId + "/" + packageName + " is NOT bound.");
+                Log.d(TAG, "Stacktrace", new Throwable());
+            }
             return;
         }
 
@@ -252,12 +266,6 @@
             return forUser(userId).getOrDefault(packageName, Collections.emptyList());
         }
 
-        synchronized @NonNull ComponentName primaryForPackage(
-                @UserIdInt int userId, @NonNull String packageName) {
-            // The primary service is always at the head of the list.
-            return forPackage(userId, packageName).get(0);
-        }
-
         synchronized void invalidate(@UserIdInt int userId) {
             remove(userId);
         }
diff --git a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
index 2c42c91..adc8459 100644
--- a/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
+++ b/services/companion/java/com/android/server/companion/virtual/CameraAccessController.java
@@ -33,17 +33,19 @@
 /**
  * Handles blocking access to the camera for apps running on virtual devices.
  */
-class CameraAccessController extends CameraManager.AvailabilityCallback {
+class CameraAccessController extends CameraManager.AvailabilityCallback implements AutoCloseable {
     private static final String TAG = "CameraAccessController";
 
     private final Object mLock = new Object();
 
     private final Context mContext;
-    private VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
-    CameraAccessBlockedCallback mBlockedCallback;
-    private CameraManager mCameraManager;
-    private boolean mListeningForCameraEvents;
-    private PackageManager mPackageManager;
+    private final VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
+    private final CameraAccessBlockedCallback mBlockedCallback;
+    private final CameraManager mCameraManager;
+    private final PackageManager mPackageManager;
+
+    @GuardedBy("mLock")
+    private int mObserverCount = 0;
 
     @GuardedBy("mLock")
     private ArrayMap<String, InjectionSessionData> mPackageToSessionData = new ArrayMap<>();
@@ -77,23 +79,38 @@
      */
     public void startObservingIfNeeded() {
         synchronized (mLock) {
-            if (!mListeningForCameraEvents) {
+            if (mObserverCount == 0) {
                 mCameraManager.registerAvailabilityCallback(mContext.getMainExecutor(), this);
-                mListeningForCameraEvents = true;
             }
+            mObserverCount++;
         }
     }
 
     /**
      * Stop watching for camera access.
      */
-    public void stopObserving() {
+    public void stopObservingIfNeeded() {
         synchronized (mLock) {
-            mCameraManager.unregisterAvailabilityCallback(this);
-            mListeningForCameraEvents = false;
+            mObserverCount--;
+            if (mObserverCount <= 0) {
+                close();
+            }
         }
     }
 
+
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            if (mObserverCount < 0) {
+                Slog.wtf(TAG, "Unexpected negative mObserverCount: " + mObserverCount);
+            } else if (mObserverCount > 0) {
+                Slog.w(TAG, "Unexpected close with observers remaining: " + mObserverCount);
+            }
+        }
+        mCameraManager.unregisterAvailabilityCallback(this);
+    }
+
     @Override
     public void onCameraOpened(@NonNull String cameraId, @NonNull String packageName) {
         synchronized (mLock) {
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 bc1f28d..b991ba8 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -24,6 +24,8 @@
 import android.annotation.Nullable;
 import android.app.compat.CompatChanges;
 import android.companion.virtual.VirtualDeviceManager.ActivityListener;
+import android.companion.virtual.VirtualDeviceParams;
+import android.companion.virtual.VirtualDeviceParams.ActivityPolicy;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
 import android.content.ComponentName;
@@ -77,7 +79,9 @@
     @Nullable
     private final ArraySet<ComponentName> mBlockedActivities;
     private final Object mGenericWindowPolicyControllerLock = new Object();
-    private Consumer<ActivityInfo> mActivityBlockedCallback;
+    @ActivityPolicy
+    private final int mDefaultActivityPolicy;
+    private final Consumer<ActivityInfo> mActivityBlockedCallback;
 
     @NonNull
     @GuardedBy("mGenericWindowPolicyControllerLock")
@@ -95,18 +99,30 @@
      * @param windowFlags The window flags that this controller is interested in.
      * @param systemWindowFlags The system window flags that this controller is interested in.
      * @param allowedUsers The set of users that are allowed to stream in this display.
+     * @param allowedActivities The set of activities explicitly allowed to stream on this device.
+     *   Used only if the {@code activityPolicy} is
+     *   {@link VirtualDeviceParams#ACTIVITY_POLICY_DEFAULT_BLOCKED}.
+     * @param blockedActivities The set of activities explicitly blocked from streaming on this
+     *   device. Used only if the {@code activityPolicy} is
+     *   {@link VirtualDeviceParams#ACTIVITY_POLICY_DEFAULT_ALLOWED}
+     * @param defaultActivityPolicy Whether activities are default allowed to be displayed or
+     *   blocked.
      * @param activityListener Activity listener to listen for activity changes. The display ID
      *   is not populated in this callback and is always {@link Display#INVALID_DISPLAY}.
+     * @param activityBlockedCallback Callback that is called when an activity is blocked from
+     *   launching.
      */
     public GenericWindowPolicyController(int windowFlags, int systemWindowFlags,
             @NonNull ArraySet<UserHandle> allowedUsers,
-            @Nullable Set<ComponentName> allowedActivities,
-            @Nullable Set<ComponentName> blockedActivities,
+            @NonNull Set<ComponentName> allowedActivities,
+            @NonNull Set<ComponentName> blockedActivities,
+            @ActivityPolicy int defaultActivityPolicy,
             @NonNull ActivityListener activityListener,
             @NonNull Consumer<ActivityInfo> activityBlockedCallback) {
         mAllowedUsers = allowedUsers;
-        mAllowedActivities = allowedActivities == null ? null : new ArraySet<>(allowedActivities);
-        mBlockedActivities = blockedActivities == null ? null : new ArraySet<>(blockedActivities);
+        mAllowedActivities = new ArraySet<>(allowedActivities);
+        mBlockedActivities = new ArraySet<>(blockedActivities);
+        mDefaultActivityPolicy = defaultActivityPolicy;
         mActivityBlockedCallback = activityBlockedCallback;
         setInterestedWindowFlags(windowFlags, systemWindowFlags);
         mActivityListener = activityListener;
@@ -191,11 +207,13 @@
             Slog.d(TAG, "Virtual device activity not allowed from user " + activityUser);
             return false;
         }
-        if (mBlockedActivities != null && mBlockedActivities.contains(activityComponent)) {
+        if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED
+                && mBlockedActivities.contains(activityComponent)) {
             Slog.d(TAG, "Virtual device blocking launch of " + activityComponent);
             return false;
         }
-        if (mAllowedActivities != null && !mAllowedActivities.contains(activityComponent)) {
+        if (mDefaultActivityPolicy == VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_BLOCKED
+                && !mAllowedActivities.contains(activityComponent)) {
             Slog.d(TAG, activityComponent + " is not in the allowed list.");
             return false;
         }
diff --git a/services/companion/java/com/android/server/companion/virtual/PermissionUtils.java b/services/companion/java/com/android/server/companion/virtual/PermissionUtils.java
index c397ea2..77b880f 100644
--- a/services/companion/java/com/android/server/companion/virtual/PermissionUtils.java
+++ b/services/companion/java/com/android/server/companion/virtual/PermissionUtils.java
@@ -18,6 +18,8 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.UserHandle;
 import android.util.Slog;
 
 /**
@@ -32,13 +34,15 @@
      *
      * @param context the context
      * @param callingPackage the calling application package name
-     * @param callingUid the calling application uid
-     * @return {@code true} if the package name matches the calling app uid, {@code false} otherwise
+     * @return {@code true} if the package name matches {@link Binder#getCallingUid()}, or
+     *   {@code false} otherwise
      */
-    public static boolean validatePackageName(Context context, String callingPackage,
-            int callingUid) {
+    public static boolean validateCallingPackageName(Context context, String callingPackage) {
+        final int callingUid = Binder.getCallingUid();
+        final long token = Binder.clearCallingIdentity();
         try {
-            int packageUid = context.getPackageManager().getPackageUid(callingPackage, 0);
+            int packageUid = context.getPackageManager()
+                    .getPackageUidAsUser(callingPackage, UserHandle.getUserId(callingUid));
             if (packageUid != callingUid) {
                 Slog.e(LOG_TAG, "validatePackageName: App with package name " + callingPackage
                         + " is UID " + packageUid + " but caller is " + callingUid);
@@ -48,6 +52,8 @@
             Slog.e(LOG_TAG, "validatePackageName: App with package name " + callingPackage
                     + " does not exist");
             return false;
+        } finally {
+            Binder.restoreCallingIdentity(token);
         }
         return true;
     }
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index c0a904f..b05a7db 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -140,7 +140,8 @@
             int ownerUid, InputController inputController, OnDeviceCloseListener listener,
             PendingTrampolineCallback pendingTrampolineCallback,
             IVirtualDeviceActivityListener activityListener, VirtualDeviceParams params) {
-        mContext = context;
+        UserHandle ownerUserHandle = UserHandle.getUserHandleForUid(ownerUid);
+        mContext = context.createContextAsUser(ownerUserHandle, 0);
         mAssociationInfo = associationInfo;
         mPendingTrampolineCallback = pendingTrampolineCallback;
         mActivityListener = activityListener;
@@ -505,6 +506,7 @@
                             getAllowedUserHandles(),
                             mParams.getAllowedActivities(),
                             mParams.getBlockedActivities(),
+                            mParams.getDefaultActivityPolicy(),
                             createListenerAdapter(displayId),
                             activityInfo -> onActivityBlocked(displayId, activityInfo));
             mWindowPolicyControllers.put(displayId, dwpc);
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index c7d8daa..9f252d7 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -36,6 +36,7 @@
 import android.os.Looper;
 import android.os.Parcel;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.ExceptionUtils;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -66,7 +67,12 @@
     private VirtualDeviceManagerInternal mLocalService;
     private final Handler mHandler = new Handler(Looper.getMainLooper());
     private final PendingTrampolineMap mPendingTrampolines = new PendingTrampolineMap(mHandler);
-    private final CameraAccessController mCameraAccessController;
+    /**
+     * Mapping from user IDs to CameraAccessControllers.
+     */
+    @GuardedBy("mVirtualDeviceManagerLock")
+    private final SparseArray<CameraAccessController> mCameraAccessControllers =
+            new SparseArray<>();
 
     /**
      * Mapping from CDM association IDs to virtual devices. Only one virtual device is allowed for
@@ -94,8 +100,6 @@
         super(context);
         mImpl = new VirtualDeviceManagerImpl();
         mLocalService = new LocalService();
-        mCameraAccessController = new CameraAccessController(getContext(), mLocalService,
-                this::onCameraAccessBlocked);
     }
 
     private final ActivityInterceptorCallback mActivityInterceptorCallback =
@@ -144,16 +148,19 @@
     @Override
     public void onUserStarting(@NonNull TargetUser user) {
         super.onUserStarting(user);
+        Context userContext = getContext().createContextAsUser(user.getUserHandle(), 0);
         synchronized (mVirtualDeviceManagerLock) {
-            final CompanionDeviceManager cdm = getContext()
-                    .createContextAsUser(user.getUserHandle(), 0)
-                    .getSystemService(CompanionDeviceManager.class);
+            final CompanionDeviceManager cdm =
+                    userContext.getSystemService(CompanionDeviceManager.class);
             final int userId = user.getUserIdentifier();
             mAllAssociations.put(userId, cdm.getAllAssociations());
             OnAssociationsChangedListener listener =
                     associations -> mAllAssociations.put(userId, associations);
             mOnAssociationsChangedListeners.put(userId, listener);
             cdm.addOnAssociationsChangedListener(Runnable::run, listener);
+            CameraAccessController cameraAccessController = new CameraAccessController(
+                    userContext, mLocalService, this::onCameraAccessBlocked);
+            mCameraAccessControllers.put(user.getUserIdentifier(), cameraAccessController);
         }
     }
 
@@ -171,6 +178,14 @@
                 cdm.removeOnAssociationsChangedListener(listener);
                 mOnAssociationsChangedListeners.remove(userId);
             }
+            CameraAccessController cameraAccessController = mCameraAccessControllers.get(
+                    user.getUserIdentifier());
+            if (cameraAccessController != null) {
+                cameraAccessController.close();
+                mCameraAccessControllers.remove(user.getUserIdentifier());
+            } else {
+                Slog.w(TAG, "Cannot unregister cameraAccessController for user " + user);
+            }
         }
     }
 
@@ -198,7 +213,7 @@
                     android.Manifest.permission.CREATE_VIRTUAL_DEVICE,
                     "createVirtualDevice");
             final int callingUid = getCallingUid();
-            if (!PermissionUtils.validatePackageName(getContext(), packageName, callingUid)) {
+            if (!PermissionUtils.validateCallingPackageName(getContext(), packageName)) {
                 throw new SecurityException(
                         "Package name " + packageName + " does not belong to calling uid "
                                 + callingUid);
@@ -213,6 +228,9 @@
                             "Virtual device for association ID " + associationId
                                     + " already exists");
                 }
+                final int userId = UserHandle.getUserId(callingUid);
+                final CameraAccessController cameraAccessController =
+                        mCameraAccessControllers.get(userId);
                 VirtualDeviceImpl virtualDevice = new VirtualDeviceImpl(getContext(),
                         associationInfo, token, callingUid,
                         new VirtualDeviceImpl.OnDeviceCloseListener() {
@@ -220,14 +238,21 @@
                             public void onClose(int associationId) {
                                 synchronized (mVirtualDeviceManagerLock) {
                                     mVirtualDevices.remove(associationId);
-                                    if (mVirtualDevices.size() == 0) {
-                                        mCameraAccessController.stopObserving();
+                                    if (cameraAccessController != null) {
+                                        cameraAccessController.stopObservingIfNeeded();
+                                    } else {
+                                        Slog.w(TAG, "cameraAccessController not found for user "
+                                                + userId);
                                     }
                                 }
                             }
                         },
                         this, activityListener, params);
-                mCameraAccessController.startObservingIfNeeded();
+                if (cameraAccessController != null) {
+                    cameraAccessController.startObservingIfNeeded();
+                } else {
+                    Slog.w(TAG, "cameraAccessController not found for user " + userId);
+                }
                 mVirtualDevices.put(associationInfo.getId(), virtualDevice);
                 return virtualDevice;
             }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 561009f..f1b8158 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -103,13 +103,11 @@
         ":android.hardware.biometrics.face-V2-java-source",
         ":statslog-art-java-gen",
         ":statslog-contexthub-java-gen",
-        ":services.bluetooth-sources", // TODO(b/214988855) : Remove once apex is ready
         ":services.core-sources",
         ":services.core.protologsrc",
         ":dumpstate_aidl",
         ":framework_native_aidl",
         ":gsiservice_aidl",
-        ":inputconstants_aidl",
         ":installd_aidl",
         ":storaged_aidl",
         ":vold_aidl",
@@ -134,7 +132,7 @@
         "app-compat-annotations",
         "framework-tethering.stubs.module_lib",
         "service-permission.stubs.system_server",
-        "service-supplementalprocess.stubs.system_server",
+        "service-sdksandbox.stubs.system_server",
     ],
 
     required: [
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 111bd34..2068e6d 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -45,6 +45,7 @@
 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;
@@ -68,6 +69,7 @@
  * @hide Only for use within the system server.
  */
 public abstract class PackageManagerInternal {
+
     @IntDef(prefix = "PACKAGE_", value = {
             PACKAGE_SYSTEM,
             PACKAGE_SETUP_WIZARD,
@@ -194,6 +196,19 @@
      */
     public abstract boolean isPermissionsReviewRequired(String packageName, int userId);
 
+
+    /**
+     * Gets whether a given package name belongs to the calling uid. If the calling uid is an
+     * {@link Process#isSdkSandboxUid(int) sdk sandbox uid}, checks whether the package name is
+     * equal to {@link PackageManager#getSdkSandboxPackageName()}.
+     *
+     * @param packageName The package name to check.
+     * @param callingUid The calling uid.
+     * @param userId The user under which to check.
+     * @return True if the package name belongs to the calling uid.
+     */
+    public abstract boolean isSameApp(String packageName, int callingUid, int userId);
+
     /**
      * Retrieve all of the information we know about a particular package/application.
      * @param filterCallingUid The results will be filtered in the context of this UID instead
@@ -657,6 +672,11 @@
     public abstract void notifyPackageUse(String packageName, int reason);
 
     /**
+     * Notify the package is force stopped.
+     */
+    public abstract void onPackageProcessKilledForUninstall(String packageName);
+
+    /**
      * Returns a package object for the given package name.
      */
     public abstract @Nullable AndroidPackage getPackage(@NonNull String packageName);
@@ -884,6 +904,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);
@@ -1344,4 +1369,8 @@
      */
     @NonNull
     public abstract PackageDataSnapshot snapshot();
+
+    public abstract void shutdown();
+
+    public abstract DynamicCodeLogger getDynamicCodeLogger();
 }
diff --git a/services/core/java/com/android/server/BinaryTransparencyService.java b/services/core/java/com/android/server/BinaryTransparencyService.java
index 6986d3b..1f8ef82 100644
--- a/services/core/java/com/android/server/BinaryTransparencyService.java
+++ b/services/core/java/com/android/server/BinaryTransparencyService.java
@@ -18,14 +18,22 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ModuleInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.os.Build;
+import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
+import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
 import android.os.SystemProperties;
@@ -42,6 +50,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
 
 /**
@@ -49,6 +58,7 @@
  */
 public class BinaryTransparencyService extends SystemService {
     private static final String TAG = "TransparencyService";
+    private static final String EXTRA_SERVICE = "service";
 
     @VisibleForTesting
     static final String VBMETA_DIGEST_UNINITIALIZED = "vbmeta-digest-uninitialized";
@@ -365,10 +375,80 @@
 
         // we are only interested in doing things at PHASE_BOOT_COMPLETED
         if (phase == PHASE_BOOT_COMPLETED) {
-            // due to potentially long computation that holds up boot time, apex sha computations
-            // are deferred to first call
             Slog.i(TAG, "Boot completed. Getting VBMeta Digest.");
             getVBMetaDigestInformation();
+
+            // due to potentially long computation that holds up boot time, computations for
+            // SHA256 digests of APEX and Module packages are scheduled here,
+            // but only executed when device is idle.
+            Slog.i(TAG, "Scheduling APEX and Module measurements to be updated.");
+            UpdateMeasurementsJobService.scheduleBinaryMeasurements(mContext,
+                    BinaryTransparencyService.this);
+        }
+    }
+
+    /**
+     * JobService to update binary measurements and update internal cache.
+     */
+    public static class UpdateMeasurementsJobService extends JobService {
+        private static final int COMPUTE_APEX_MODULE_SHA256_JOB_ID =
+                BinaryTransparencyService.UpdateMeasurementsJobService.class.hashCode();
+
+        @Override
+        public boolean onStartJob(JobParameters params) {
+            Slog.d(TAG, "Job to update binary measurements started.");
+            if (params.getJobId() != COMPUTE_APEX_MODULE_SHA256_JOB_ID) {
+                return false;
+            }
+
+            // we'll still update the measurements via threads to be mindful of low-end devices
+            // where this operation might take longer than expected, and so that we don't block
+            // system_server's main thread.
+            Executors.defaultThreadFactory().newThread(() -> {
+                // since we can't call updateBinaryMeasurements() directly, calling
+                // getApexInfo() achieves the same effect, and we simply discard the return
+                // value
+
+                IBinder b = ServiceManager.getService(Context.BINARY_TRANSPARENCY_SERVICE);
+                IBinaryTransparencyService iBtsService =
+                        IBinaryTransparencyService.Stub.asInterface(b);
+                try {
+                    iBtsService.getApexInfo();
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Updating binary measurements was interrupted.", e);
+                    return;
+                }
+                jobFinished(params, false);
+            }).start();
+
+            return true;
+        }
+
+        @Override
+        public boolean onStopJob(JobParameters params) {
+            return false;
+        }
+
+        @SuppressLint("DefaultLocale")
+        static void scheduleBinaryMeasurements(Context context, BinaryTransparencyService service) {
+            Slog.i(TAG, "Scheduling APEX & Module SHA256 digest computation job");
+            final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
+            if (jobScheduler == null) {
+                Slog.e(TAG, "Failed to obtain an instance of JobScheduler.");
+                return;
+            }
+
+            final JobInfo jobInfo = new JobInfo.Builder(COMPUTE_APEX_MODULE_SHA256_JOB_ID,
+                    new ComponentName(context, UpdateMeasurementsJobService.class))
+                    .setRequiresDeviceIdle(true)
+                    .build();
+            if (jobScheduler.schedule(jobInfo) != JobScheduler.RESULT_SUCCESS) {
+                Slog.e(TAG, "Failed to schedule job to update binary measurements.");
+                return;
+            }
+            Slog.d(TAG, String.format(
+                    "Job %d to update binary measurements scheduled successfully.",
+                    COMPUTE_APEX_MODULE_SHA256_JOB_ID));
         }
     }
 
@@ -380,7 +460,7 @@
 
     @NonNull
     private List<PackageInfo> getInstalledApexs() {
-        List<PackageInfo> results = new ArrayList<PackageInfo>();
+        List<PackageInfo> results = new ArrayList<>();
         PackageManager pm = mContext.getPackageManager();
         if (pm == null) {
             Slog.e(TAG, "Error obtaining an instance of PackageManager.");
diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java
index 8ea3dd6..1095ba3 100644
--- a/services/core/java/com/android/server/DiskStatsService.java
+++ b/services/core/java/com/android/server/DiskStatsService.java
@@ -125,6 +125,8 @@
                 DiskStatsFreeSpaceProto.FOLDER_CACHE);
         reportFreeSpace(new File("/system"), "System", pw, proto,
                 DiskStatsFreeSpaceProto.FOLDER_SYSTEM);
+        reportFreeSpace(Environment.getMetadataDirectory(), "Metadata", pw, proto,
+                DiskStatsFreeSpaceProto.FOLDER_METADATA);
 
         boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
         boolean blockBased = fileBased ? false : StorageManager.isBlockEncrypted();
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index ff2308c..186ff62 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.timedetector.NetworkTimeSuggestion;
@@ -35,17 +37,21 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
 import android.os.SystemClock;
 import android.os.TimestampedValue;
 import android.provider.Settings;
+import android.util.LocalLog;
 import android.util.Log;
 import android.util.NtpTrustedTime;
-import android.util.TimeUtils;
+import android.util.NtpTrustedTime.TimeResult;
 
 import com.android.internal.util.DumpUtils;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.time.Duration;
 
 /**
  * Monitors the network time. If looking up the network time fails for some reason, it tries a few
@@ -95,6 +101,13 @@
     // connection to happen.
     private int mTryAgainCounter;
 
+    /**
+     * A log that records the decisions to fetch a network time update.
+     * This is logged in bug reports to assist with debugging issues with network time suggestions.
+     */
+    @NonNull
+    private final LocalLog mLocalLog = new LocalLog(30, false /* useLocalTimestamps */);
+
     public NetworkTimeUpdateService(Context context) {
         mContext = context;
         mTime = NtpTrustedTime.getInstance(context);
@@ -143,6 +156,55 @@
                 }, new IntentFilter(ACTION_POLL));
     }
 
+    /**
+     * Clears the cached NTP time. For use during tests to simulate when no NTP time is available.
+     *
+     * <p>This operation takes place in the calling thread rather than the service's handler thread.
+     */
+    void clearTimeForTests() {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.SET_TIME, "clear latest network time");
+
+        mTime.clearCachedTimeResult();
+
+        mLocalLog.log("clearTimeForTests");
+    }
+
+    /**
+     * Forces the service to refresh the NTP time.
+     *
+     * <p>This operation takes place in the calling thread rather than the service's handler thread.
+     * This method does not affect currently scheduled refreshes. If the NTP request is successful
+     * it will make an (asynchronously handled) suggestion to the time detector.
+     */
+    boolean forceRefreshForTests() {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.SET_TIME, "force network time refresh");
+
+        boolean success = mTime.forceRefresh();
+        mLocalLog.log("forceRefreshForTests: success=" + success);
+
+        if (success) {
+            makeNetworkTimeSuggestion(mTime.getCachedTimeResult(),
+                    "Origin: NetworkTimeUpdateService: forceRefreshForTests");
+        }
+
+        return success;
+    }
+
+    /**
+     * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
+     * test value, i.e. so the normal value will be used next time.
+     */
+    void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.SET_TIME, "set NTP server config for tests");
+
+        mLocalLog.log("Setting server config for tests: hostname=" + hostname
+                + ", timeout=" + timeout);
+        mTime.setServerConfigForTests(hostname, timeout);
+    }
+
     private void onPollNetworkTime(int event) {
         // If we don't have any default network, don't bother.
         if (mDefaultNetwork == null) return;
@@ -155,24 +217,37 @@
     }
 
     private void onPollNetworkTimeUnderWakeLock(int event) {
+        long currentElapsedRealtimeMillis = SystemClock.elapsedRealtime();
         // Force an NTP fix when outdated
         NtpTrustedTime.TimeResult cachedNtpResult = mTime.getCachedTimeResult();
-        if (cachedNtpResult == null || cachedNtpResult.getAgeMillis() >= mPollingIntervalMs) {
+        if (cachedNtpResult == null || cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
+                >= mPollingIntervalMs) {
             if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
-            mTime.forceRefresh();
+            boolean isSuccessful = mTime.forceRefresh();
+            if (isSuccessful) {
+                mTryAgainCounter = 0;
+            } else {
+                String logMsg = "forceRefresh() returned false: cachedNtpResult=" + cachedNtpResult
+                        + ", currentElapsedRealtimeMillis=" + currentElapsedRealtimeMillis;
+
+                if (DBG) {
+                    Log.d(TAG, logMsg);
+                }
+                mLocalLog.log(logMsg);
+            }
+
             cachedNtpResult = mTime.getCachedTimeResult();
         }
 
-        if (cachedNtpResult != null && cachedNtpResult.getAgeMillis() < mPollingIntervalMs) {
+        if (cachedNtpResult != null
+                && cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
+                < mPollingIntervalMs) {
             // Obtained fresh fix; schedule next normal update
-            resetAlarm(mPollingIntervalMs);
+            resetAlarm(mPollingIntervalMs
+                    - cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis));
 
-            // Suggest the time to the time detector. It may choose use it to set the system clock.
-            TimestampedValue<Long> timeSignal = new TimestampedValue<>(
-                    cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis());
-            NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
-            timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateService. event=" + event);
-            mTimeDetector.suggestNetworkTime(timeSuggestion);
+            makeNetworkTimeSuggestion(cachedNtpResult,
+                    "Origin: NetworkTimeUpdateService. event=" + event);
         } else {
             // No fresh fix; schedule retry
             mTryAgainCounter++;
@@ -180,12 +255,26 @@
                 resetAlarm(mPollingIntervalShorterMs);
             } else {
                 // Try much later
+                String logMsg = "mTryAgainTimesMax exceeded, cachedNtpResult=" + cachedNtpResult;
+                if (DBG) {
+                    Log.d(TAG, logMsg);
+                }
+                mLocalLog.log(logMsg);
                 mTryAgainCounter = 0;
                 resetAlarm(mPollingIntervalMs);
             }
         }
     }
 
+    /** Suggests the time to the time detector. It may choose use it to set the system clock. */
+    private void makeNetworkTimeSuggestion(TimeResult ntpResult, String debugInfo) {
+        TimestampedValue<Long> timeSignal = new TimestampedValue<>(
+                ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
+        NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
+        timeSuggestion.addDebugInfo(debugInfo);
+        mTimeDetector.suggestNetworkTime(timeSuggestion);
+    }
+
     /**
      * Cancel old alarm and starts a new one for the specified interval.
      *
@@ -274,17 +363,23 @@
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        pw.print("PollingIntervalMs: ");
-        TimeUtils.formatDuration(mPollingIntervalMs, pw);
-        pw.print("\nPollingIntervalShorterMs: ");
-        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
-        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
-        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
-        NtpTrustedTime.TimeResult ntpResult = mTime.getCachedTimeResult();
-        pw.println("NTP cache result: " + ntpResult);
-        if (ntpResult != null) {
-            pw.println("NTP result age: " + ntpResult.getAgeMillis());
-        }
+        pw.println("mPollingIntervalMs=" + Duration.ofMillis(mPollingIntervalMs));
+        pw.println("mPollingIntervalShorterMs=" + Duration.ofMillis(mPollingIntervalShorterMs));
+        pw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
+        pw.println("mTryAgainCounter=" + mTryAgainCounter);
         pw.println();
+        pw.println("NtpTrustedTime:");
+        mTime.dump(pw);
+        pw.println();
+        pw.println("Local logs:");
+        mLocalLog.dump(fd, pw, args);
+        pw.println();
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+        new NetworkTimeUpdateServiceShellCommand(this).exec(
+                this, in, out, err, args, callback, resultReceiver);
     }
 }
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java b/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java
new file mode 100644
index 0000000..464af01
--- /dev/null
+++ b/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java
@@ -0,0 +1,129 @@
+/*
+ * 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;
+
+import android.annotation.NonNull;
+import android.os.ShellCommand;
+
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.util.Objects;
+
+/** Implements the shell command interface for {@link NetworkTimeUpdateService}. */
+class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
+
+    /**
+     * The name of the service.
+     */
+    private static final String SHELL_COMMAND_SERVICE_NAME = "network_time_update_service";
+
+    /**
+     * A shell command that clears the time signal received from the network.
+     */
+    private static final String SHELL_COMMAND_CLEAR_TIME = "clear_time";
+
+    /**
+     * A shell command that forces the time signal to be refreshed from the network.
+     */
+    private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
+
+    /**
+     * A shell command that sets the NTP server config for tests. Config is cleared on reboot.
+     */
+    private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config";
+    private static final String SET_SERVER_CONFIG_HOSTNAME_ARG = "--hostname";
+    private static final String SET_SERVER_CONFIG_TIMEOUT_ARG = "--timeout_millis";
+
+    @NonNull
+    private final NetworkTimeUpdateService mNetworkTimeUpdateService;
+
+    NetworkTimeUpdateServiceShellCommand(NetworkTimeUpdateService networkTimeUpdateService) {
+        mNetworkTimeUpdateService = Objects.requireNonNull(networkTimeUpdateService);
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+
+        switch (cmd) {
+            case SHELL_COMMAND_CLEAR_TIME:
+                return runClearTime();
+            case SHELL_COMMAND_FORCE_REFRESH:
+                return runForceRefresh();
+            case SHELL_COMMAND_SET_SERVER_CONFIG:
+                return runSetServerConfig();
+            default: {
+                return handleDefaultCommands(cmd);
+            }
+        }
+    }
+
+    private int runClearTime() {
+        mNetworkTimeUpdateService.clearTimeForTests();
+        return 0;
+    }
+
+    private int runForceRefresh() {
+        boolean success = mNetworkTimeUpdateService.forceRefreshForTests();
+        getOutPrintWriter().println(success);
+        return 0;
+    }
+
+    private int runSetServerConfig() {
+        String hostname = null;
+        Duration timeout = null;
+        String opt;
+        while ((opt = getNextArg()) != null) {
+            switch (opt) {
+                case SET_SERVER_CONFIG_HOSTNAME_ARG: {
+                    hostname = getNextArgRequired();
+                    break;
+                }
+                case SET_SERVER_CONFIG_TIMEOUT_ARG: {
+                    timeout = Duration.ofMillis(Integer.parseInt(getNextArgRequired()));
+                    break;
+                }
+                default: {
+                    throw new IllegalArgumentException("Unknown option: " + opt);
+                }
+            }
+        }
+        mNetworkTimeUpdateService.setServerConfigForTests(hostname, timeout);
+        return 0;
+    }
+
+    @Override
+    public void onHelp() {
+        final PrintWriter pw = getOutPrintWriter();
+        pw.printf("Network Time Update Service (%s) commands:\n", SHELL_COMMAND_SERVICE_NAME);
+        pw.printf("  help\n");
+        pw.printf("    Print this help text.\n");
+        pw.printf("  %s\n", SHELL_COMMAND_CLEAR_TIME);
+        pw.printf("    Clears the latest time.\n");
+        pw.printf("  %s\n", SHELL_COMMAND_FORCE_REFRESH);
+        pw.printf("    Refreshes the latest time. Prints whether it was successful.\n");
+        pw.printf("  %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
+        pw.printf("    Sets the NTP server config for tests. The config is not persisted.\n");
+        pw.printf("      Options: [%s <hostname>] [%s <millis>]\n",
+                SET_SERVER_CONFIG_HOSTNAME_ARG, SET_SERVER_CONFIG_TIMEOUT_ARG);
+        pw.printf("      Each key/value is optional and must be specified to override the\n");
+        pw.printf("      normal value, not specifying a key causes it to reset to the original.\n");
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 4129feb..6ff8e36 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -21,14 +21,13 @@
 per-file *Battery* = file:/BATTERY_STATS_OWNERS
 per-file *BinaryTransparency* = file:/core/java/android/transparency/OWNERS
 per-file *Binder* = file:/core/java/com/android/internal/os/BINDER_OWNERS
-per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
 per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
 per-file **IpSec* = file:/services/core/java/com/android/server/net/OWNERS
 per-file **IpSec* = file:/services/core/java/com/android/server/vcn/OWNERS
 per-file *Location* = file:/services/core/java/com/android/server/location/OWNERS
 per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
 per-file *Storage* = file:/core/java/android/os/storage/OWNERS
-per-file *TimeUpdate* = file:/core/java/android/app/timezone/OWNERS
+per-file *TimeUpdate* = file:/services/core/java/com/android/server/timezonedetector/OWNERS
 per-file DynamicSystemService.java = file:/packages/DynamicSystemInstallationService/OWNERS
 per-file GestureLauncherService.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
 per-file MmsServiceBroker.java = file:/telephony/OWNERS
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c194527..4628a1f 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -176,9 +176,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 +195,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
@@ -3130,8 +3123,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 +3133,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)
@@ -3677,11 +3670,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 +4588,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 +4615,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)
@@ -4747,7 +4726,7 @@
     private int getMountModeInternal(int uid, String packageName) {
         try {
             // Get some easy cases out of the way first
-            if (Process.isIsolated(uid) || Process.isSupplemental(uid)) {
+            if (Process.isIsolated(uid) || Process.isSdkSandboxUid(uid)) {
                 return StorageManager.MOUNT_MODE_EXTERNAL_NONE;
             }
 
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 12e438d..78df983 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -21,6 +21,8 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.UserInfo;
 import android.os.Environment;
 import android.os.SystemClock;
@@ -38,6 +40,7 @@
 import com.android.server.SystemService.TargetUser;
 import com.android.server.SystemService.UserCompletedEventType;
 import com.android.server.am.EventLogTags;
+import com.android.server.pm.ApexManager;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.utils.TimingsTraceAndSlog;
 
@@ -47,6 +50,8 @@
 import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -147,12 +152,31 @@
      * @return The service instance.
      */
     public SystemService startServiceFromJar(String className, String path) {
-        PathClassLoader pathClassLoader = SystemServerClassLoaderFactory.getOrCreateClassLoader(
-                path, this.getClass().getClassLoader());
+        PathClassLoader pathClassLoader =
+                SystemServerClassLoaderFactory.getOrCreateClassLoader(
+                        path, this.getClass().getClassLoader(), isJarInTestApex(path));
         final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader);
         return startService(serviceClass);
     }
 
+    /**
+     * Returns true if the jar is in a test APEX.
+     */
+    private static boolean isJarInTestApex(String pathStr) {
+        Path path = Paths.get(pathStr);
+        if (path.getNameCount() >= 2 && path.getName(0).toString().equals("apex")) {
+            String apexModuleName = path.getName(1).toString();
+            ApexManager apexManager = ApexManager.getInstance();
+            String packageName = apexManager.getActivePackageNameForApexModuleName(apexModuleName);
+            PackageInfo packageInfo = apexManager.getPackageInfo(
+                    packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
+            if (packageInfo != null) {
+                return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0;
+            }
+        }
+        return false;
+    }
+
     /*
      * Loads and initializes a class from the given classLoader. Returns the class.
      */
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index efbc4de..40ab0c0 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -651,100 +651,102 @@
     }
 
     private void onMultiSimConfigChanged() {
-        int oldNumPhones = mNumPhones;
-        mNumPhones = getTelephonyManager().getActiveModemCount();
-        if (oldNumPhones == mNumPhones) return;
+        synchronized (mRecords) {
+            int oldNumPhones = mNumPhones;
+            mNumPhones = getTelephonyManager().getActiveModemCount();
+            if (oldNumPhones == mNumPhones) return;
 
-        if (DBG) {
-            log("TelephonyRegistry: activeModemCount changed from " + oldNumPhones
-                    + " to " + mNumPhones);
-        }
-        mCallState = copyOf(mCallState, mNumPhones);
-        mDataActivity = copyOf(mCallState, mNumPhones);
-        mDataConnectionState = copyOf(mCallState, mNumPhones);
-        mDataConnectionNetworkType = copyOf(mCallState, mNumPhones);
-        mCallIncomingNumber = copyOf(mCallIncomingNumber, mNumPhones);
-        mServiceState = copyOf(mServiceState, mNumPhones);
-        mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones);
-        mDataActivationState = copyOf(mDataActivationState, mNumPhones);
-        mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones);
-        if (mSignalStrength != null) {
-            mSignalStrength = copyOf(mSignalStrength, mNumPhones);
-        } else {
-            mSignalStrength = new SignalStrength[mNumPhones];
-        }
-        mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
-        mCallForwarding = copyOf(mCallForwarding, mNumPhones);
-        mCellIdentity = copyOf(mCellIdentity, mNumPhones);
-        mSrvccState = copyOf(mSrvccState, mNumPhones);
-        mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
-        mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
-        mBackgroundCallState = copyOf(mBackgroundCallState, mNumPhones);
-        mRingingCallState = copyOf(mRingingCallState, mNumPhones);
-        mCallDisconnectCause = copyOf(mCallDisconnectCause, mNumPhones);
-        mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones);
-        mCallQuality = copyOf(mCallQuality, mNumPhones);
-        mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
-        mCallAttributes = copyOf(mCallAttributes, mNumPhones);
-        mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
-        mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
-        mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
-        mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones);
-        mIsDataEnabled= copyOf(mIsDataEnabled, mNumPhones);
-        mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
-        mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones);
-        mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones);
+            if (DBG) {
+                log("TelephonyRegistry: activeModemCount changed from " + oldNumPhones
+                        + " to " + mNumPhones);
+            }
+            mCallState = copyOf(mCallState, mNumPhones);
+            mDataActivity = copyOf(mCallState, mNumPhones);
+            mDataConnectionState = copyOf(mCallState, mNumPhones);
+            mDataConnectionNetworkType = copyOf(mCallState, mNumPhones);
+            mCallIncomingNumber = copyOf(mCallIncomingNumber, mNumPhones);
+            mServiceState = copyOf(mServiceState, mNumPhones);
+            mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones);
+            mDataActivationState = copyOf(mDataActivationState, mNumPhones);
+            mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones);
+            if (mSignalStrength != null) {
+                mSignalStrength = copyOf(mSignalStrength, mNumPhones);
+            } else {
+                mSignalStrength = new SignalStrength[mNumPhones];
+            }
+            mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
+            mCallForwarding = copyOf(mCallForwarding, mNumPhones);
+            mCellIdentity = copyOf(mCellIdentity, mNumPhones);
+            mSrvccState = copyOf(mSrvccState, mNumPhones);
+            mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
+            mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
+            mBackgroundCallState = copyOf(mBackgroundCallState, mNumPhones);
+            mRingingCallState = copyOf(mRingingCallState, mNumPhones);
+            mCallDisconnectCause = copyOf(mCallDisconnectCause, mNumPhones);
+            mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones);
+            mCallQuality = copyOf(mCallQuality, mNumPhones);
+            mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
+            mCallAttributes = copyOf(mCallAttributes, mNumPhones);
+            mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
+            mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
+            mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
+            mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones);
+            mIsDataEnabled = copyOf(mIsDataEnabled, mNumPhones);
+            mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
+            mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones);
+            mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones);
 
-        // ds -> ss switch.
-        if (mNumPhones < oldNumPhones) {
-            cutListToSize(mCellInfo, mNumPhones);
-            cutListToSize(mImsReasonInfo, mNumPhones);
-            cutListToSize(mPreciseDataConnectionStates, mNumPhones);
-            cutListToSize(mBarringInfo, mNumPhones);
-            cutListToSize(mPhysicalChannelConfigs, mNumPhones);
-            cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
-            cutListToSize(mCarrierPrivilegeStates, mNumPhones);
-            return;
-        }
+            // ds -> ss switch.
+            if (mNumPhones < oldNumPhones) {
+                cutListToSize(mCellInfo, mNumPhones);
+                cutListToSize(mImsReasonInfo, mNumPhones);
+                cutListToSize(mPreciseDataConnectionStates, mNumPhones);
+                cutListToSize(mBarringInfo, mNumPhones);
+                cutListToSize(mPhysicalChannelConfigs, mNumPhones);
+                cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
+                cutListToSize(mCarrierPrivilegeStates, mNumPhones);
+                return;
+            }
 
-        // mNumPhones > oldNumPhones: ss -> ds switch
-        for (int i = oldNumPhones; i < mNumPhones; i++) {
-            mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
-            mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
-            mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
-            mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
-            mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
-            mCallIncomingNumber[i] =  "";
-            mServiceState[i] =  new ServiceState();
-            mSignalStrength[i] =  null;
-            mUserMobileDataState[i] = false;
-            mMessageWaiting[i] =  false;
-            mCallForwarding[i] =  false;
-            mCellIdentity[i] = null;
-            mCellInfo.add(i, null);
-            mImsReasonInfo.add(i, null);
-            mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
-            mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
-            mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
-            mCallQuality[i] = createCallQuality();
-            mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
-                    TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
-            mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-            mPreciseCallState[i] = createPreciseCallState();
-            mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-            mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-            mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
-            mPreciseDataConnectionStates.add(new ArrayMap<>());
-            mBarringInfo.add(i, new BarringInfo());
-            mCarrierNetworkChangeState[i] = false;
-            mTelephonyDisplayInfos[i] = null;
-            mIsDataEnabled[i] = false;
-            mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
-            mPhysicalChannelConfigs.add(i, new ArrayList<>());
-            mAllowedNetworkTypeReason[i] = -1;
-            mAllowedNetworkTypeValue[i] = -1;
-            mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
-            mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
+            // mNumPhones > oldNumPhones: ss -> ds switch
+            for (int i = oldNumPhones; i < mNumPhones; i++) {
+                mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
+                mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
+                mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
+                mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
+                mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
+                mCallIncomingNumber[i] = "";
+                mServiceState[i] = new ServiceState();
+                mSignalStrength[i] = null;
+                mUserMobileDataState[i] = false;
+                mMessageWaiting[i] = false;
+                mCallForwarding[i] = false;
+                mCellIdentity[i] = null;
+                mCellInfo.add(i, null);
+                mImsReasonInfo.add(i, null);
+                mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
+                mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
+                mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
+                mCallQuality[i] = createCallQuality();
+                mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
+                        TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
+                mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+                mPreciseCallState[i] = createPreciseCallState();
+                mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+                mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+                mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
+                mPreciseDataConnectionStates.add(new ArrayMap<>());
+                mBarringInfo.add(i, new BarringInfo());
+                mCarrierNetworkChangeState[i] = false;
+                mTelephonyDisplayInfos[i] = null;
+                mIsDataEnabled[i] = false;
+                mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
+                mPhysicalChannelConfigs.add(i, new ArrayList<>());
+                mAllowedNetworkTypeReason[i] = -1;
+                mAllowedNetworkTypeValue[i] = -1;
+                mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
+                mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
+            }
         }
     }
 
@@ -2802,11 +2804,11 @@
                             + " callback=" + callback
                             + " callback.asBinder=" + callback.asBinder());
         }
-        if (!validatePhoneId(phoneId)) {
-            throw new IllegalArgumentException("Invalid slot index: " + phoneId);
-        }
 
         synchronized (mRecords) {
+            if (!validatePhoneId(phoneId)) {
+                throw new IllegalArgumentException("Invalid slot index: " + phoneId);
+            }
             Record r = add(
                     callback.asBinder(), Binder.getCallingUid(), Binder.getCallingPid(), false);
 
@@ -2851,7 +2853,6 @@
         if (!checkNotifyPermission("notifyCarrierPrivilegesChanged")) {
             return;
         }
-        if (!validatePhoneId(phoneId)) return;
         if (VDBG) {
             log(
                     "notifyCarrierPrivilegesChanged: phoneId=" + phoneId
@@ -2859,6 +2860,9 @@
                             + ", uids=" + Arrays.toString(privilegedUids) + ">");
         }
         synchronized (mRecords) {
+            if (!validatePhoneId(phoneId)) {
+                throw new IllegalArgumentException("Invalid slot index: " + phoneId);
+            }
             mCarrierPrivilegeStates.set(
                     phoneId, new Pair<>(privilegedPackageNames, privilegedUids));
             for (Record r : mRecords) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 092172a..d4ad718 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2721,7 +2721,7 @@
 
     int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
             String resolvedType, final IServiceConnection connection, int flags,
-            String instanceName, boolean isSupplementalProcessService, int supplementedAppUid,
+            String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
             String callingPackage, final int userId)
             throws TransactionTooLargeException {
         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
@@ -2807,7 +2807,7 @@
         final boolean allowInstant = (flags & Context.BIND_ALLOW_INSTANT) != 0;
 
         ServiceLookupResult res = retrieveServiceLocked(service, instanceName,
-                isSupplementalProcessService, supplementedAppUid, resolvedType, callingPackage,
+                isSdkSandboxService, sdkSandboxClientAppUid, resolvedType, callingPackage,
                 callingPid, callingUid, userId, true, callerFg, isBindExternal, allowInstant);
         if (res == null) {
             return 0;
@@ -3234,13 +3234,13 @@
     }
 
     private ServiceLookupResult retrieveServiceLocked(Intent service,
-            String instanceName, boolean isSupplementalProcessService, int supplementedAppUid,
+            String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
             String resolvedType,
             String callingPackage, int callingPid, int callingUid, int userId,
             boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
             boolean allowInstant) {
-        if (isSupplementalProcessService && instanceName == null) {
-            throw new IllegalArgumentException("No instanceName provided for supplemental process");
+        if (isSdkSandboxService && instanceName == null) {
+            throw new IllegalArgumentException("No instanceName provided for sdk sandbox process");
         }
 
         ServiceRecord r = null;
@@ -3319,13 +3319,13 @@
                 }
                 if (instanceName != null
                         && (sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0
-                        && !isSupplementalProcessService) {
+                        && !isSdkSandboxService) {
                     throw new IllegalArgumentException("Can't use instance name '" + instanceName
-                            + "' with non-isolated non-supplemental service '" + sInfo.name + "'");
+                            + "' with non-isolated non-sdk sandbox service '" + sInfo.name + "'");
                 }
-                if (isSupplementalProcessService
+                if (isSdkSandboxService
                         && (sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) {
-                    throw new IllegalArgumentException("Service cannot be both supplemental and "
+                    throw new IllegalArgumentException("Service cannot be both sdk sandbox and "
                             + "isolated");
                 }
 
@@ -3412,11 +3412,11 @@
                     final Intent.FilterComparison filter
                             = new Intent.FilterComparison(service.cloneFilter());
                     final ServiceRestarter res = new ServiceRestarter();
-                    String supplementalProcessName = isSupplementalProcessService ? instanceName
+                    String sdkSandboxProcessName = isSdkSandboxService ? instanceName
                                                                                   : null;
                     r = new ServiceRecord(mAm, className, name, definingPackageName,
                             definingUid, filter, sInfo, callingFromFg, res,
-                            supplementalProcessName, supplementedAppUid);
+                            sdkSandboxProcessName, sdkSandboxClientAppUid);
                     res.setService(r);
                     smap.mServicesByInstanceName.put(name, r);
                     smap.mServicesByIntent.put(filter, r);
@@ -4139,7 +4139,8 @@
 
         final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
         final String procName = r.processName;
-        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName);
+        HostingRecord hostingRecord = new HostingRecord("service", r.instanceName,
+                r.definingPackageName, r.definingUid, r.serviceInfo.processName);
         ProcessRecord app;
 
         if (!isolated) {
@@ -4177,11 +4178,12 @@
             app = r.isolationHostProc;
             if (WebViewZygote.isMultiprocessEnabled()
                     && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
-                hostingRecord = HostingRecord.byWebviewZygote(r.instanceName);
+                hostingRecord = HostingRecord.byWebviewZygote(r.instanceName, r.definingPackageName,
+                        r.definingUid, r.serviceInfo.processName);
             }
             if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
                 hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
-                        r.definingUid);
+                        r.definingUid, r.serviceInfo.processName);
             }
         }
 
@@ -4190,9 +4192,9 @@
         if (app == null && !permissionsReviewRequired && !packageFrozen) {
             // TODO (chriswailes): Change the Zygote policy flags based on if the launch-for-service
             //  was initiated from a notification tap or not.
-            if (r.supplemental) {
-                final int uid = Process.toSupplementalUid(r.supplementedAppUid);
-                app = mAm.startSupplementalProcessLocked(procName, r.appInfo, true, intentFlags,
+            if (r.isSdkSandbox) {
+                final int uid = Process.toSdkSandboxUid(r.sdkSandboxClientAppUid);
+                app = mAm.startSdkSandboxProcessLocked(procName, r.appInfo, true, intentFlags,
                         hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, uid);
                 r.isolationHostProc = app;
             } else {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 5fe8719..18e0155 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -650,6 +650,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 +691,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.
      */
@@ -869,6 +909,15 @@
                             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;
                         }
@@ -1288,6 +1337,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);
@@ -1562,6 +1632,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 535340b..3226a2b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerLocal.java
+++ b/services/core/java/com/android/server/am/ActivityManagerLocal.java
@@ -65,15 +65,15 @@
     void tempAllowWhileInUsePermissionInFgs(int uid, long durationMs);
 
     /**
-     * Binds to a supplemental process service, creating it if needed. You can through the arguments
+     * Binds to a sdk sandbox service, creating it if needed. You can through the arguments
      * here have the system bring up multiple concurrent processes hosting their own instance of
      * that service. The {@code processName} you provide here identifies the different instances.
      *
-     * @param service Identifies the supplemental process service to connect to. The Intent must
+     * @param service Identifies the sdk sandbox process service to connect to. The Intent must
      *        specify an explicit component name. This value cannot be null.
      * @param conn Receives information as the service is started and stopped.
      *        This must be a valid ServiceConnection object; it must not be null.
-     * @param userAppUid Uid of the app for which the supplemental process needs to be spawned.
+     * @param clientAppUid Uid of the app for which the sdk sandbox process needs to be spawned.
      * @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.
@@ -86,7 +86,7 @@
      * @see Context#bindService(Intent, ServiceConnection, int)
      */
     @SuppressLint("RethrowRemoteException")
-    boolean bindSupplementalProcessService(@NonNull Intent service, @NonNull ServiceConnection conn,
-            int userAppUid, @NonNull String processName, @Context.BindServiceFlags int flags)
+    boolean bindSdkSandboxService(@NonNull Intent service, @NonNull ServiceConnection conn,
+            int clientAppUid, @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 1c10304..9512e1d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -79,6 +79,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;
@@ -694,12 +695,6 @@
         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
     }
 
-    /**
-     * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
-     * <p>Not actually used</p>
-     */
-    private volatile String mDeviceOwnerName;
-
     private volatile int mDeviceOwnerUid = INVALID_UID;
 
     /**
@@ -2795,13 +2790,13 @@
     }
 
     @GuardedBy("this")
-    final ProcessRecord startSupplementalProcessLocked(String processName,
+    final ProcessRecord startSdkSandboxProcessLocked(String processName,
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
-            HostingRecord hostingRecord, int zygotePolicyFlags, int supplementalUid) {
+            HostingRecord hostingRecord, int zygotePolicyFlags, int sdkSandboxUid) {
         return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                 hostingRecord, zygotePolicyFlags, false /* allowWhileBooting */,
                 false /* isolated */, 0 /* isolatedUid */,
-                true /* supplemental */, supplementalUid,
+                true /* isSdkSandbox */, sdkSandboxUid,
                 null /* ABI override */, null /* entryPoint */,
                 null /* entryPointArgs */, null /* crashHandler */);
     }
@@ -2813,7 +2808,7 @@
             boolean isolated) {
         return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                 hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
-                false /* supplemental */, 0 /* supplementalUid */,
+                false /* isSdkSandbox */, 0 /* sdkSandboxClientdAppUid */,
                 null /* ABI override */, null /* entryPoint */,
                 null /* entryPointArgs */, null /* crashHandler */);
     }
@@ -6238,17 +6233,6 @@
     }
 
     @Override
-    public void updateDeviceOwner(String packageName) {
-        final int callingUid = Binder.getCallingUid();
-        if (callingUid != 0 && callingUid != SYSTEM_UID) {
-            throw new SecurityException("updateDeviceOwner called from non-system process");
-        }
-        synchronized (this) {
-            mDeviceOwnerName = packageName;
-        }
-    }
-
-    @Override
     public void updateLockTaskPackages(int userId, String[] packages) {
         mActivityTaskManager.updateLockTaskPackages(userId, packages);
     }
@@ -8578,6 +8562,9 @@
             if (process.info.isInstantApp()) {
                 sb.append("Instant-App: true\n");
             }
+            if (isSdkSandboxUid(process.uid)) {
+                sb.append("SdkSandbox: true\n");
+            }
         }
     }
 
@@ -9172,10 +9159,14 @@
             }
             mComponentAliasResolver.dump(pw);
         }
-        if (dumpAll) {
-            pw.println("-------------------------------------------------------------------------------");
-            mAppRestrictionController.dump(pw, "");
-        }
+    }
+
+    /**
+     * Dump the app restriction controller, it's required not to hold the global lock here.
+     */
+    private void dumpAppRestrictionController(PrintWriter pw) {
+        pw.println("-------------------------------------------------------------------------------");
+        mAppRestrictionController.dump(pw, "");
     }
 
     /**
@@ -9193,6 +9184,7 @@
         boolean dumpVisibleStacksOnly = false;
         boolean dumpFocusedStackOnly = false;
         String dumpPackage = null;
+        int dumpUserId = UserHandle.USER_ALL;
 
         int opti = 0;
         while (opti < args.length) {
@@ -9224,6 +9216,17 @@
                 dumpCheckinFormat = true;
             } else if ("--normal-priority".equals(opt)) {
                 dumpNormalPriority = true;
+            } else if ("--user".equals(opt)) {
+                if (opti < args.length) {
+                    dumpUserId = UserHandle.parseUserArg(args[opti]);
+                    if (dumpUserId == UserHandle.USER_CURRENT) {
+                        dumpUserId = mUserController.getCurrentUserId();
+                    }
+                    opti++;
+                } else {
+                    pw.println("Error: --user option requires user id argument");
+                    return;
+                }
             } else if ("-h".equals(opt)) {
                 ActivityManagerShellCommand.dumpHelp(pw, true);
                 return;
@@ -9414,29 +9417,17 @@
             } else if ("service".equals(cmd)) {
                 String[] newArgs;
                 String name;
-                int[] users = null;
                 if (opti >= args.length) {
                     name = null;
                     newArgs = EMPTY_STRING_ARRAY;
                 } else {
                     name = args[opti];
                     opti++;
-                    if ("--user".equals(name) && opti < args.length) {
-                        int userId = UserHandle.parseUserArg(args[opti]);
-                        opti++;
-                        if (userId != UserHandle.USER_ALL) {
-                            if (userId == UserHandle.USER_CURRENT) {
-                                userId = getCurrentUser().id;
-                            }
-                            users = new int[] { userId };
-                        }
-                        name = args[opti];
-                        opti++;
-                    }
                     newArgs = new String[args.length - opti];
                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
                             args.length - opti);
                 }
+                int[] users = dumpUserId == UserHandle.USER_ALL ? null : new int[] { dumpUserId };
                 if (!mServices.dumpService(fd, pw, name, users, newArgs, 0, dumpAll)) {
                     pw.println("No services match: " + name);
                     pw.println("Use -h for help.");
@@ -9497,7 +9488,7 @@
             } else {
                 // Dumping a single activity?
                 if (!mAtmInternal.dumpActivity(fd, pw, cmd, args, opti, dumpAll,
-                        dumpVisibleStacksOnly, dumpFocusedStackOnly)) {
+                        dumpVisibleStacksOnly, dumpFocusedStackOnly, dumpUserId)) {
                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
                     int res = shell.exec(this, null, fd, null, args, null,
                             new ResultReceiver(null));
@@ -9531,6 +9522,9 @@
                             dumpNormalPriority, dumpAppId, false /* dumpProxies */);
                 }
             }
+            if (dumpAll) {
+                dumpAppRestrictionController(pw);
+            }
         }
         Binder.restoreCallingIdentity(origId);
     }
@@ -9762,7 +9756,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));
                         }
                     }
                 }
@@ -12406,7 +12400,7 @@
 
     private int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
             String resolvedType, IServiceConnection connection, int flags, String instanceName,
-            boolean isSupplementalProcessService, int supplementedAppUid, String callingPackage,
+            boolean isSdkSandboxService, int sdkSandboxClientdAppUid, String callingPackage,
             int userId)
             throws TransactionTooLargeException {
         enforceNotIsolatedCaller("bindService");
@@ -12420,7 +12414,7 @@
             throw new IllegalArgumentException("callingPackage cannot be null");
         }
 
-        if (isSupplementalProcessService && instanceName == null) {
+        if (isSdkSandboxService && instanceName == null) {
             throw new IllegalArgumentException("No instance name provided for isolated process");
         }
 
@@ -12436,10 +12430,19 @@
             }
         }
 
-        synchronized(this) {
-            return mServices.bindServiceLocked(caller, token, service, resolvedType, connection,
-                    flags, instanceName, isSupplementalProcessService, supplementedAppUid,
-                    callingPackage, userId);
+        try {
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                final ComponentName cn = service.getComponent();
+                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindService:"
+                        + (cn != null ? cn.toShortString() : service.getAction()));
+            }
+            synchronized (this) {
+                return mServices.bindServiceLocked(caller, token, service, resolvedType, connection,
+                        flags, instanceName, isSdkSandboxService, sdkSandboxClientdAppUid,
+                        callingPackage, userId);
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
         }
     }
 
@@ -13596,6 +13599,8 @@
                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
                                                 false, true, true, false, fullUninstall, userId,
                                                 removed ? "pkg removed" : "pkg changed");
+                                        getPackageManagerInternal()
+                                                .onPackageProcessKilledForUninstall(ssp);
                                     } else {
                                         // Kill any app zygotes always, since they can't fork new
                                         // processes with references to the old code
@@ -14347,7 +14352,8 @@
             int match = mContext.getPackageManager().checkSignatures(
                     ii.targetPackage, ii.packageName);
             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
-                if (Build.IS_DEBUGGABLE && (flags & INSTR_FLAG_ALWAYS_CHECK_SIGNATURE) == 0) {
+                if (Build.IS_DEBUGGABLE && (callingUid == Process.ROOT_UID)
+                        && (flags & INSTR_FLAG_ALWAYS_CHECK_SIGNATURE) == 0) {
                     Slog.w(TAG, "Instrumentation test " + ii.packageName
                             + " doesn't have a signature matching the target " + ii.targetPackage
                             + ", which would not be allowed on the production Android builds");
@@ -16015,7 +16021,7 @@
         }
 
         @Override
-        public boolean bindSupplementalProcessService(Intent service, ServiceConnection conn,
+        public boolean bindSdkSandboxService(Intent service, ServiceConnection conn,
                 int userAppUid, String processName, int flags) throws RemoteException {
             if (service == null) {
                 throw new IllegalArgumentException("intent is null");
@@ -16996,7 +17002,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
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 655e309..7cd45fe 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -1217,7 +1217,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 +1227,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(
@@ -1531,7 +1531,7 @@
 
             if (excessive) {
                 if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
-                    Slog.i(TAG, "Excessive background current drain " + uid
+                    Slog.i(TAG, "Excessive background current drain " + uid + " "
                             + usage + " (" + usage.percentageToString() + " ) over "
                             + TimeUtils.formatDuration(mBgCurrentDrainWindowMs));
                 }
@@ -1542,7 +1542,7 @@
                 }
             } else {
                 if (DEBUG_BACKGROUND_BATTERY_TRACKER) {
-                    Slog.i(TAG, "Background current drain backs to normal " + uid
+                    Slog.i(TAG, "Background current drain backs to normal " + uid + " "
                             + usage + " (" + usage.percentageToString() + " ) over "
                             + TimeUtils.formatDuration(mBgCurrentDrainWindowMs));
                 }
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/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 2ffd487..6e6cb87 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -77,6 +77,7 @@
 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.AppFGSTracker.foregroundServiceTypeToIndex;
+import static com.android.server.am.BaseAppStateTracker.ONE_DAY;
 
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.IntDef;
@@ -87,7 +88,6 @@
 import android.app.ActivityManager.RestrictionLevel;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.AppBackgroundRestrictionListener;
-import android.app.ActivityThread;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.IUidObserver;
@@ -192,7 +192,7 @@
     // No lock is needed, as it's immutable after initialization in constructor.
     private final ArrayList<BaseAppStateTracker> mAppStateTrackers = new ArrayList<>();
 
-    @GuardedBy("mLock")
+    @GuardedBy("mSettingsLock")
     private final RestrictionSettings mRestrictionSettings = new RestrictionSettings();
 
     private final CopyOnWriteArraySet<AppBackgroundRestrictionListener> mRestrictionListeners =
@@ -202,7 +202,7 @@
      * A mapping between the UID/Pkg and its pending work which should be triggered on inactive;
      * an active UID/pkg pair should have an entry here, although its pending work could be null.
      */
-    @GuardedBy("mLock")
+    @GuardedBy("mSettingsLock")
     private final SparseArrayMap<String, Runnable> mActiveUids = new SparseArrayMap<>();
 
     // No lock is needed as it's accessed in bg handler thread only.
@@ -219,6 +219,7 @@
     private int[] mDeviceIdleExceptIdleAllowlist = new int[0]; // No lock is needed.
 
     private final Object mLock = new Object();
+    private final Object mSettingsLock = new Object();
     private final Injector mInjector;
     private final NotificationHelper mNotificationHelper;
 
@@ -257,12 +258,95 @@
 
     final ActivityManagerService mActivityManagerService;
 
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            switch (intent.getAction()) {
+                case Intent.ACTION_PACKAGE_ADDED: {
+                    if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                        final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+                        if (uid >= 0) {
+                            onUidAdded(uid);
+                        }
+                    }
+                }
+                // fall through.
+                case Intent.ACTION_PACKAGE_CHANGED: {
+                    final String pkgName = intent.getData().getSchemeSpecificPart();
+                    final String[] cmpList = intent.getStringArrayExtra(
+                            Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
+                    // If this is PACKAGE_ADDED (cmpList == null), or if it's a whole-package
+                    // enable/disable event (cmpList is just the package name itself), drop
+                    // our carrier privileged app & system-app caches and let them refresh
+                    if (cmpList == null
+                            || (cmpList.length == 1 && pkgName.equals(cmpList[0]))) {
+                        clearCarrierPrivilegedApps();
+                    }
+                } break;
+                case Intent.ACTION_PACKAGE_FULLY_REMOVED: {
+                    final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+                    final Uri data = intent.getData();
+                    String ssp;
+                    if (uid >= 0 && data != null
+                            && (ssp = data.getSchemeSpecificPart()) != null) {
+                        onPackageRemoved(ssp, uid);
+                    }
+                } break;
+                case Intent.ACTION_UID_REMOVED: {
+                    if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                        final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
+                        if (uid >= 0) {
+                            onUidRemoved(uid);
+                        }
+                    }
+                } break;
+                case Intent.ACTION_USER_ADDED: {
+                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                    if (userId >= 0) {
+                        onUserAdded(userId);
+                    }
+                } break;
+                case Intent.ACTION_USER_STARTED: {
+                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                    if (userId >= 0) {
+                        onUserStarted(userId);
+                    }
+                } break;
+                case Intent.ACTION_USER_STOPPED: {
+                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                    if (userId >= 0) {
+                        onUserStopped(userId);
+                    }
+                } break;
+                case Intent.ACTION_USER_REMOVED: {
+                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                    if (userId >= 0) {
+                        onUserRemoved(userId);
+                    }
+                } break;
+            }
+        }
+    };
+
+    private final BroadcastReceiver mBootReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            switch (intent.getAction()) {
+                case Intent.ACTION_LOCKED_BOOT_COMPLETED: {
+                    onLockedBootCompleted();
+                } break;
+            }
+        }
+    };
+
     /**
      * The restriction levels that each package is on, the levels here are defined in
      * {@link android.app.ActivityManager.RESTRICTION_LEVEL_*}.
      */
     final class RestrictionSettings {
-        @GuardedBy("mLock")
+        @GuardedBy("mSettingsLock")
         final SparseArrayMap<String, PkgSettings> mRestrictionLevels = new SparseArrayMap();
 
         final class PkgSettings {
@@ -283,6 +367,7 @@
                 mCurrentRestrictionLevel = mLastRestrictionLevel = RESTRICTION_LEVEL_UNKNOWN;
             }
 
+            @GuardedBy("mSettingsLock")
             @RestrictionLevel int update(@RestrictionLevel int level, int reason, int subReason) {
                 if (level != mCurrentRestrictionLevel) {
                     mLastRestrictionLevel = mCurrentRestrictionLevel;
@@ -296,6 +381,7 @@
             }
 
             @Override
+            @GuardedBy("mSettingsLock")
             public String toString() {
                 final StringBuilder sb = new StringBuilder(128);
                 sb.append("RestrictionLevel{");
@@ -314,21 +400,23 @@
             }
 
             void dump(PrintWriter pw, @ElapsedRealtimeLong long nowElapsed) {
-                pw.print(toString());
-                if (mLastRestrictionLevel != RESTRICTION_LEVEL_UNKNOWN) {
-                    pw.print('/');
-                    pw.print(ActivityManager.restrictionLevelToName(mLastRestrictionLevel));
-                }
-                pw.print(" levelChange=");
-                TimeUtils.formatDuration(mLevelChangeTimeElapsed - nowElapsed, pw);
-                if (mLastNotificationShownTimeElapsed != null) {
-                    for (int i = 0; i < mLastNotificationShownTimeElapsed.length; i++) {
-                        if (mLastNotificationShownTimeElapsed[i] > 0) {
-                            pw.print(" lastNoti(");
-                            pw.print(mNotificationHelper.notificationTypeToString(i));
-                            pw.print(")=");
-                            TimeUtils.formatDuration(
-                                    mLastNotificationShownTimeElapsed[i] - nowElapsed, pw);
+                synchronized (mSettingsLock) {
+                    pw.print(toString());
+                    if (mLastRestrictionLevel != RESTRICTION_LEVEL_UNKNOWN) {
+                        pw.print('/');
+                        pw.print(ActivityManager.restrictionLevelToName(mLastRestrictionLevel));
+                    }
+                    pw.print(" levelChange=");
+                    TimeUtils.formatDuration(mLevelChangeTimeElapsed - nowElapsed, pw);
+                    if (mLastNotificationShownTimeElapsed != null) {
+                        for (int i = 0; i < mLastNotificationShownTimeElapsed.length; i++) {
+                            if (mLastNotificationShownTimeElapsed[i] > 0) {
+                                pw.print(" lastNoti(");
+                                pw.print(mNotificationHelper.notificationTypeToString(i));
+                                pw.print(")=");
+                                TimeUtils.formatDuration(
+                                        mLastNotificationShownTimeElapsed[i] - nowElapsed, pw);
+                            }
                         }
                     }
                 }
@@ -344,18 +432,22 @@
                 return mUid;
             }
 
+            @GuardedBy("mSettingsLock")
             @RestrictionLevel int getCurrentRestrictionLevel() {
                 return mCurrentRestrictionLevel;
             }
 
+            @GuardedBy("mSettingsLock")
             @RestrictionLevel int getLastRestrictionLevel() {
                 return mLastRestrictionLevel;
             }
 
+            @GuardedBy("mSettingsLock")
             int getReason() {
                 return mReason;
             }
 
+            @GuardedBy("mSettingsLock")
             @ElapsedRealtimeLong long getLastNotificationTime(
                     @NotificationHelper.NotificationType int notificationType) {
                 if (mLastNotificationShownTimeElapsed == null) {
@@ -364,6 +456,7 @@
                 return mLastNotificationShownTimeElapsed[notificationType];
             }
 
+            @GuardedBy("mSettingsLock")
             void setLastNotificationTime(@NotificationHelper.NotificationType int notificationType,
                     @ElapsedRealtimeLong long timestamp) {
                 if (mLastNotificationShownTimeElapsed == null) {
@@ -373,6 +466,7 @@
                 mLastNotificationShownTimeElapsed[notificationType] = timestamp;
             }
 
+            @GuardedBy("mSettingsLock")
             int getNotificationId(@NotificationHelper.NotificationType int notificationType) {
                 if (mNotificationId == null) {
                     return 0;
@@ -380,6 +474,7 @@
                 return mNotificationId[notificationType];
             }
 
+            @GuardedBy("mSettingsLock")
             void setNotificationId(@NotificationHelper.NotificationType int notificationType,
                     int notificationId) {
                 if (mNotificationId == null) {
@@ -396,7 +491,7 @@
          */
         @RestrictionLevel int update(String packageName, int uid, @RestrictionLevel int level,
                 int reason, int subReason) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 PkgSettings settings = getRestrictionSettingsLocked(uid, packageName);
                 if (settings == null) {
                     settings = new PkgSettings(packageName, uid);
@@ -410,7 +505,7 @@
          * @return The reason of why it's in this level.
          */
         int getReason(String packageName, int uid) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 final PkgSettings settings = mRestrictionLevels.get(uid, packageName);
                 return settings != null ? settings.getReason()
                         : (REASON_MAIN_DEFAULT | REASON_SUB_DEFAULT_UNDEFINED);
@@ -418,7 +513,7 @@
         }
 
         @RestrictionLevel int getRestrictionLevel(int uid) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 final int uidKeyIndex = mRestrictionLevels.indexOfKey(uid);
                 if (uidKeyIndex < 0) {
                     return RESTRICTION_LEVEL_UNKNOWN;
@@ -440,7 +535,7 @@
         }
 
         @RestrictionLevel int getRestrictionLevel(int uid, String packageName) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 final PkgSettings settings = getRestrictionSettingsLocked(uid, packageName);
                 return settings == null
                         ? getRestrictionLevel(uid) : settings.getCurrentRestrictionLevel();
@@ -454,14 +549,14 @@
         }
 
         private @RestrictionLevel int getLastRestrictionLevel(int uid, String packageName) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 final PkgSettings settings = mRestrictionLevels.get(uid, packageName);
                 return settings == null
-                        ? RESTRICTION_LEVEL_UNKNOWN : settings.mLastRestrictionLevel;
+                        ? RESTRICTION_LEVEL_UNKNOWN : settings.getLastRestrictionLevel();
             }
         }
 
-        @GuardedBy("mLock")
+        @GuardedBy("mSettingsLock")
         void forEachPackageInUidLocked(int uid,
                 @NonNull TriConsumer<String, Integer, Integer> consumer) {
             final int uidKeyIndex = mRestrictionLevels.indexOfKey(uid);
@@ -476,20 +571,20 @@
             }
         }
 
-        @GuardedBy("mLock")
+        @GuardedBy("mSettingsLock")
         void forEachUidLocked(@NonNull Consumer<Integer> consumer) {
             for (int i = mRestrictionLevels.numMaps() - 1; i >= 0; i--) {
                 consumer.accept(mRestrictionLevels.keyAt(i));
             }
         }
 
-        @GuardedBy("mLock")
+        @GuardedBy("mSettingsLock")
         PkgSettings getRestrictionSettingsLocked(int uid, String packageName) {
             return mRestrictionLevels.get(uid, packageName);
         }
 
         void removeUser(@UserIdInt int userId) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 for (int i = mRestrictionLevels.numMaps() - 1; i >= 0; i--) {
                     final int uid = mRestrictionLevels.keyAt(i);
                     if (UserHandle.getUserId(uid) != userId) {
@@ -501,28 +596,29 @@
         }
 
         void removePackage(String pkgName, int uid) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 mRestrictionLevels.delete(uid, pkgName);
             }
         }
 
         void removeUid(int uid) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 mRestrictionLevels.delete(uid);
             }
         }
 
         @VisibleForTesting
         void reset() {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 mRestrictionLevels.clear();
             }
         }
 
-        @GuardedBy("mLock")
-        void dumpLocked(PrintWriter pw, String prefix) {
+        void dump(PrintWriter pw, String prefix) {
             final ArrayList<PkgSettings> settings = new ArrayList<>();
-            mRestrictionLevels.forEach(setting -> settings.add(setting));
+            synchronized (mSettingsLock) {
+                mRestrictionLevels.forEach(setting -> settings.add(setting));
+            }
             Collections.sort(settings, Comparator.comparingInt(PkgSettings::getUid));
             final long nowElapsed = SystemClock.elapsedRealtime();
             for (int i = 0, size = settings.size(); i < size; i++) {
@@ -553,6 +649,13 @@
                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "abusive_notification_minimal_interval";
 
         /**
+         * The minimal interval in ms before posting a notification again on long running FGS
+         * from a certain package.
+         */
+        static final String KEY_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL =
+                DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "long_fgs_notification_minimal_interval";
+
+        /**
          * The behavior for an app with a FGS and its notification is still showing, when the system
          * detects it's abusive and should be put into bg restricted level. {@code true} - we'll
          * show the prompt to user, {@code false} - we'll not show it.
@@ -566,8 +669,20 @@
         static final String KEY_BG_RESTRICTION_EXEMPTED_PACKAGES =
                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "restriction_exempted_packages";
 
+        /**
+         * Default value to {@link #mBgAutoRestrictedBucket}.
+         */
         static final boolean DEFAULT_BG_AUTO_RESTRICTED_BUCKET_ON_BG_RESTRICTION = false;
-        static final long DEFAULT_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL_MS = 24 * 60 * 60 * 1000;
+
+        /**
+         * Default value to {@link #mBgAbusiveNotificationMinIntervalMs}.
+         */
+        static final long DEFAULT_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL_MS = ONE_DAY;
+
+        /**
+         * Default value to {@link #mBgAbusiveNotificationMinIntervalMs}.
+         */
+        static final long DEFAULT_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL_MS = 30 * ONE_DAY;
 
         /**
          * Default value to {@link #mBgPromptFgsWithNotiToBgRestricted}.
@@ -578,7 +693,9 @@
 
         volatile boolean mRestrictedBucketEnabled;
 
-        volatile long mBgNotificationMinIntervalMs;
+        volatile long mBgAbusiveNotificationMinIntervalMs;
+
+        volatile long mBgLongFgsNotificationMinIntervalMs;
 
         /**
          * @see #KEY_BG_RESTRICTION_EXEMPTED_PACKAGES.
@@ -611,6 +728,9 @@
                     case KEY_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL:
                         updateBgAbusiveNotificationMinimalInterval();
                         break;
+                    case KEY_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL:
+                        updateBgLongFgsNotificationMinimalInterval();
+                        break;
                     case KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_TO_BG_RESTRICTED:
                         updateBgPromptFgsWithNotiToBgRestricted();
                         break;
@@ -648,6 +768,7 @@
         void updateDeviceConfig() {
             updateBgAutoRestrictedBucketChanged();
             updateBgAbusiveNotificationMinimalInterval();
+            updateBgLongFgsNotificationMinimalInterval();
             updateBgPromptFgsWithNotiToBgRestricted();
             updateBgRestrictionExemptedPackages();
         }
@@ -664,12 +785,19 @@
         }
 
         private void updateBgAbusiveNotificationMinimalInterval() {
-            mBgNotificationMinIntervalMs = DeviceConfig.getLong(
+            mBgAbusiveNotificationMinIntervalMs = DeviceConfig.getLong(
                     DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
                     KEY_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL,
                     DEFAULT_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL_MS);
         }
 
+        private void updateBgLongFgsNotificationMinimalInterval() {
+            mBgLongFgsNotificationMinIntervalMs = DeviceConfig.getLong(
+                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                    KEY_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL,
+                    DEFAULT_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL_MS);
+        }
+
         private void updateBgPromptFgsWithNotiToBgRestricted() {
             mBgPromptFgsWithNotiToBgRestricted = DeviceConfig.getBoolean(
                     DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -706,7 +834,11 @@
             pw.print(prefix);
             pw.print(KEY_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL);
             pw.print('=');
-            pw.println(mBgNotificationMinIntervalMs);
+            pw.println(mBgAbusiveNotificationMinIntervalMs);
+            pw.print(prefix);
+            pw.print(KEY_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL);
+            pw.print('=');
+            pw.println(mBgLongFgsNotificationMinIntervalMs);
             pw.print(prefix);
             pw.print(KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_TO_BG_RESTRICTED);
             pw.print('=');
@@ -804,7 +936,7 @@
 
     void onSystemReady() {
         DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
-                ActivityThread.currentApplication().getMainExecutor(), mConstantsObserver);
+                mBgExecutor, mConstantsObserver);
         mConstantsObserver.start();
         initBgRestrictionExemptioFromSysConfig();
         initRestrictionStates();
@@ -826,10 +958,19 @@
 
     @VisibleForTesting
     void resetRestrictionSettings() {
-        mRestrictionSettings.reset();
+        synchronized (mSettingsLock) {
+            mRestrictionSettings.reset();
+        }
         initRestrictionStates();
     }
 
+    @VisibleForTesting
+    void tearDown() {
+        DeviceConfig.removeOnPropertiesChangedListener(mConstantsObserver);
+        unregisterForUidObservers();
+        unregisterForSystemBroadcasts();
+    }
+
     private void initBgRestrictionExemptioFromSysConfig() {
         mBgRestrictionExemptioFromSysConfig =
                 SystemConfig.getInstance().getBgRestrictionExemption();
@@ -912,6 +1053,14 @@
         }
     }
 
+    private void unregisterForUidObservers() {
+        try {
+            mInjector.getIActivityManager().unregisterUidObserver(mUidObserver);
+        } catch (RemoteException e) {
+            // Intra-process call, it won't happen.
+        }
+    }
+
     /**
      * Called when initializing a user.
      */
@@ -1212,9 +1361,7 @@
         prefix = "  " + prefix;
         pw.print(prefix);
         pw.println("BACKGROUND RESTRICTION LEVEL SETTINGS");
-        synchronized (mLock) {
-            mRestrictionSettings.dumpLocked(pw, "  " + prefix);
-        }
+        mRestrictionSettings.dump(pw, "  " + prefix);
         mConstantsObserver.dump(pw, "  " + prefix);
         for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) {
             pw.println();
@@ -1226,7 +1373,7 @@
             int curBucket, boolean allowUpdateBucket, int reason, int subReason) {
         int curLevel;
         int prevReason;
-        synchronized (mLock) {
+        synchronized (mSettingsLock) {
             curLevel = getRestrictionLevel(uid, pkgName);
             if (curLevel == level) {
                 // Nothing to do.
@@ -1264,7 +1411,7 @@
                     || level == RESTRICTION_LEVEL_RESTRICTED_BUCKET)) {
                 // restrict the app if it hasn't done so.
                 boolean doIt = true;
-                synchronized (mLock) {
+                synchronized (mSettingsLock) {
                     final int index = mActiveUids.indexOfKey(uid, pkgName);
                     if (index >= 0) {
                         // It's currently active, enqueue it.
@@ -1282,7 +1429,7 @@
                 && level < RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
             // Moved out of the background-restricted state.
             if (curBucket != STANDBY_BUCKET_RARE) {
-                synchronized (mLock) {
+                synchronized (mSettingsLock) {
                     final int index = mActiveUids.indexOfKey(uid, pkgName);
                     if (index >= 0) {
                         mActiveUids.add(uid, pkgName, null);
@@ -1340,7 +1487,7 @@
     private void dispatchAutoRestrictedBucketFeatureFlagChanged(boolean newValue) {
         final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
         final ArrayList<Runnable> pendingTasks = new ArrayList<>();
-        synchronized (mLock) {
+        synchronized (mSettingsLock) {
             mRestrictionSettings.forEachUidLocked(uid -> {
                 mRestrictionSettings.forEachPackageInUidLocked(uid, (pkgName, level, reason) -> {
                     if (level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
@@ -1434,6 +1581,7 @@
         private final NotificationManager mNotificationManager;
         private final Injector mInjector;
         private final Object mLock;
+        private final Object mSettingsLock;
         private final Context mContext;
 
         private final BroadcastReceiver mActionButtonReceiver = new BroadcastReceiver() {
@@ -1454,7 +1602,7 @@
             }
         };
 
-        @GuardedBy("mLock")
+        @GuardedBy("mSettingsLock")
         private int mNotificationIDStepper = SUMMARY_NOTIFICATION_ID + 1;
 
         NotificationHelper(AppRestrictionController controller) {
@@ -1462,6 +1610,7 @@
             mInjector = controller.mInjector;
             mNotificationManager = mInjector.getNotificationManager();
             mLock = controller.mLock;
+            mSettingsLock = controller.mSettingsLock;
             mContext = mInjector.getContext();
         }
 
@@ -1538,9 +1687,20 @@
                     pendingIntent, packageName, uid, null);
         }
 
+        long getNotificationMinInterval(@NotificationType int notificationType) {
+            switch (notificationType) {
+                case NOTIFICATION_TYPE_ABUSIVE_CURRENT_DRAIN:
+                    return mBgController.mConstantsObserver.mBgAbusiveNotificationMinIntervalMs;
+                case NOTIFICATION_TYPE_LONG_RUNNING_FGS:
+                    return mBgController.mConstantsObserver.mBgLongFgsNotificationMinIntervalMs;
+                default:
+                    return 0L;
+            }
+        }
+
         int getNotificationIdIfNecessary(@NotificationType int notificationType,
                 String packageName, int uid) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 final RestrictionSettings.PkgSettings settings = mBgController.mRestrictionSettings
                         .getRestrictionSettingsLocked(uid, packageName);
                 if (settings == null) {
@@ -1551,7 +1711,7 @@
                 final long lastNotificationShownTimeElapsed =
                         settings.getLastNotificationTime(notificationType);
                 if (lastNotificationShownTimeElapsed != 0 && (lastNotificationShownTimeElapsed
-                        + mBgController.mConstantsObserver.mBgNotificationMinIntervalMs > now)) {
+                        + getNotificationMinInterval(notificationType) > now)) {
                     if (DEBUG_BG_RESTRICTION_CONTROLLER) {
                         Slog.i(TAG, "Not showing notification as last notification was shown "
                                 + TimeUtils.formatDuration(now - lastNotificationShownTimeElapsed)
@@ -1644,7 +1804,7 @@
         }
 
         void cancelRequestBgRestrictedIfNecessary(String packageName, int uid) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 final RestrictionSettings.PkgSettings settings = mBgController.mRestrictionSettings
                         .getRestrictionSettingsLocked(uid, packageName);
                 if (settings != null) {
@@ -1658,7 +1818,7 @@
         }
 
         void cancelLongRunningFGSNotificationIfNecessary(String packageName, int uid) {
-            synchronized (mLock) {
+            synchronized (mSettingsLock) {
                 final RestrictionSettings.PkgSettings settings = mBgController.mRestrictionSettings
                         .getRestrictionSettingsLocked(uid, packageName);
                 if (settings != null) {
@@ -1674,7 +1834,7 @@
 
     void handleUidInactive(int uid, boolean disabled) {
         final ArrayList<Runnable> pendingTasks = mTmpRunnables;
-        synchronized (mLock) {
+        synchronized (mSettingsLock) {
             final int index = mActiveUids.indexOfKey(uid);
             if (index < 0) {
                 return;
@@ -1695,7 +1855,7 @@
     }
 
     void handleUidActive(int uid) {
-        synchronized (mLock) {
+        synchronized (mSettingsLock) {
             final AppStandbyInternal appStandbyInternal = mInjector.getAppStandbyInternal();
             final int userId = UserHandle.getUserId(uid);
             mRestrictionSettings.forEachPackageInUidLocked(uid, (pkgName, level, reason) -> {
@@ -2147,104 +2307,28 @@
     }
 
     private void registerForSystemBroadcasts() {
-        final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String action = intent.getAction();
-                switch (intent.getAction()) {
-                    case Intent.ACTION_PACKAGE_ADDED: {
-                        if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                            final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                            if (uid >= 0) {
-                                onUidAdded(uid);
-                            }
-                        }
-                    }
-                    // fall through.
-                    case Intent.ACTION_PACKAGE_CHANGED: {
-                        final String pkgName = intent.getData().getSchemeSpecificPart();
-                        final String[] cmpList = intent.getStringArrayExtra(
-                                Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
-                        // If this is PACKAGE_ADDED (cmpList == null), or if it's a whole-package
-                        // enable/disable event (cmpList is just the package name itself), drop
-                        // our carrier privileged app & system-app caches and let them refresh
-                        if (cmpList == null
-                                || (cmpList.length == 1 && pkgName.equals(cmpList[0]))) {
-                            clearCarrierPrivilegedApps();
-                        }
-                    } break;
-                    case Intent.ACTION_PACKAGE_FULLY_REMOVED: {
-                        final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                        final Uri data = intent.getData();
-                        String ssp;
-                        if (uid >= 0 && data != null
-                                && (ssp = data.getSchemeSpecificPart()) != null) {
-                            onPackageRemoved(ssp, uid);
-                        }
-                    } break;
-                    case Intent.ACTION_UID_REMOVED: {
-                        if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                            final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                            if (uid >= 0) {
-                                onUidRemoved(uid);
-                            }
-                        }
-                    } break;
-                    case Intent.ACTION_USER_ADDED: {
-                        final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                        if (userId >= 0) {
-                            onUserAdded(userId);
-                        }
-                    } break;
-                    case Intent.ACTION_USER_STARTED: {
-                        final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                        if (userId >= 0) {
-                            onUserStarted(userId);
-                        }
-                    } break;
-                    case Intent.ACTION_USER_STOPPED: {
-                        final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                        if (userId >= 0) {
-                            onUserStopped(userId);
-                        }
-                    } break;
-                    case Intent.ACTION_USER_REMOVED: {
-                        final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                        if (userId >= 0) {
-                            onUserRemoved(userId);
-                        }
-                    } break;
-                }
-            }
-        };
         final IntentFilter packageFilter = new IntentFilter();
         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
         packageFilter.addDataScheme("package");
-        mContext.registerReceiverForAllUsers(broadcastReceiver, packageFilter, null, mBgHandler);
+        mContext.registerReceiverForAllUsers(mBroadcastReceiver, packageFilter, null, mBgHandler);
         final IntentFilter userFilter = new IntentFilter();
         userFilter.addAction(Intent.ACTION_USER_ADDED);
         userFilter.addAction(Intent.ACTION_USER_REMOVED);
         userFilter.addAction(Intent.ACTION_UID_REMOVED);
-        mContext.registerReceiverForAllUsers(broadcastReceiver, userFilter, null, mBgHandler);
-        final BroadcastReceiver bootReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                final String action = intent.getAction();
-                switch (intent.getAction()) {
-                    case Intent.ACTION_LOCKED_BOOT_COMPLETED: {
-                        onLockedBootCompleted();
-                    } break;
-                }
-            }
-        };
+        mContext.registerReceiverForAllUsers(mBroadcastReceiver, userFilter, null, mBgHandler);
         final IntentFilter bootFilter = new IntentFilter();
         bootFilter.addAction(Intent.ACTION_LOCKED_BOOT_COMPLETED);
-        mContext.registerReceiverAsUser(bootReceiver, UserHandle.SYSTEM,
+        mContext.registerReceiverAsUser(mBootReceiver, UserHandle.SYSTEM,
                 bootFilter, null, mBgHandler);
     }
 
+    private void unregisterForSystemBroadcasts() {
+        mContext.unregisterReceiver(mBroadcastReceiver);
+        mContext.unregisterReceiver(mBootReceiver);
+    }
+
     void forEachTracker(Consumer<BaseAppStateTracker> sink) {
         for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) {
             sink.accept(mAppStateTrackers.get(i));
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 86ca699..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.
      */
@@ -1056,7 +1094,9 @@
         if(wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) {
             // Remove any pending compaction we may have scheduled to happen while screen was off
             Slog.e(TAG_AM, "Cancel pending or running compactions as system is awake");
-            mPendingCompactionProcesses.clear();
+            synchronized(mProcLock) {
+                mPendingCompactionProcesses.clear();
+            }
             cancelCompaction();
         }
     }
@@ -1462,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/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
index 6bb5def..bbf5861 100644
--- a/services/core/java/com/android/server/am/HostingRecord.java
+++ b/services/core/java/com/android/server/am/HostingRecord.java
@@ -56,19 +56,27 @@
     private final String mDefiningPackageName;
     private final int mDefiningUid;
     private final boolean mIsTopApp;
+    private final String mDefiningProcessName;
 
     public HostingRecord(String hostingType) {
         this(hostingType, null /* hostingName */, REGULAR_ZYGOTE, null /* definingPackageName */,
-                -1 /* mDefiningUid */, false /* isTopApp */);
+                -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */);
     }
 
     public HostingRecord(String hostingType, ComponentName hostingName) {
         this(hostingType, hostingName, REGULAR_ZYGOTE);
     }
 
+    public HostingRecord(String hostingType, ComponentName hostingName, String definingPackageName,
+            int definingUid, String definingProcessName) {
+        this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, definingPackageName,
+                definingUid, false /* isTopApp */, definingProcessName);
+    }
+
     public HostingRecord(String hostingType, ComponentName hostingName, boolean isTopApp) {
         this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE,
-                null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */);
+                null /* definingPackageName */, -1 /* mDefiningUid */, isTopApp /* isTopApp */,
+                null /* definingProcessName */);
     }
 
     public HostingRecord(String hostingType, String hostingName) {
@@ -81,17 +89,19 @@
 
     private HostingRecord(String hostingType, String hostingName, int hostingZygote) {
         this(hostingType, hostingName, hostingZygote, null /* definingPackageName */,
-                -1 /* mDefiningUid */, false /* isTopApp */);
+                -1 /* mDefiningUid */, false /* isTopApp */, null /* definingProcessName */);
     }
 
     private HostingRecord(String hostingType, String hostingName, int hostingZygote,
-            String definingPackageName, int definingUid, boolean isTopApp) {
+            String definingPackageName, int definingUid, boolean isTopApp,
+            String definingProcessName) {
         mHostingType = hostingType;
         mHostingName = hostingName;
         mHostingZygote = hostingZygote;
         mDefiningPackageName = definingPackageName;
         mDefiningUid = definingUid;
         mIsTopApp = isTopApp;
+        mDefiningProcessName = definingProcessName;
     }
 
     public String getType() {
@@ -127,12 +137,24 @@
     }
 
     /**
+     * Returns the processName of the component we want to start as specified in the defining app's
+     * manifest.
+     *
+     * @return the processName of the process in the hosting application
+     */
+    public String getDefiningProcessName() {
+        return mDefiningProcessName;
+    }
+
+    /**
      * Creates a HostingRecord for a process that must spawn from the webview zygote
      * @param hostingName name of the component to be hosted in this process
      * @return The constructed HostingRecord
      */
-    public static HostingRecord byWebviewZygote(ComponentName hostingName) {
-        return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE);
+    public static HostingRecord byWebviewZygote(ComponentName hostingName,
+            String definingPackageName, int definingUid, String definingProcessName) {
+        return new HostingRecord("", hostingName.toShortString(), WEBVIEW_ZYGOTE,
+                definingPackageName, definingUid, false /* isTopApp */, definingProcessName);
     }
 
     /**
@@ -143,9 +165,9 @@
      * @return The constructed HostingRecord
      */
     public static HostingRecord byAppZygote(ComponentName hostingName, String definingPackageName,
-            int definingUid) {
+            int definingUid, String definingProcessName) {
         return new HostingRecord("", hostingName.toShortString(), APP_ZYGOTE,
-                definingPackageName, definingUid, false /* isTopApp */);
+                definingPackageName, definingUid, false /* isTopApp */, definingProcessName);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 8d77eda..e0d333e 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();
 
@@ -1499,7 +1528,6 @@
         int adj;
         int schedGroup;
         int procState;
-        int cachedAdjSeq;
         int capability = cycleReEval ? app.mState.getCurCapability() : 0;
 
         boolean foregroundActivities = false;
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 763bbee..48ca59d 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -70,7 +70,6 @@
 import android.app.IProcessObserver;
 import android.app.IUidObserver;
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.Disabled;
 import android.compat.annotation.EnabledAfter;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -294,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;
 
@@ -363,59 +359,6 @@
     private static final long LMKD_RECONNECT_DELAY_MS = 1000;
 
     /**
-     * Native heap allocations will now have a non-zero tag in the most significant byte.
-     * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged
-     * Pointers</a>
-     */
-    @ChangeId
-    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
-    private static final long NATIVE_HEAP_POINTER_TAGGING = 135754954; // This is a bug id.
-
-    /**
-     * Native heap allocations in AppZygote process and its descendants will now have a
-     * non-zero tag in the most significant byte.
-     * @see <a href="https://source.android.com/devices/tech/debug/tagged-pointers">Tagged
-     * Pointers</a>
-     */
-    @ChangeId
-    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S)
-    private static final long NATIVE_HEAP_POINTER_TAGGING_APP_ZYGOTE = 207557677;
-
-    /**
-     * Enable asynchronous (ASYNC) memory tag checking in this process. This
-     * flag will only have an effect on hardware supporting the ARM Memory
-     * Tagging Extension (MTE).
-     */
-    @ChangeId
-    @Disabled
-    private static final long NATIVE_MEMTAG_ASYNC = 135772972; // This is a bug id.
-
-    /**
-     * Enable synchronous (SYNC) memory tag checking in this process. This flag
-     * will only have an effect on hardware supporting the ARM Memory Tagging
-     * Extension (MTE). If both NATIVE_MEMTAG_ASYNC and this option is selected,
-     * this option takes preference and MTE is enabled in SYNC mode.
-     */
-    @ChangeId
-    @Disabled
-    private static final long NATIVE_MEMTAG_SYNC = 177438394; // This is a bug id.
-
-    /**
-     * Enable automatic zero-initialization of native heap memory allocations.
-     */
-    @ChangeId
-    @Disabled
-    private static final long NATIVE_HEAP_ZERO_INIT = 178038272; // This is a bug id.
-
-    /**
-     * Enable sampled memory bug detection in the app.
-     * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>.
-     */
-    @ChangeId
-    @Disabled
-    private static final long GWP_ASAN = 135634846; // This is a bug id.
-
-    /**
      * Apps have no access to the private data directories of any other app, even if the other
      * app has made them world-readable.
      */
@@ -1681,136 +1624,6 @@
         return gidArray;
     }
 
-    private int memtagModeToZygoteMemtagLevel(int memtagMode) {
-        switch (memtagMode) {
-            case ApplicationInfo.MEMTAG_ASYNC:
-                return Zygote.MEMORY_TAG_LEVEL_ASYNC;
-            case ApplicationInfo.MEMTAG_SYNC:
-                return Zygote.MEMORY_TAG_LEVEL_SYNC;
-            default:
-                return Zygote.MEMORY_TAG_LEVEL_NONE;
-        }
-    }
-
-    // Returns the requested memory tagging level.
-    private int getRequestedMemtagLevel(ProcessRecord app) {
-        // Look at the process attribute first.
-        if (app.processInfo != null
-                && app.processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) {
-            return memtagModeToZygoteMemtagLevel(app.processInfo.memtagMode);
-        }
-
-        // Then at the application attribute.
-        if (app.info.getMemtagMode() != ApplicationInfo.MEMTAG_DEFAULT) {
-            return memtagModeToZygoteMemtagLevel(app.info.getMemtagMode());
-        }
-
-        if (mPlatformCompat.isChangeEnabled(NATIVE_MEMTAG_SYNC, app.info)) {
-            return Zygote.MEMORY_TAG_LEVEL_SYNC;
-        }
-
-        if (mPlatformCompat.isChangeEnabled(NATIVE_MEMTAG_ASYNC, app.info)) {
-            return Zygote.MEMORY_TAG_LEVEL_ASYNC;
-        }
-
-        // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute.
-        if (!app.info.allowsNativeHeapPointerTagging()) {
-            return Zygote.MEMORY_TAG_LEVEL_NONE;
-        }
-
-        String defaultLevel = SystemProperties.get("persist.arm64.memtag.app_default");
-        if ("sync".equals(defaultLevel)) {
-            return Zygote.MEMORY_TAG_LEVEL_SYNC;
-        } else if ("async".equals(defaultLevel)) {
-            return Zygote.MEMORY_TAG_LEVEL_ASYNC;
-        }
-
-        // Check to see that the compat feature for TBI is enabled.
-        if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
-            return Zygote.MEMORY_TAG_LEVEL_TBI;
-        }
-
-        return Zygote.MEMORY_TAG_LEVEL_NONE;
-    }
-
-    private int decideTaggingLevel(ProcessRecord app) {
-        // Get the desired tagging level (app manifest + compat features).
-        int level = getRequestedMemtagLevel(app);
-
-        // Take into account the hardware capabilities.
-        if (Zygote.nativeSupportsMemoryTagging()) {
-            // MTE devices can not do TBI, because the Zygote process already has live MTE
-            // allocations. Downgrade TBI to NONE.
-            if (level == Zygote.MEMORY_TAG_LEVEL_TBI) {
-                level = Zygote.MEMORY_TAG_LEVEL_NONE;
-            }
-        } else if (Zygote.nativeSupportsTaggedPointers()) {
-            // TBI-but-not-MTE devices downgrade MTE modes to TBI.
-            // The idea is that if an app opts into full hardware tagging (MTE), it must be ok with
-            // the "fake" pointer tagging (TBI).
-            if (level == Zygote.MEMORY_TAG_LEVEL_ASYNC || level == Zygote.MEMORY_TAG_LEVEL_SYNC) {
-                level = Zygote.MEMORY_TAG_LEVEL_TBI;
-            }
-        } else {
-            // Otherwise disable all tagging.
-            level = Zygote.MEMORY_TAG_LEVEL_NONE;
-        }
-
-        return level;
-    }
-
-    private int decideTaggingLevelForAppZygote(ProcessRecord app) {
-        int level = decideTaggingLevel(app);
-        // TBI ("fake" pointer tagging) in AppZygote is controlled by a separate compat feature.
-        if (!mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING_APP_ZYGOTE, app.info)
-                && level == Zygote.MEMORY_TAG_LEVEL_TBI) {
-            level = Zygote.MEMORY_TAG_LEVEL_NONE;
-        }
-        return level;
-    }
-
-    private int decideGwpAsanLevel(ProcessRecord app) {
-        // Look at the process attribute first.
-       if (app.processInfo != null
-                && app.processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) {
-            return app.processInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_ALWAYS
-                    ? Zygote.GWP_ASAN_LEVEL_ALWAYS
-                    : Zygote.GWP_ASAN_LEVEL_NEVER;
-        }
-        // Then at the application attribute.
-        if (app.info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) {
-            return app.info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS
-                    ? Zygote.GWP_ASAN_LEVEL_ALWAYS
-                    : Zygote.GWP_ASAN_LEVEL_NEVER;
-        }
-        // If the app does not specify gwpAsanMode, the default behavior is lottery among the
-        // system apps, and disabled for user apps, unless overwritten by the compat feature.
-        if (mPlatformCompat.isChangeEnabled(GWP_ASAN, app.info)) {
-            return Zygote.GWP_ASAN_LEVEL_ALWAYS;
-        }
-        if ((app.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-            return Zygote.GWP_ASAN_LEVEL_LOTTERY;
-        }
-        return Zygote.GWP_ASAN_LEVEL_NEVER;
-    }
-
-    private boolean enableNativeHeapZeroInit(ProcessRecord app) {
-        // Look at the process attribute first.
-        if (app.processInfo != null
-                && app.processInfo.nativeHeapZeroInitialized != ApplicationInfo.ZEROINIT_DEFAULT) {
-            return app.processInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_ENABLED;
-        }
-        // Then at the application attribute.
-        if (app.info.getNativeHeapZeroInitialized() != ApplicationInfo.ZEROINIT_DEFAULT) {
-            return app.info.getNativeHeapZeroInitialized() == ApplicationInfo.ZEROINIT_ENABLED;
-        }
-        // Compat feature last.
-        if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_ZERO_INIT, app.info)) {
-            return true;
-        }
-        return false;
-    }
-
     /**
      * @return {@code true} if process start is successful, false otherwise.
      */
@@ -1903,7 +1716,13 @@
                 uid = 0;
             }
             int runtimeFlags = 0;
-            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+
+            boolean debuggableFlag = (app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+            if (!debuggableFlag && app.isSdkSandbox) {
+                debuggableFlag = isAppForSdkSandboxDebuggable(app);
+            }
+
+            if (debuggableFlag) {
                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
                 // Also turn on CheckJNI for debuggable apps. It's quite
@@ -1992,8 +1811,6 @@
                 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
             }
 
-            runtimeFlags |= decideGwpAsanLevel(app);
-
             String invokeWith = null;
             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                 // Debuggable apps may include a wrapper script with their library directory.
@@ -2024,23 +1841,21 @@
             app.setRequiredAbi(requiredAbi);
             app.setInstructionSet(instructionSet);
 
-            // If instructionSet is non-null, this indicates that the system_server is spawning a
-            // process with an ISA that may be different from its own. System (kernel and hardware)
-            // compatibility for these features is checked in the decideTaggingLevel in the
-            // system_server process (not the child process). As both MTE and TBI are only supported
-            // in aarch64, we can simply ensure that the new process is also aarch64. This prevents
-            // the mismatch where a 64-bit system server spawns a 32-bit child that thinks it should
-            // enable some tagging variant. Theoretically, a 32-bit system server could exist that
-            // spawns 64-bit processes, in which case the new process won't get any tagging. This is
-            // fine as we haven't seen this configuration in practice, and we can reasonable assume
-            // that if tagging is desired, the system server will be 64-bit.
-            if (instructionSet == null || instructionSet.equals("arm64")) {
-                runtimeFlags |= decideTaggingLevel(app);
+            // If this was an external service, the package name and uid in the passed in
+            // ApplicationInfo have been changed to match those of the calling package;
+            // that will incorrectly apply compat feature overrides for the calling package instead
+            // of the defining one.
+            ApplicationInfo definingAppInfo;
+            if (hostingRecord.getDefiningPackageName() != null) {
+                definingAppInfo = new ApplicationInfo(app.info);
+                definingAppInfo.packageName = hostingRecord.getDefiningPackageName();
+                definingAppInfo.uid = uid;
+            } else {
+                definingAppInfo = app.info;
             }
 
-            if (enableNativeHeapZeroInit(app)) {
-                runtimeFlags |= Zygote.NATIVE_HEAP_ZERO_INIT;
-            }
+            runtimeFlags |= Zygote.getMemorySafetyRuntimeFlags(
+                    definingAppInfo, app.processInfo, instructionSet, mPlatformCompat);
 
             // the per-user SELinux context must be set
             if (TextUtils.isEmpty(app.info.seInfoUser)) {
@@ -2072,6 +1887,25 @@
         }
     }
 
+    /** 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.getAppUidForSdkSandboxUid(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,
             int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
@@ -2299,8 +2133,7 @@
                 // not the calling one.
                 appInfo.packageName = app.getHostingRecord().getDefiningPackageName();
                 appInfo.uid = uid;
-                int runtimeFlags = decideTaggingLevelForAppZygote(app);
-                appZygote = new AppZygote(appInfo, uid, firstUid, lastUid, runtimeFlags);
+                appZygote = new AppZygote(appInfo, app.processInfo, uid, firstUid, lastUid);
                 mAppZygotes.put(app.info.processName, uid, appZygote);
                 zygoteProcessList = new ArrayList<ProcessRecord>();
                 mAppZygoteProcesses.put(appZygote, zygoteProcessList);
@@ -2532,7 +2365,7 @@
     ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
             boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
             int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
-            boolean supplemental, int supplementalUid,
+            boolean isSdkSandbox, int sdkSandboxUid,
             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
         long startTime = SystemClock.uptimeMillis();
         ProcessRecord app;
@@ -2626,8 +2459,8 @@
 
         if (app == null) {
             checkSlow(startTime, "startProcess: creating new process record");
-            app = newProcessRecordLocked(info, processName, isolated, isolatedUid, supplemental,
-                    supplementalUid, hostingRecord);
+            app = newProcessRecordLocked(info, processName, isolated, isolatedUid, isSdkSandbox,
+                    sdkSandboxUid, hostingRecord);
             if (app == null) {
                 Slog.w(TAG, "Failed making new process record for "
                         + processName + "/" + info.uid + " isolated=" + isolated);
@@ -3122,13 +2955,13 @@
 
     @GuardedBy("mService")
     ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
-            boolean isolated, int isolatedUid, boolean supplemental, int supplementalUid,
+            boolean isolated, int isolatedUid, boolean isSdkSandbox, int sdkSandboxUid,
             HostingRecord hostingRecord) {
         String proc = customProcess != null ? customProcess : info.processName;
         final int userId = UserHandle.getUserId(info.uid);
         int uid = info.uid;
-        if (supplemental) {
-            uid = supplementalUid;
+        if (isSdkSandbox) {
+            uid = sdkSandboxUid;
         }
         if (isolated) {
             if (isolatedUid == 0) {
@@ -3158,7 +2991,8 @@
             FrameworkStatsLog.write(FrameworkStatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
                     FrameworkStatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
         }
-        final ProcessRecord r = new ProcessRecord(mService, info, proc, uid);
+        final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
+                hostingRecord.getDefiningUid(), hostingRecord.getDefiningProcessName());
         final ProcessStateRecord state = r.mState;
 
         if (!mService.mBooted && !mService.mBooting
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index be187e2..f7cc3d7 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -79,6 +79,7 @@
     volatile ApplicationInfo info; // all about the first app in the process
     final ProcessInfo processInfo; // if non-null, process-specific manifest info
     final boolean isolated;     // true if this is a special isolated process
+    public final boolean isSdkSandbox; // true if this is an SDK sandbox process
     final boolean appZygote;    // true if this is forked from the app zygote
     final int uid;              // uid of process; may be different from 'info' if isolated
     final int userId;           // user of process.
@@ -492,28 +493,38 @@
 
     ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
             int _uid) {
+        this(_service, _info, _processName, _uid, -1, null);
+    }
+
+    ProcessRecord(ActivityManagerService _service, ApplicationInfo _info, String _processName,
+            int _uid, int _definingUid, String _definingProcessName) {
         mService = _service;
         mProcLock = _service.mProcLock;
         info = _info;
         ProcessInfo procInfo = null;
         if (_service.mPackageManagerInt != null) {
-            ArrayMap<String, ProcessInfo> processes =
-                    _service.mPackageManagerInt.getProcessesForUid(_uid);
-            if (processes != null) {
-                procInfo = processes.get(_processName);
-                if (procInfo != null && procInfo.deniedPermissions == null
-                        && procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
-                        && procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
-                        && procInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_DEFAULT) {
-                    // If this process hasn't asked for permissions to be denied, or for a
-                    // non-default GwpAsan mode, or any other non-default setting, then we don't
-                    // care about it.
-                    procInfo = null;
-                }
+            if (_definingUid > 0) {
+                ArrayMap<String, ProcessInfo> processes =
+                        _service.mPackageManagerInt.getProcessesForUid(_definingUid);
+                if (processes != null) procInfo = processes.get(_definingProcessName);
+            } else {
+                ArrayMap<String, ProcessInfo> processes =
+                        _service.mPackageManagerInt.getProcessesForUid(_uid);
+                if (processes != null) procInfo = processes.get(_processName);
+            }
+            if (procInfo != null && procInfo.deniedPermissions == null
+                    && procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
+                    && procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
+                    && procInfo.nativeHeapZeroInitialized == ApplicationInfo.ZEROINIT_DEFAULT) {
+                // If this process hasn't asked for permissions to be denied, or for a
+                // non-default GwpAsan mode, or any other non-default setting, then we don't
+                // care about it.
+                procInfo = null;
             }
         }
         processInfo = procInfo;
         isolated = Process.isIsolated(_uid);
+        isSdkSandbox = Process.isSdkSandboxUid(_uid);
         appZygote = (UserHandle.getAppId(_uid) >= Process.FIRST_APP_ZYGOTE_ISOLATED_UID
                 && UserHandle.getAppId(_uid) <= Process.LAST_APP_ZYGOTE_ISOLATED_UID);
         uid = _uid;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index bf2876f..c53d4d6 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -94,8 +94,8 @@
     final boolean exported; // from ServiceInfo.exported
     final Runnable restarter; // used to schedule retries of starting the service
     final long createRealTime;  // when this service was created
-    final boolean supplemental; // whether this is a supplemental service
-    final int supplementedAppUid; // the app uid for which this supplemental service is running
+    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 ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
             = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
                             // All active bindings to the service.
@@ -105,7 +105,7 @@
 
     ProcessRecord app;      // where this service is running or null.
     ProcessRecord isolationHostProc; // process which we've started for this service (used for
-                                     // isolated and supplemental processes)
+                                     // isolated and sdk sandbox processes)
     ServiceState tracker; // tracking service execution, may be null
     ServiceState restartTracker; // tracking service restart
     boolean allowlistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
@@ -579,7 +579,7 @@
     ServiceRecord(ActivityManagerService ams, ComponentName name,
             ComponentName instanceName, String definingPackageName, int definingUid,
             Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
-            Runnable restarter, String supplementalProcessName, int supplementedAppUid) {
+            Runnable restarter, String sdkSandboxProcessName, int sdkSandboxClientAppUid) {
         this.ams = ams;
         this.name = name;
         this.instanceName = instanceName;
@@ -590,12 +590,12 @@
         serviceInfo = sInfo;
         appInfo = sInfo.applicationInfo;
         packageName = sInfo.applicationInfo.packageName;
-        supplemental = supplementalProcessName != null;
-        this.supplementedAppUid = supplementedAppUid;
+        isSdkSandbox = sdkSandboxProcessName != null;
+        this.sdkSandboxClientAppUid = sdkSandboxClientAppUid;
         if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) {
             processName = sInfo.processName + ":" + instanceName.getClassName();
-        } else if (supplementalProcessName != null) {
-            processName = supplementalProcessName;
+        } else if (sdkSandboxProcessName != null) {
+            processName = sdkSandboxProcessName;
         } else {
             processName = sInfo.processName;
         }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index b6801fb..ad17655 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 (!getUserInfo(userId).isManagedProfile()) {
+        if (!mInjector.getUserManager().isCredentialSharedWithParent(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/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index 16d83ec..7a6603d 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -91,8 +91,8 @@
         setCancelable(false);
         Resources res = getContext().getResources();
         // Custom view due to alignment and font size requirements
-        View view = LayoutInflater.from(getContext()).inflate(R.layout.user_switching_dialog,
-            null);
+        TextView view = (TextView) LayoutInflater.from(getContext()).inflate(
+                R.layout.user_switching_dialog, null);
 
         String viewMessage = null;
         if (UserManager.isSplitSystemUser() && mNewUser.id == UserHandle.USER_SYSTEM) {
@@ -115,9 +115,12 @@
             if (viewMessage == null) {
                 viewMessage = res.getString(R.string.user_switching_message, mNewUser.name);
             }
+
+            view.setCompoundDrawablesWithIntrinsicBounds(null,
+                    getContext().getDrawable(R.drawable.ic_swap_horiz), null, null);
         }
         view.setAccessibilityPaneTitle(viewMessage);
-        ((TextView) view.findViewById(R.id.message)).setText(viewMessage);
+        view.setText(viewMessage);
         setView(view);
     }
 
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index b813bc4..4fa1ba1 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -90,6 +90,7 @@
 import com.android.internal.compat.CompatibilityOverrideConfig;
 import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
@@ -268,16 +269,34 @@
                     break;
                 }
                 case SET_GAME_STATE: {
-                    if (mPowerManagerInternal == null) {
-                        final Bundle data = msg.getData();
-                        Slog.d(TAG, "Error setting loading mode for package "
-                                + data.getString(PACKAGE_NAME_MSG_KEY)
-                                + " and userId " + data.getInt(USER_ID_MSG_KEY));
-                        break;
-                    }
                     final GameState gameState = (GameState) msg.obj;
                     final boolean isLoading = gameState.isLoading();
-                    mPowerManagerInternal.setPowerMode(Mode.GAME_LOADING, isLoading);
+                    final Bundle data = msg.getData();
+                    final String packageName = data.getString(PACKAGE_NAME_MSG_KEY);
+                    final int userId = data.getInt(USER_ID_MSG_KEY);
+
+                    // Restrict to games only. Requires performance mode to be enabled.
+                    final boolean boostEnabled =
+                            getGameMode(packageName, userId) == GameManager.GAME_MODE_PERFORMANCE;
+                    int uid;
+                    try {
+                        uid = mPackageManager.getPackageUidAsUser(packageName, userId);
+                    } catch (NameNotFoundException e) {
+                        Slog.v(TAG, "Failed to get package metadata");
+                        uid = -1;
+                    }
+                    FrameworkStatsLog.write(FrameworkStatsLog.GAME_STATE_CHANGED, packageName, uid,
+                            boostEnabled, gameStateModeToStatsdGameState(gameState.getMode()),
+                            isLoading, gameState.getLabel(), gameState.getQuality());
+
+                    if (boostEnabled) {
+                        if (mPowerManagerInternal == null) {
+                            Slog.d(TAG, "Error setting loading mode for package " + packageName
+                                    + " and userId " + userId);
+                            break;
+                        }
+                        mPowerManagerInternal.setPowerMode(Mode.GAME_LOADING, isLoading);
+                    }
                     break;
                 }
             }
@@ -340,6 +359,7 @@
     public enum FrameRate {
         FPS_DEFAULT(0),
         FPS_30(30),
+        FPS_40(40),
         FPS_45(45),
         FPS_60(60),
         FPS_90(90),
@@ -359,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":
@@ -387,12 +409,6 @@
             // Restrict to games only.
             return;
         }
-
-        if (getGameMode(packageName, userId) != GameManager.GAME_MODE_PERFORMANCE) {
-            // Requires performance mode to be enabled.
-            return;
-        }
-
         final Message msg = mHandler.obtainMessage(SET_GAME_STATE);
         final Bundle data = new Bundle();
         data.putString(PACKAGE_NAME_MSG_KEY, packageName);
@@ -1307,15 +1323,26 @@
         // Make sure after resetting the game mode is still supported.
         // If not, set the game mode to standard
         int gameMode = getGameMode(packageName, userId);
-        int newGameMode = gameMode;
 
         GamePackageConfiguration config = null;
         synchronized (mOverrideConfigLock) {
             config = mOverrideConfigs.get(packageName);
         }
-        synchronized (mDeviceConfigLock) {
-            config = mConfigs.get(packageName);
+        if (config == null) {
+            synchronized (mDeviceConfigLock) {
+                config = mConfigs.get(packageName);
+            }
         }
+        final int newGameMode = getNewGameMode(gameMode, config);
+        if (gameMode != newGameMode) {
+            setGameMode(packageName, GameManager.GAME_MODE_STANDARD, userId);
+            return;
+        }
+        setGameMode(packageName, gameMode, userId);
+    }
+
+    private int getNewGameMode(int gameMode, GamePackageConfiguration config) {
+        int newGameMode = gameMode;
         if (config != null) {
             int modesBitfield = config.getAvailableGameModesBitfield();
             // Remove UNSUPPORTED to simplify the logic here, since we really just
@@ -1337,11 +1364,7 @@
             // UNSUPPORTED, then set to UNSUPPORTED
             newGameMode = GameManager.GAME_MODE_UNSUPPORTED;
         }
-        if (gameMode != newGameMode) {
-            setGameMode(packageName, GameManager.GAME_MODE_STANDARD, userId);
-            return;
-        }
-        setGameMode(packageName, gameMode, userId);
+        return newGameMode;
     }
 
     /**
@@ -1399,7 +1422,6 @@
             }
             for (final String packageName : packageNames) {
                 int gameMode = getGameMode(packageName, userId);
-                int newGameMode = gameMode;
                 // Make sure the user settings and package configs don't conflict.
                 // I.e. the user setting is set to a mode that no longer available due to
                 // config/manifest changes.
@@ -1408,27 +1430,7 @@
                 synchronized (mDeviceConfigLock) {
                     config = mConfigs.get(packageName);
                 }
-                if (config != null) {
-                    int modesBitfield = config.getAvailableGameModesBitfield();
-                    // Remove UNSUPPORTED to simplify the logic here, since we really just
-                    // want to check if we support selectable game modes
-                    modesBitfield &= ~modeToBitmask(GameManager.GAME_MODE_UNSUPPORTED);
-                    if (!bitFieldContainsModeBitmask(modesBitfield, gameMode)) {
-                        if (bitFieldContainsModeBitmask(modesBitfield,
-                                GameManager.GAME_MODE_STANDARD)) {
-                            // If the current set mode isn't supported,
-                            // but we support STANDARD, then set the mode to STANDARD.
-                            newGameMode = GameManager.GAME_MODE_STANDARD;
-                        } else {
-                            // If we don't support any game modes, then set to UNSUPPORTED
-                            newGameMode = GameManager.GAME_MODE_UNSUPPORTED;
-                        }
-                    }
-                } else if (gameMode != GameManager.GAME_MODE_UNSUPPORTED) {
-                    // If we have no config for the package, but the configured mode is not
-                    // UNSUPPORTED, then set to UNSUPPORTED
-                    newGameMode = GameManager.GAME_MODE_UNSUPPORTED;
-                }
+                final int newGameMode = getNewGameMode(gameMode, config);
                 if (newGameMode != gameMode) {
                     setGameMode(packageName, newGameMode, userId);
                 }
@@ -1543,6 +1545,22 @@
         return out.toString();
     }
 
+    private static int gameStateModeToStatsdGameState(int mode) {
+        switch (mode) {
+            case GameState.MODE_NONE:
+                return FrameworkStatsLog.GAME_STATE_CHANGED__STATE__MODE_NONE;
+            case GameState.MODE_GAMEPLAY_INTERRUPTIBLE:
+                return FrameworkStatsLog.GAME_STATE_CHANGED__STATE__MODE_GAMEPLAY_INTERRUPTIBLE;
+            case GameState.MODE_GAMEPLAY_UNINTERRUPTIBLE:
+                return FrameworkStatsLog.GAME_STATE_CHANGED__STATE__MODE_GAMEPLAY_UNINTERRUPTIBLE;
+            case GameState.MODE_CONTENT:
+                return FrameworkStatsLog.GAME_STATE_CHANGED__STATE__MODE_CONTENT;
+            case GameState.MODE_UNKNOWN:
+            default:
+                return FrameworkStatsLog.GAME_STATE_CHANGED__STATE__MODE_UNKNOWN;
+        }
+    }
+
     private static ServiceThread createServiceThread() {
         ServiceThread handlerThread = new ServiceThread(TAG,
                 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
index 0abab6a..b0a389d 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java
@@ -29,6 +29,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;
@@ -55,7 +56,8 @@
                 (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 e8d9dad..faf5c38 100644
--- a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
+++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java
@@ -29,7 +29,10 @@
 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;
@@ -45,11 +48,15 @@
 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;
@@ -58,12 +65,47 @@
 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";
     private static final int CREATE_GAME_SESSION_TIMEOUT_MS = 10_000;
     private static final boolean DEBUG = false;
 
+    private final ServiceLifecycleCallbacks<IGameService> mGameServiceLifecycleCallbacks =
+            new ServiceLifecycleCallbacks<IGameService>() {
+                @Override
+                public void onConnected(@NonNull IGameService service) {
+                    try {
+                        service.connected(mGameServiceController);
+                    } catch (RemoteException ex) {
+                        Slog.w(TAG, "Failed to send connected event", ex);
+                    }
+                }
+
+                @Override
+                public void onDisconnected(@NonNull IGameService service) {
+                    try {
+                        service.disconnected();
+                    } catch (RemoteException ex) {
+                        Slog.w(TAG, "Failed to send disconnected event", ex);
+                    }
+                }
+            };
+
+    private final ServiceLifecycleCallbacks<IGameSessionService>
+            mGameSessionServiceLifecycleCallbacks =
+            new ServiceLifecycleCallbacks<IGameSessionService>() {
+                @Override
+                public void onBinderDied() {
+                    mBackgroundExecutor.execute(() -> {
+                        synchronized (mLock) {
+                            destroyAndClearAllGameSessionsLocked();
+                        }
+                    });
+                }
+            };
+
     private final TaskSystemBarsListener mTaskSystemBarsVisibilityListener =
             new TaskSystemBarsListener() {
                 @Override
@@ -153,6 +195,7 @@
     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;
 
@@ -172,7 +215,8 @@
             @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;
@@ -183,6 +227,7 @@
         mWindowManagerInternal = windowManagerInternal;
         mGameServiceConnector = gameServiceConnector;
         mGameSessionServiceConnector = gameSessionServiceConnector;
+        mScreenshotHelper = screenshotHelper;
     }
 
     @Override
@@ -206,11 +251,11 @@
         }
         mIsRunning = true;
 
-        // TODO(b/204503192): In cases where the connection to the game service fails retry with
-        //  back off mechanism.
-        AndroidFuture<Void> unusedPostConnectedFuture = mGameServiceConnector.post(gameService -> {
-            gameService.connected(mGameServiceController);
-        });
+        mGameServiceConnector.setServiceLifecycleCallbacks(mGameServiceLifecycleCallbacks);
+        mGameSessionServiceConnector.setServiceLifecycleCallbacks(
+                mGameSessionServiceLifecycleCallbacks);
+
+        AndroidFuture<?> unusedConnectFuture = mGameServiceConnector.connect();
 
         try {
             mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
@@ -237,19 +282,14 @@
         mWindowManagerInternal.unregisterTaskSystemBarsListener(
                 mTaskSystemBarsVisibilityListener);
 
-        for (GameSessionRecord gameSessionRecord : mGameSessions.values()) {
-            destroyGameSessionFromRecordLocked(gameSessionRecord);
-        }
-        mGameSessions.clear();
+        destroyAndClearAllGameSessionsLocked();
 
-        // TODO(b/204503192): It is possible that the game service is disconnected. In this
-        //  case we should avoid rebinding just to shut it down again.
-        mGameServiceConnector.post(gameService -> {
-            gameService.disconnected();
-        }).whenComplete((result, t) -> {
-            mGameServiceConnector.unbind();
-        });
+        mGameServiceConnector.unbind();
         mGameSessionServiceConnector.unbind();
+
+        mGameServiceConnector.setServiceLifecycleCallbacks(null);
+        mGameSessionServiceConnector.setServiceLifecycleCallbacks(null);
+
     }
 
     private void onTaskCreated(int taskId, @NonNull ComponentName componentName) {
@@ -488,6 +528,14 @@
                         createGameSessionResult.getSurfacePackage()));
     }
 
+    @GuardedBy("mLock")
+    private void destroyAndClearAllGameSessionsLocked() {
+        for (GameSessionRecord gameSessionRecord : mGameSessions.values()) {
+            destroyGameSessionFromRecordLocked(gameSessionRecord);
+        }
+        mGameSessions.clear();
+    }
+
     private void destroyGameSessionDuringAttach(
             int taskId,
             CreateGameSessionResult createGameSessionResult) {
@@ -544,9 +592,7 @@
                 Slog.d(TAG, "No active game sessions. Disconnecting GameSessionService");
             }
 
-            if (mGameSessionServiceConnector != null) {
-                mGameSessionServiceConnector.unbind();
-            }
+            mGameSessionServiceConnector.unbind();
         }
     }
 
@@ -615,7 +661,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/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index e2d00f7..361629b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -113,7 +113,6 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.PermissionInfo;
 import android.content.pm.UserInfo;
-import com.android.server.pm.pkg.component.ParsedAttribution;
 import android.database.ContentObserver;
 import android.hardware.camera2.CameraDevice.CAMERA_AUDIO_RESTRICTION;
 import android.net.Uri;
@@ -178,6 +177,8 @@
 import com.android.server.SystemServiceManager;
 import com.android.server.pm.PackageList;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.component.ParsedAttribution;
+import com.android.server.policy.AppOpsPolicy;
 
 import dalvik.annotation.optimization.NeverCompile;
 
@@ -4551,15 +4552,16 @@
             return new PackageVerificationResult(null,
                     /* isAttributionTagValid */ true);
         }
-        if (Process.isSupplemental(uid)) {
-            // Supplemental processes run in their own UID range, but their associated
-            // UID for checks should always be the UID of the supplemental package.
+        if (Process.isSdkSandboxUid(uid)) {
+            // SDK sandbox processes run in their own UID range, but their associated
+            // UID for checks should always be the UID of the package implementing SDK sandbox
+            // service.
             // TODO: We will need to modify the callers of this function instead, so
             // modifications and checks against the app ops state are done with the
             // correct UID.
             try {
                 final PackageManager pm = mContext.getPackageManager();
-                final String supplementalPackageName = pm.getSupplementalProcessPackageName();
+                final String supplementalPackageName = pm.getSdkSandboxPackageName();
                 if (Objects.equals(packageName, supplementalPackageName)) {
                     int supplementalAppId = pm.getPackageUid(supplementalPackageName,
                             PackageManager.PackageInfoFlags.of(0));
@@ -6230,8 +6232,8 @@
                 }
             }
             if (mAudioRestrictionManager.hasActiveRestrictions() && dumpOp < 0
-                    && dumpPackage != null && dumpMode < 0 && !dumpWatchers && !dumpWatchers) {
-                needSep = mAudioRestrictionManager.dump(pw) | needSep ;
+                    && dumpPackage != null && dumpMode < 0 && !dumpWatchers) {
+                needSep = mAudioRestrictionManager.dump(pw) || needSep;
             }
             if (needSep) {
                 pw.println();
@@ -6507,6 +6509,17 @@
                     ipw.decreaseIndent();
                 }
             }
+
+            if (!dumpHistory && !dumpWatchers) {
+                pw.println();
+                if (mCheckOpsDelegateDispatcher.mPolicy != null
+                        && mCheckOpsDelegateDispatcher.mPolicy instanceof AppOpsPolicy) {
+                    AppOpsPolicy policy = (AppOpsPolicy) mCheckOpsDelegateDispatcher.mPolicy;
+                    policy.dumpTags(pw);
+                } else {
+                    pw.println("  AppOps policy not set.");
+                }
+            }
         }
 
         // Must not hold the appops lock
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index daf3561..270a61b 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -396,7 +396,8 @@
             AudioAttributes attr =
                     AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
                             AudioSystem.STREAM_VOICE_CALL);
-            List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(attr);
+            List<AudioDeviceAttributes> devices = AudioSystem.getDevicesForAttributes(
+                    attr, false /* forVolume */);
             if (devices.isEmpty()) {
                 if (mAudioService.isPlatformVoice()) {
                     Log.w(TAG,
@@ -1564,6 +1565,13 @@
 
     private AtomicBoolean mMusicMuted = new AtomicBoolean(false);
 
+    private static <T> boolean hasIntersection(Set<T> a, Set<T> b) {
+        for (T e : a) {
+            if (b.contains(e)) return true;
+        }
+        return false;
+    }
+
     boolean messageMutesMusic(int message) {
         if (message == 0) {
             return false;
@@ -1573,8 +1581,8 @@
                 || message == MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT
                 || message == MSG_L_A2DP_DEVICE_CONFIG_CHANGE)
                 && AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)
-                && mDeviceInventory.DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET.contains(
-                        mAudioService.getDevicesForStream(AudioSystem.STREAM_MUSIC))) {
+                && hasIntersection(mDeviceInventory.DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET,
+                        mAudioService.getDeviceSetForStream(AudioSystem.STREAM_MUSIC))) {
             return false;
         }
         return true;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0b9fb1a..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;
@@ -195,6 +196,7 @@
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -1808,6 +1810,10 @@
      * @param caller caller of this method
      */
     private void updateVolumeStates(int device, int streamType, String caller) {
+        // Handle device volume aliasing of SPEAKER_SAFE.
+        if (device == AudioSystem.DEVICE_OUT_SPEAKER_SAFE) {
+            device = AudioSystem.DEVICE_OUT_SPEAKER;
+        }
         if (!mStreamStates[streamType].hasIndexForDevice(device)) {
             // set the default value, if device is affected by a full/fix/abs volume rule, it
             // will taken into account in checkFixedVolumeDevices()
@@ -1818,8 +1824,10 @@
         }
 
         // Check if device to be updated is routed for the given audio stream
+        // This may include devices such as SPEAKER_SAFE.
         List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
-                new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
+                new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build(),
+                true /* forVolume */);
         for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
             if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
                     device)) {
@@ -2687,7 +2695,7 @@
     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
             @NonNull AudioAttributes attributes) {
         enforceQueryStateOrModifyRoutingPermission();
-        return getDevicesForAttributesInt(attributes);
+        return getDevicesForAttributesInt(attributes, false /* forVolume */);
     }
 
     /** @see AudioManager#getAudioDevicesForAttributes(AudioAttributes)
@@ -2697,7 +2705,7 @@
      */
     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesUnprotected(
             @NonNull AudioAttributes attributes) {
-        return getDevicesForAttributesInt(attributes);
+        return getDevicesForAttributesInt(attributes, false /* forVolume */);
     }
 
     /**
@@ -2719,9 +2727,9 @@
     }
 
     protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
-            @NonNull AudioAttributes attributes) {
+            @NonNull AudioAttributes attributes, boolean forVolume) {
         Objects.requireNonNull(attributes);
-        return mAudioSystem.getDevicesForAttributes(attributes);
+        return mAudioSystem.getDevicesForAttributes(attributes, forVolume);
     }
 
     /** Indicates no special treatment in the handling of the volume adjustement */
@@ -3688,8 +3696,7 @@
 
         int streamType = getBluetoothContextualVolumeStream(newMode);
 
-        final Set<Integer> deviceTypes = AudioSystem.generateAudioDeviceTypesSet(
-                mAudioSystem.getDevicesForStream(streamType));
+        final Set<Integer> deviceTypes = getDeviceSetForStreamDirect(streamType);
         final Set<Integer> absVolumeMultiModeCaseDevices = AudioSystem.intersectionAudioDeviceTypes(
                 mAbsVolumeMultiModeCaseDevices, deviceTypes);
         if (absVolumeMultiModeCaseDevices.isEmpty()) {
@@ -6253,55 +6260,107 @@
         }
     }
 
-    /** only public for mocking/spying, do not call outside of AudioService */
+    /**
+     * Returns device associated with the stream volume.
+     *
+     * Only public for mocking/spying, do not call outside of AudioService.
+     * Device volume aliasing means DEVICE_OUT_SPEAKER may be returned for
+     * DEVICE_OUT_SPEAKER_SAFE.
+     */
     @VisibleForTesting
     public int getDeviceForStream(int stream) {
-        int device = getDevicesForStreamInt(stream);
-        if ((device & (device - 1)) != 0) {
+        return selectOneAudioDevice(getDeviceSetForStream(stream));
+    }
+
+    /*
+     * Must match native apm_extract_one_audio_device() used in getDeviceForVolume()
+     * or the wrong device volume may be adjusted.
+     */
+    private int selectOneAudioDevice(Set<Integer> deviceSet) {
+        if (deviceSet.isEmpty()) {
+            return AudioSystem.DEVICE_NONE;
+        } else if (deviceSet.size() == 1) {
+            return deviceSet.iterator().next();
+        } else {
             // Multiple device selection is either:
             //  - speaker + one other device: give priority to speaker in this case.
             //  - one A2DP device + another device: happens with duplicated output. In this case
             // retain the device on the A2DP output as the other must not correspond to an active
             // selection if not the speaker.
             //  - HDMI-CEC system audio mode only output: give priority to available item in order.
-            // FIXME: Haven't applied audio device type refactor to this API
-            //  as it is going to be deprecated.
-            if ((device & AudioSystem.DEVICE_OUT_SPEAKER) != 0) {
-                device = AudioSystem.DEVICE_OUT_SPEAKER;
-            } else if ((device & AudioSystem.DEVICE_OUT_HDMI_ARC) != 0) {
-                // FIXME(b/184944421): DEVICE_OUT_HDMI_EARC has two bits set,
-                // so it must be handled correctly as it aliases
-                // with DEVICE_OUT_HDMI_ARC | DEVICE_OUT_EARPIECE.
-                device = AudioSystem.DEVICE_OUT_HDMI_ARC;
-            } else if ((device & AudioSystem.DEVICE_OUT_SPDIF) != 0) {
-                device = AudioSystem.DEVICE_OUT_SPDIF;
-            } else if ((device & AudioSystem.DEVICE_OUT_AUX_LINE) != 0) {
-                device = AudioSystem.DEVICE_OUT_AUX_LINE;
+
+            if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER)) {
+                return AudioSystem.DEVICE_OUT_SPEAKER;
+            } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPEAKER_SAFE)) {
+                // Note: DEVICE_OUT_SPEAKER_SAFE not present in getDeviceSetForStreamDirect
+                return AudioSystem.DEVICE_OUT_SPEAKER_SAFE;
+            } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_ARC)) {
+                return AudioSystem.DEVICE_OUT_HDMI_ARC;
+            } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_HDMI_EARC)) {
+                return AudioSystem.DEVICE_OUT_HDMI_EARC;
+            } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_AUX_LINE)) {
+                return AudioSystem.DEVICE_OUT_AUX_LINE;
+            } else if (deviceSet.contains(AudioSystem.DEVICE_OUT_SPDIF)) {
+                return AudioSystem.DEVICE_OUT_SPDIF;
             } else {
-                for (int deviceType : AudioSystem.DEVICE_OUT_ALL_A2DP_SET) {
-                    if ((deviceType & device) == deviceType) {
+                // At this point, deviceSet should contain exactly one A2DP device;
+                // regardless, return the first A2DP device in numeric order.
+                // If there is no A2DP device, this falls through to log an error.
+                for (int deviceType : deviceSet) {
+                    if (AudioSystem.DEVICE_OUT_ALL_A2DP_SET.contains(deviceType)) {
                         return deviceType;
                     }
                 }
             }
         }
-        return device;
+        Log.w(TAG, "selectOneAudioDevice returning DEVICE_NONE from invalid device combination "
+                + AudioSystem.deviceSetToString(deviceSet));
+        return AudioSystem.DEVICE_NONE;
     }
 
     /**
      * @see AudioManager#getDevicesForStream(int)
+     * @deprecated on {@link android.os.Build.VERSION_CODES#T} as new devices
+     *              will have multi-bit device types since S.
+     *              Use {@link #getDevicesForAttributes()} instead.
      */
-    public int getDevicesForStream(int streamType) {
+    @Override
+    @Deprecated
+    public int getDeviceMaskForStream(int streamType) {
         ensureValidStreamType(streamType);
+        // no permission required
         final long token = Binder.clearCallingIdentity();
         try {
-            return mAudioSystem.getDevicesForStream(streamType);
+            return AudioSystem.getDeviceMaskFromSet(
+                    getDeviceSetForStreamDirect(streamType));
         } finally {
             Binder.restoreCallingIdentity(token);
         }
     }
 
-    private int getDevicesForStreamInt(int stream) {
+    /**
+     * Returns the devices associated with a stream type.
+     *
+     * SPEAKER_SAFE will alias to SPEAKER.
+     */
+    @NonNull
+    private Set<Integer> getDeviceSetForStreamDirect(int stream) {
+        final AudioAttributes attr =
+                AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(stream);
+        Set<Integer> deviceSet =
+                AudioSystem.generateAudioDeviceTypesSet(
+                        getDevicesForAttributesInt(attr, true /* forVolume */));
+        return deviceSet;
+    }
+
+    /**
+     * Returns a reference to the list of devices for the stream, do not modify.
+     *
+     * The device returned may be aliased to the actual device whose volume curve
+     * will be used.  For example DEVICE_OUT_SPEAKER_SAFE aliases to DEVICE_OUT_SPEAKER.
+     */
+    @NonNull
+    public Set<Integer> getDeviceSetForStream(int stream) {
         ensureValidStreamType(stream);
         synchronized (VolumeStreamState.class) {
             return mStreamStates[stream].observeDevicesForStream_syncVSS(true);
@@ -6313,11 +6372,10 @@
             synchronized (VolumeStreamState.class) {
                 for (int stream = 0; stream < mStreamStates.length; stream++) {
                     if (stream != skipStream) {
-                        int devices = mStreamStates[stream].observeDevicesForStream_syncVSS(
-                                false /*checkOthers*/);
-
-                        Set<Integer> devicesSet = AudioSystem.generateAudioDeviceTypesSet(devices);
-                        for (Integer device : devicesSet) {
+                        Set<Integer> deviceSet =
+                                mStreamStates[stream].observeDevicesForStream_syncVSS(
+                                        false /*checkOthers*/);
+                        for (Integer device : deviceSet) {
                             // Update volume states for devices routed for the stream
                             updateVolumeStates(device, stream,
                                     "AudioService#onObserveDevicesForAllStreams");
@@ -6490,7 +6548,8 @@
                 .setUsage(AudioAttributes.USAGE_MEDIA)
                 .build();
         // calling getDevice*Int to bypass permission check
-        final List<AudioDeviceAttributes> devices = getDevicesForAttributesInt(attributes);
+        final List<AudioDeviceAttributes> devices =
+                getDevicesForAttributesInt(attributes, true /* forVolume */);
         for (AudioDeviceAttributes device : devices) {
             if (getDeviceVolumeBehaviorInt(device) == AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED) {
                 return true;
@@ -6637,7 +6696,7 @@
                 && DEVICE_MEDIA_UNMUTED_ON_PLUG_SET.contains(newDevice)
                 && mStreamStates[AudioSystem.STREAM_MUSIC].mIsMuted
                 && mStreamStates[AudioSystem.STREAM_MUSIC].getIndex(newDevice) != 0
-                && (newDevice & mAudioSystem.getDevicesForStream(AudioSystem.STREAM_MUSIC)) != 0) {
+                && getDeviceSetForStreamDirect(AudioSystem.STREAM_MUSIC).contains(newDevice)) {
             if (DEBUG_VOL) {
                 Log.i(TAG, String.format("onAccessoryPlugMediaUnmute unmuting device=%d [%s]",
                         newDevice, AudioSystem.getOutputDeviceName(newDevice)));
@@ -7025,7 +7084,7 @@
         private boolean mIsMuted;
         private boolean mIsMutedInternally;
         private String mVolumeIndexSettingName;
-        private int mObservedDevices;
+        @NonNull private Set<Integer> mObservedDeviceSet = new TreeSet<>();
 
         private final SparseIntArray mIndexMap = new SparseIntArray(8) {
             @Override
@@ -7092,17 +7151,30 @@
             }
         }
 
+        /**
+         * Returns a list of devices associated with the stream type.
+         *
+         * This is a reference to the local list, do not modify.
+         */
         @GuardedBy("VolumeStreamState.class")
-        public int observeDevicesForStream_syncVSS(boolean checkOthers) {
+        @NonNull
+        public Set<Integer> observeDevicesForStream_syncVSS(
+                boolean checkOthers) {
             if (!mSystemServer.isPrivileged()) {
-                return AudioSystem.DEVICE_NONE;
+                return new TreeSet<Integer>();
             }
-            final int devices = mAudioSystem.getDevicesForStream(mStreamType);
-            if (devices == mObservedDevices) {
-                return devices;
+            final Set<Integer> deviceSet =
+                    getDeviceSetForStreamDirect(mStreamType);
+            if (deviceSet.equals(mObservedDeviceSet)) {
+                return mObservedDeviceSet;
             }
-            final int prevDevices = mObservedDevices;
-            mObservedDevices = devices;
+
+            // Use legacy bit masks for message signalling.
+            // TODO(b/185386781): message needs update since it uses devices bit-mask.
+            final int devices = AudioSystem.getDeviceMaskFromSet(deviceSet);
+            final int prevDevices = AudioSystem.getDeviceMaskFromSet(mObservedDeviceSet);
+
+            mObservedDeviceSet = deviceSet;
             if (checkOthers) {
                 // one stream's devices have changed, check the others
                 postObserveDevicesForAllStreams(mStreamType);
@@ -7118,7 +7190,7 @@
                     SENDMSG_QUEUE, prevDevices /*arg1*/, devices /*arg2*/,
                     // ok to send reference to this object, it is final
                     mStreamDevicesChanged /*obj*/, 0 /*delay*/);
-            return devices;
+            return mObservedDeviceSet;
         }
 
         public @Nullable String getSettingNameForDevice(int device) {
@@ -7549,19 +7621,7 @@
             }
             pw.println();
             pw.print("   Devices: ");
-            final int devices = getDevicesForStreamInt(mStreamType);
-            int device, i = 0, n = 0;
-            // iterate all devices from 1 to DEVICE_OUT_DEFAULT exclusive
-            // (the default device is not returned by getDevicesForStreamInt)
-            while ((device = 1 << i) != AudioSystem.DEVICE_OUT_DEFAULT) {
-                if ((devices & device) != 0) {
-                    if (n++ > 0) {
-                        pw.print(", ");
-                    }
-                    pw.print(AudioSystem.getOutputDeviceName(device));
-                }
-                i++;
-            }
+            pw.print(AudioSystem.deviceSetToString(getDeviceSetForStream(mStreamType)));
         }
     }
 
@@ -9318,7 +9378,9 @@
                     mDeviceBroker.setForceUse_Async(AudioSystem.FOR_HDMI_SYSTEM_AUDIO, config,
                             "setHdmiSystemAudioSupported");
                 }
-                device = getDevicesForStreamInt(AudioSystem.STREAM_MUSIC);
+                // TODO(b/185386781): Update AudioManager API to use device list.
+                // So far, this value appears to be advisory for debug log.
+                device = getDeviceMaskForStream(AudioSystem.STREAM_MUSIC);
             }
         }
         return device;
@@ -10410,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) {
@@ -11273,6 +11354,7 @@
     @Override
     public void setActiveAssistantServiceUids(int [] activeAssistantUids) {
         enforceModifyAudioRoutingPermission();
+        Objects.requireNonNull(activeAssistantUids);
         synchronized (mSettingsLock) {
             mActiveAssistantServiceUids = activeAssistantUids;
         }
diff --git a/services/core/java/com/android/server/audio/AudioSystemAdapter.java b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
index a70b470..1429b3c 100644
--- a/services/core/java/com/android/server/audio/AudioSystemAdapter.java
+++ b/services/core/java/com/android/server/audio/AudioSystemAdapter.java
@@ -24,12 +24,14 @@
 import android.media.audiopolicy.AudioMix;
 import android.os.SystemClock;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -50,16 +52,14 @@
      * in measured methods
      */
     private static final boolean ENABLE_GETDEVICES_STATS = false;
-    private static final int NB_MEASUREMENTS = 2;
-    private static final int METHOD_GETDEVICESFORSTREAM = 0;
-    private static final int METHOD_GETDEVICESFORATTRIBUTES = 1;
+    private static final int NB_MEASUREMENTS = 1;
+    private static final int METHOD_GETDEVICESFORATTRIBUTES = 0;
     private long[] mMethodTimeNs;
     private int[] mMethodCallCounter;
-    private String[] mMethodNames = {"getDevicesForStream", "getDevicesForAttributes"};
+    private String[] mMethodNames = {"getDevicesForAttributes"};
 
     private static final boolean USE_CACHE_FOR_GETDEVICES = true;
-    private ConcurrentHashMap<Integer, Integer> mDevicesForStreamCache;
-    private ConcurrentHashMap<AudioAttributes, ArrayList<AudioDeviceAttributes>>
+    private ConcurrentHashMap<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>>
             mDevicesForAttrCache;
     private int[] mMethodCacheHit;
     private static final Object sRoutingListenerLock = new Object();
@@ -111,8 +111,6 @@
             sSingletonDefaultAdapter = new AudioSystemAdapter();
             AudioSystem.setRoutingCallback(sSingletonDefaultAdapter);
             if (USE_CACHE_FOR_GETDEVICES) {
-                sSingletonDefaultAdapter.mDevicesForStreamCache =
-                        new ConcurrentHashMap<>(AudioSystem.getNumStreamTypes());
                 sSingletonDefaultAdapter.mDevicesForAttrCache =
                         new ConcurrentHashMap<>(AudioSystem.getNumStreamTypes());
                 sSingletonDefaultAdapter.mMethodCacheHit = new int[NB_MEASUREMENTS];
@@ -129,11 +127,6 @@
         if (DEBUG_CACHE) {
             Log.d(TAG, "---- clearing cache ----------");
         }
-        if (mDevicesForStreamCache != null) {
-            synchronized (mDevicesForStreamCache) {
-                mDevicesForStreamCache.clear();
-            }
-        }
         if (mDevicesForAttrCache != null) {
             synchronized (mDevicesForAttrCache) {
                 mDevicesForAttrCache.clear();
@@ -142,85 +135,33 @@
     }
 
     /**
-     * Same as {@link AudioSystem#getDevicesForStream(int)}
-     * @param stream a valid stream type
-     * @return a mask of device types
-     */
-    public int getDevicesForStream(int stream) {
-        if (!ENABLE_GETDEVICES_STATS) {
-            return getDevicesForStreamImpl(stream);
-        }
-        mMethodCallCounter[METHOD_GETDEVICESFORSTREAM]++;
-        final long startTime = SystemClock.uptimeNanos();
-        final int res = getDevicesForStreamImpl(stream);
-        mMethodTimeNs[METHOD_GETDEVICESFORSTREAM] += SystemClock.uptimeNanos() - startTime;
-        return res;
-    }
-
-    private int getDevicesForStreamImpl(int stream) {
-        if (USE_CACHE_FOR_GETDEVICES) {
-            Integer res;
-            synchronized (mDevicesForStreamCache) {
-                res = mDevicesForStreamCache.get(stream);
-                if (res == null) {
-                    res = AudioSystem.getDevicesForStream(stream);
-                    mDevicesForStreamCache.put(stream, res);
-                    if (DEBUG_CACHE) {
-                        Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORSTREAM]
-                                + streamDeviceToDebugString(stream, res));
-                    }
-                    return res;
-                }
-                // cache hit
-                mMethodCacheHit[METHOD_GETDEVICESFORSTREAM]++;
-                if (DEBUG_CACHE) {
-                    final int real = AudioSystem.getDevicesForStream(stream);
-                    if (res == real) {
-                        Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORSTREAM]
-                                + streamDeviceToDebugString(stream, res) + " CACHE");
-                    } else {
-                        Log.e(TAG, mMethodNames[METHOD_GETDEVICESFORSTREAM]
-                                + streamDeviceToDebugString(stream, res)
-                                + " CACHE ERROR real dev=0x" + Integer.toHexString(real));
-                    }
-                }
-            }
-            return res;
-        }
-        // not using cache
-        return AudioSystem.getDevicesForStream(stream);
-    }
-
-    private static String streamDeviceToDebugString(int stream, int dev) {
-        return " stream=" + stream + " dev=0x" + Integer.toHexString(dev);
-    }
-
-    /**
      * Same as {@link AudioSystem#getDevicesForAttributes(AudioAttributes)}
      * @param attributes the attributes for which the routing is queried
      * @return the devices that the stream with the given attributes would be routed to
      */
     public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
-            @NonNull AudioAttributes attributes) {
+            @NonNull AudioAttributes attributes, boolean forVolume) {
         if (!ENABLE_GETDEVICES_STATS) {
-            return getDevicesForAttributesImpl(attributes);
+            return getDevicesForAttributesImpl(attributes, forVolume);
         }
         mMethodCallCounter[METHOD_GETDEVICESFORATTRIBUTES]++;
         final long startTime = SystemClock.uptimeNanos();
-        final ArrayList<AudioDeviceAttributes> res = getDevicesForAttributesImpl(attributes);
+        final ArrayList<AudioDeviceAttributes> res = getDevicesForAttributesImpl(
+                attributes, forVolume);
         mMethodTimeNs[METHOD_GETDEVICESFORATTRIBUTES] += SystemClock.uptimeNanos() - startTime;
         return res;
     }
 
     private @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesImpl(
-            @NonNull AudioAttributes attributes) {
+            @NonNull AudioAttributes attributes, boolean forVolume) {
         if (USE_CACHE_FOR_GETDEVICES) {
             ArrayList<AudioDeviceAttributes> res;
+            final Pair<AudioAttributes, Boolean> key = new Pair(attributes, forVolume);
             synchronized (mDevicesForAttrCache) {
-                res = mDevicesForAttrCache.get(attributes);
+                res = mDevicesForAttrCache.get(key);
                 if (res == null) {
-                    res = AudioSystem.getDevicesForAttributes(attributes);
-                    mDevicesForAttrCache.put(attributes, res);
+                    res = AudioSystem.getDevicesForAttributes(attributes, forVolume);
+                    mDevicesForAttrCache.put(key, res);
                     if (DEBUG_CACHE) {
                         Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES]
                                 + attrDeviceToDebugString(attributes, res));
@@ -231,7 +172,7 @@
                 mMethodCacheHit[METHOD_GETDEVICESFORATTRIBUTES]++;
                 if (DEBUG_CACHE) {
                     final ArrayList<AudioDeviceAttributes> real =
-                            AudioSystem.getDevicesForAttributes(attributes);
+                            AudioSystem.getDevicesForAttributes(attributes, forVolume);
                     if (res.equals(real)) {
                         Log.d(TAG, mMethodNames[METHOD_GETDEVICESFORATTRIBUTES]
                                 + attrDeviceToDebugString(attributes, res) + " CACHE");
@@ -245,16 +186,13 @@
             return res;
         }
         // not using cache
-        return AudioSystem.getDevicesForAttributes(attributes);
+        return AudioSystem.getDevicesForAttributes(attributes, forVolume);
     }
 
     private static String attrDeviceToDebugString(@NonNull AudioAttributes attr,
-            @NonNull ArrayList<AudioDeviceAttributes> devices) {
-        String ds = " attrUsage=" + attr.getSystemUsage();
-        for (AudioDeviceAttributes ada : devices) {
-            ds = ds.concat(" dev=0x" + Integer.toHexString(ada.getInternalType()));
-        }
-        return ds;
+            @NonNull List<AudioDeviceAttributes> devices) {
+        return " attrUsage=" + attr.getSystemUsage() + " "
+                + AudioSystem.deviceSetToString(AudioSystem.generateAudioDeviceTypesSet(devices));
     }
 
     /**
@@ -514,19 +452,23 @@
      */
     public void dump(PrintWriter pw) {
         pw.println("\nAudioSystemAdapter:");
-        pw.println(" mDevicesForStreamCache:");
-        if (mDevicesForStreamCache != null) {
-            for (Integer stream : mDevicesForStreamCache.keySet()) {
-                pw.println("\t stream:" + stream + " device:"
-                        + AudioSystem.getOutputDeviceName(mDevicesForStreamCache.get(stream)));
-            }
-        }
         pw.println(" mDevicesForAttrCache:");
         if (mDevicesForAttrCache != null) {
-            for (AudioAttributes attr : mDevicesForAttrCache.keySet()) {
-                pw.println("\t" + attr);
-                for (AudioDeviceAttributes devAttr : mDevicesForAttrCache.get(attr)) {
-                    pw.println("\t\t" + devAttr);
+            for (Map.Entry<Pair<AudioAttributes, Boolean>, ArrayList<AudioDeviceAttributes>>
+                    entry : mDevicesForAttrCache.entrySet()) {
+                final AudioAttributes attributes = entry.getKey().first;
+                try {
+                    final int stream = attributes.getVolumeControlStream();
+                    pw.println("\t" + attributes + " forVolume: " + entry.getKey().second
+                            + " stream: "
+                            + AudioSystem.STREAM_NAMES[stream] + "(" + stream + ")");
+                    for (AudioDeviceAttributes devAttr : entry.getValue()) {
+                        pw.println("\t\t" + devAttr);
+                    }
+                } catch (IllegalArgumentException e) {
+                    // dump could fail if attributes do not map to a stream.
+                    pw.println("\t dump failed for attributes: " + attributes);
+                    Log.e(TAG, "dump failed", e);
                 }
             }
         }
@@ -540,7 +482,8 @@
                     + ": counter=" + mMethodCallCounter[i]
                     + " time(ms)=" + (mMethodTimeNs[i] / 1E6)
                     + (USE_CACHE_FOR_GETDEVICES
-                        ? (" FScacheHit=" + mMethodCacheHit[METHOD_GETDEVICESFORSTREAM]) : ""));
+                        ? (" FScacheHit=" + mMethodCacheHit[METHOD_GETDEVICESFORATTRIBUTES])
+                        : ""));
         }
         pw.println("\n");
     }
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 63b27d8..193cc5f 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -264,7 +264,8 @@
             return;
         }
         mState = STATE_DISABLED_UNAVAILABLE;
-        mASA.getDevicesForAttributes(DEFAULT_ATTRIBUTES).toArray(ROUTING_DEVICES);
+        mASA.getDevicesForAttributes(
+                DEFAULT_ATTRIBUTES, false /* forVolume */).toArray(ROUTING_DEVICES);
         // note at this point mSpat is still not instantiated
     }
 
@@ -298,7 +299,8 @@
             case STATE_DISABLED_AVAILABLE:
                 break;
         }
-        mASA.getDevicesForAttributes(DEFAULT_ATTRIBUTES).toArray(ROUTING_DEVICES);
+        mASA.getDevicesForAttributes(
+                DEFAULT_ATTRIBUTES, false /* forVolume */).toArray(ROUTING_DEVICES);
 
         // is media routed to a new device?
         if (isWireless(ROUTING_DEVICES[0].getType())) {
@@ -865,7 +867,8 @@
         }
         AudioDeviceAttributes[] devices = new AudioDeviceAttributes[1];
         // going through adapter to take advantage of routing cache
-        mASA.getDevicesForAttributes(attributes).toArray(devices);
+        mASA.getDevicesForAttributes(
+                attributes, false /* forVolume */).toArray(devices);
         final boolean able = canBeSpatializedOnDevice(attributes, format, devices);
         logd("canBeSpatialized returning " + able);
         return able;
diff --git a/services/core/java/com/android/server/audio/TEST_MAPPING b/services/core/java/com/android/server/audio/TEST_MAPPING
index 5a6c6a5..f3a73f0 100644
--- a/services/core/java/com/android/server/audio/TEST_MAPPING
+++ b/services/core/java/com/android/server/audio/TEST_MAPPING
@@ -8,6 +8,9 @@
                 },
                 {
                     "include-filter": "android.media.audio.cts.AudioFocusTest"
+                },
+                {
+                    "include-filter": "android.media.audio.cts.SpatializerTest"
                 }
             ]
         }
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 79705a3..bf69284 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -20,12 +20,8 @@
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
 import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
-import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT;
+import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
 
-import static com.android.server.biometrics.BiometricServiceStateProto.MULTI_SENSOR_STATE_FACE_SCANNING;
-import static com.android.server.biometrics.BiometricServiceStateProto.MULTI_SENSOR_STATE_FP_SCANNING;
-import static com.android.server.biometrics.BiometricServiceStateProto.MULTI_SENSOR_STATE_SWITCHING;
-import static com.android.server.biometrics.BiometricServiceStateProto.MULTI_SENSOR_STATE_UNKNOWN;
 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTHENTICATED_PENDING_SYSUI;
 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED;
 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE;
@@ -100,14 +96,6 @@
     @Retention(RetentionPolicy.SOURCE)
     @interface SessionState {}
 
-    /** Defined in biometrics.proto */
-    @IntDef({
-            MULTI_SENSOR_STATE_UNKNOWN,
-            MULTI_SENSOR_STATE_FACE_SCANNING,
-            MULTI_SENSOR_STATE_FP_SCANNING})
-    @Retention(RetentionPolicy.SOURCE)
-    @interface MultiSensorState {}
-
     /**
      * Notify the holder of the AuthSession that the caller/client's binder has died. The
      * holder (BiometricService) should schedule {@link AuthSession#onClientDied()} to be run
@@ -119,7 +107,7 @@
 
     private final Context mContext;
     private final IStatusBarService mStatusBarService;
-    private final IBiometricSysuiReceiver mSysuiReceiver;
+    @VisibleForTesting final IBiometricSysuiReceiver mSysuiReceiver;
     private final KeyStore mKeyStore;
     private final Random mRandom;
     private final ClientDeathReceiver mClientDeathReceiver;
@@ -133,7 +121,7 @@
     private final long mRequestId;
     private final long mOperationId;
     private final int mUserId;
-    private final IBiometricSensorReceiver mSensorReceiver;
+    @VisibleForTesting final IBiometricSensorReceiver mSensorReceiver;
     // Original receiver from BiometricPrompt.
     private final IBiometricServiceReceiver mClientReceiver;
     private final String mOpPackageName;
@@ -143,10 +131,10 @@
     // The current state, which can be either idle, called, or started
     private @SessionState int mState = STATE_AUTH_IDLE;
     private @BiometricMultiSensorMode int mMultiSensorMode;
-    private @MultiSensorState int mMultiSensorState;
     private int[] mSensors;
     // TODO(b/197265902): merge into state
     private boolean mCancelled;
+    private int mAuthenticatedSensorId = -1;
     // For explicit confirmation, do not send to keystore until the user has confirmed
     // the authentication.
     private byte[] mTokenEscrow;
@@ -232,8 +220,16 @@
         }
     }
 
-    private void setSensorsToStateWaitingForCookie() throws RemoteException {
+    private void setSensorsToStateWaitingForCookie(boolean isTryAgain) throws RemoteException {
         for (BiometricSensor sensor : mPreAuthInfo.eligibleSensors) {
+            @BiometricSensor.SensorState final int state = sensor.getSensorState();
+            if (isTryAgain
+                    && state != BiometricSensor.STATE_STOPPED
+                    && state != BiometricSensor.STATE_CANCELING) {
+                Slog.d(TAG, "Skip retry because sensor: " + sensor.id + " is: " + state);
+                continue;
+            }
+
             final int cookie = mRandom.nextInt(Integer.MAX_VALUE - 1) + 1;
             final boolean requireConfirmation = isConfirmationRequired(sensor);
 
@@ -254,7 +250,6 @@
             mState = STATE_SHOWING_DEVICE_CREDENTIAL;
             mSensors = new int[0];
             mMultiSensorMode = BIOMETRIC_MULTI_SENSOR_DEFAULT;
-            mMultiSensorState = MULTI_SENSOR_STATE_UNKNOWN;
 
             mStatusBarService.showAuthenticationDialog(
                     mPromptInfo,
@@ -269,7 +264,7 @@
                     mMultiSensorMode);
         } else if (!mPreAuthInfo.eligibleSensors.isEmpty()) {
             // Some combination of biometric or biometric|credential is requested
-            setSensorsToStateWaitingForCookie();
+            setSensorsToStateWaitingForCookie(false /* isTryAgain */);
             mState = STATE_AUTH_CALLED;
         } else {
             // No authenticators requested. This should never happen - an exception should have
@@ -283,6 +278,10 @@
             Slog.w(TAG, "Received cookie but already cancelled (ignoring): " + cookie);
             return;
         }
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onCookieReceived after successful auth");
+            return;
+        }
 
         for (BiometricSensor sensor : mPreAuthInfo.eligibleSensors) {
             sensor.goToStateCookieReturnedIfCookieMatches(cookie);
@@ -307,7 +306,6 @@
                     }
                     mMultiSensorMode = getMultiSensorModeForNewSession(
                             mPreAuthInfo.eligibleSensors);
-                    mMultiSensorState = MULTI_SENSOR_STATE_UNKNOWN;
 
                     mStatusBarService.showAuthenticationDialog(mPromptInfo,
                             mSysuiReceiver,
@@ -381,9 +379,8 @@
         // sending the final error callback to the application.
         for (BiometricSensor sensor : mPreAuthInfo.eligibleSensors) {
             try {
-                final boolean shouldCancel = filter.apply(sensor);
-                Slog.d(TAG, "sensorId: " + sensor.id + ", shouldCancel: " + shouldCancel);
-                if (shouldCancel) {
+                if (filter.apply(sensor)) {
+                    Slog.d(TAG, "Cancelling sensorId: " + sensor.id);
                     sensor.goToStateCancelling(mToken, mOpPackageName, mRequestId);
                 }
             } catch (RemoteException e) {
@@ -412,10 +409,16 @@
             }
         }
 
+        // do not propagate the error and let onAuthenticationSucceeded handle the new state
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onErrorReceived after successful auth (ignoring)");
+            return false;
+        }
+
         mErrorEscrow = error;
         mVendorCodeEscrow = vendorCode;
 
-        final @BiometricAuthenticator.Modality int modality = sensorIdToModality(sensorId);
+        @Modality final int modality = sensorIdToModality(sensorId);
 
         switch (mState) {
             case STATE_AUTH_CALLED: {
@@ -430,7 +433,6 @@
 
                     mState = STATE_SHOWING_DEVICE_CREDENTIAL;
                     mMultiSensorMode = BIOMETRIC_MULTI_SENSOR_DEFAULT;
-                    mMultiSensorState = MULTI_SENSOR_STATE_UNKNOWN;
                     mSensors = new int[0];
 
                     mStatusBarService.showAuthenticationDialog(
@@ -468,12 +470,6 @@
                     return true;
                 } else {
                     mState = STATE_ERROR_PENDING_SYSUI;
-                    if (mMultiSensorMode == BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT
-                            && mMultiSensorState == MULTI_SENSOR_STATE_FACE_SCANNING) {
-                        // wait for the UI to signal when modality should switch
-                        Slog.d(TAG, "onErrorReceived: waiting for modality switch callback");
-                        mMultiSensorState = MULTI_SENSOR_STATE_SWITCHING;
-                    }
                     mStatusBarService.onBiometricError(modality, error, vendorCode);
                 }
                 break;
@@ -505,6 +501,11 @@
     }
 
     void onAcquired(int sensorId, int acquiredInfo, int vendorCode) {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onAcquired after successful auth");
+            return;
+        }
+
         final String message = getAcquiredMessageForSensor(sensorId, acquiredInfo, vendorCode);
         Slog.d(TAG, "sensorId: " + sensorId + " acquiredInfo: " + acquiredInfo
                 + " message: " + message);
@@ -520,6 +521,10 @@
     }
 
     void onSystemEvent(int event) {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onSystemEvent after successful auth");
+            return;
+        }
         if (!mPromptInfo.isReceiveSystemEvents()) {
             return;
         }
@@ -538,53 +543,35 @@
 
         mState = STATE_AUTH_STARTED_UI_SHOWING;
 
-        if (mMultiSensorMode == BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT) {
-            mMultiSensorState = MULTI_SENSOR_STATE_FACE_SCANNING;
-        } else {
-            startFingerprintSensorsNow();
-        }
-    }
-
-    // call anytime after onDialogAnimatedIn() to indicate it's appropriate to start the
-    // fingerprint sensor (i.e. face auth has failed or is not available)
-    void onStartFingerprint() {
-        if (mMultiSensorMode != BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT) {
-            Slog.e(TAG, "onStartFingerprint, unexpected mode: " + mMultiSensorMode);
-            return;
-        }
-
-        if (mState != STATE_AUTH_STARTED
-                && mState != STATE_AUTH_STARTED_UI_SHOWING
-                && mState != STATE_AUTH_PAUSED
-                && mState != STATE_ERROR_PENDING_SYSUI) {
-            Slog.w(TAG, "onStartFingerprint, started from unexpected state: " + mState);
-        }
-
-        mMultiSensorState = MULTI_SENSOR_STATE_FP_SCANNING;
-        startFingerprintSensorsNow();
-    }
-
-    // unguarded helper for the above methods only
-    private void startFingerprintSensorsNow() {
         startAllPreparedFingerprintSensors();
         mState = STATE_AUTH_STARTED_UI_SHOWING;
     }
 
     void onTryAgainPressed() {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onTryAgainPressed after successful auth");
+            return;
+        }
+
         if (mState != STATE_AUTH_PAUSED) {
             Slog.w(TAG, "onTryAgainPressed, state: " + mState);
         }
 
         try {
-            setSensorsToStateWaitingForCookie();
+            setSensorsToStateWaitingForCookie(true /* isTryAgain */);
             mState = STATE_AUTH_PAUSED_RESUMING;
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException: " + e);
         }
     }
 
-    void onAuthenticationSucceeded(int sensorId, boolean strong,
-            byte[] token) {
+    void onAuthenticationSucceeded(int sensorId, boolean strong, byte[] token) {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onAuthenticationSucceeded after successful auth");
+            return;
+        }
+
+        mAuthenticatedSensorId = sensorId;
         if (strong) {
             mTokenEscrow = token;
         } else {
@@ -596,7 +583,7 @@
         try {
             // Notify SysUI that the biometric has been authenticated. SysUI already knows
             // the implicit/explicit state and will react accordingly.
-            mStatusBarService.onBiometricAuthenticated();
+            mStatusBarService.onBiometricAuthenticated(sensorIdToModality(sensorId));
 
             final boolean requireConfirmation = isConfirmationRequiredByAnyEligibleSensor();
 
@@ -609,20 +596,22 @@
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException", e);
         }
+
+        cancelAllSensors(sensor -> sensor.id != sensorId);
     }
 
-    void onAuthenticationRejected() {
-        try {
-            mStatusBarService.onBiometricError(TYPE_NONE,
-                    BiometricConstants.BIOMETRIC_PAUSED_REJECTED, 0 /* vendorCode */);
+    void onAuthenticationRejected(int sensorId) {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onAuthenticationRejected after successful auth");
+            return;
+        }
 
-            // TODO: This logic will need to be updated if BP is multi-modal
-            if (hasPausableBiometric()) {
-                // Pause authentication. onBiometricAuthenticated(false) causes the
-                // dialog to show a "try again" button for passive modalities.
+        try {
+            mStatusBarService.onBiometricError(sensorIdToModality(sensorId),
+                    BiometricConstants.BIOMETRIC_PAUSED_REJECTED, 0 /* vendorCode */);
+            if (pauseSensorIfSupported(sensorId)) {
                 mState = STATE_AUTH_PAUSED;
             }
-
             mClientReceiver.onAuthenticationFailed();
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException", e);
@@ -630,15 +619,34 @@
     }
 
     void onAuthenticationTimedOut(int sensorId, int cookie, int error, int vendorCode) {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onAuthenticationTimedOut after successful auth");
+            return;
+        }
+
         try {
             mStatusBarService.onBiometricError(sensorIdToModality(sensorId), error, vendorCode);
+            pauseSensorIfSupported(sensorId);
             mState = STATE_AUTH_PAUSED;
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException", e);
         }
     }
 
+    private boolean pauseSensorIfSupported(int sensorId) {
+        if (sensorIdToModality(sensorId) == TYPE_FACE) {
+            cancelAllSensors(sensor -> sensor.id == sensorId);
+            return true;
+        }
+        return false;
+    }
+
     void onDeviceCredentialPressed() {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onDeviceCredentialPressed after successful auth");
+            return;
+        }
+
         // Cancel authentication. Skip the token/package check since we are cancelling
         // from system server. The interface is permission protected so this is fine.
         cancelAllSensors();
@@ -666,6 +674,10 @@
         }
     }
 
+    private boolean hasAuthenticated() {
+        return mAuthenticatedSensorId != -1;
+    }
+
     private void logOnDialogDismissed(@BiometricPrompt.DismissedReason int reason) {
         if (reason == BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED) {
             // Explicit auth, authentication confirmed.
@@ -794,6 +806,11 @@
      * @return true if this AuthSession is finished, e.g. should be set to null
      */
     boolean onCancelAuthSession(boolean force) {
+        if (hasAuthenticated()) {
+            Slog.d(TAG, "onCancelAuthSession after successful auth");
+            return true;
+        }
+
         mCancelled = true;
 
         final boolean authStarted = mState == STATE_AUTH_CALLED
@@ -848,15 +865,6 @@
         return remainingCookies == 0;
     }
 
-    private boolean hasPausableBiometric() {
-        for (BiometricSensor sensor : mPreAuthInfo.eligibleSensors) {
-            if (sensor.modality == TYPE_FACE) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     @SessionState int getState() {
         return mState;
     }
@@ -919,7 +927,7 @@
         }
 
         if (hasFace && hasFingerprint) {
-            return BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT;
+            return BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
         }
         return BIOMETRIC_MULTI_SENSOR_DEFAULT;
     }
diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java
index 0333c3e..7166783 100644
--- a/services/core/java/com/android/server/biometrics/BiometricSensor.java
+++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java
@@ -131,8 +131,10 @@
 
     void goToStateCancelling(IBinder token, String opPackageName, long requestId)
             throws RemoteException {
-        impl.cancelAuthenticationFromService(token, opPackageName, requestId);
-        mSensorState = STATE_CANCELING;
+        if (mSensorState != STATE_CANCELING) {
+            impl.cancelAuthenticationFromService(token, opPackageName, requestId);
+            mSensorState = STATE_CANCELING;
+        }
     }
 
     void goToStoppedStateIfCookieMatches(int cookie, int error) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 758cf7a..0d9b754 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -55,7 +55,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -84,6 +83,7 @@
 import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
 
 /**
  * System service that arbitrates the modality for BiometricPrompt to use.
@@ -92,22 +92,6 @@
 
     static final String TAG = "BiometricService";
 
-    private static final int MSG_ON_AUTHENTICATION_SUCCEEDED = 2;
-    private static final int MSG_ON_AUTHENTICATION_REJECTED = 3;
-    private static final int MSG_ON_ERROR = 4;
-    private static final int MSG_ON_ACQUIRED = 5;
-    private static final int MSG_ON_DISMISSED = 6;
-    private static final int MSG_ON_TRY_AGAIN_PRESSED = 7;
-    private static final int MSG_ON_READY_FOR_AUTHENTICATION = 8;
-    private static final int MSG_AUTHENTICATE = 9;
-    private static final int MSG_CANCEL_AUTHENTICATION = 10;
-    private static final int MSG_ON_AUTHENTICATION_TIMED_OUT = 11;
-    private static final int MSG_ON_DEVICE_CREDENTIAL_PRESSED = 12;
-    private static final int MSG_ON_SYSTEM_EVENT = 13;
-    private static final int MSG_CLIENT_DIED = 14;
-    private static final int MSG_ON_DIALOG_ANIMATED_IN = 15;
-    private static final int MSG_ON_START_FINGERPRINT_NOW = 16;
-
     private final Injector mInjector;
     private final DevicePolicyManager mDevicePolicyManager;
     @VisibleForTesting
@@ -116,7 +100,7 @@
     final SettingObserver mSettingObserver;
     private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
     private final Random mRandom = new Random();
-    @NonNull private final AtomicLong mRequestCounter;
+    @NonNull private final Supplier<Long> mRequestCounter;
 
     @VisibleForTesting
     IStatusBarService mStatusBarService;
@@ -128,133 +112,13 @@
     // Get and cache the available biometric authenticators and their associated info.
     final ArrayList<BiometricSensor> mSensors = new ArrayList<>();
 
+    @VisibleForTesting
     BiometricStrengthController mBiometricStrengthController;
 
     // The current authentication session, null if idle/done.
     @VisibleForTesting
-    AuthSession mCurrentAuthSession;
-
-    @VisibleForTesting
-    final Handler mHandler = new Handler(Looper.getMainLooper()) {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_ON_AUTHENTICATION_SUCCEEDED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    handleAuthenticationSucceeded(
-                            args.argi1 /* sensorId */,
-                            (byte[]) args.arg1 /* token */);
-                    args.recycle();
-                    break;
-                }
-
-                case MSG_ON_AUTHENTICATION_REJECTED: {
-                    handleAuthenticationRejected();
-                    break;
-                }
-
-                case MSG_ON_ERROR: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    handleOnError(
-                            args.argi1 /* sensorId */,
-                            args.argi2 /* cookie */,
-                            args.argi3 /* error */,
-                            args.argi4 /* vendorCode */);
-                    args.recycle();
-                    break;
-                }
-
-                case MSG_ON_ACQUIRED: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    handleOnAcquired(
-                            args.argi1 /* sensorId */,
-                            args.argi2 /* acquiredInfo */,
-                            args.argi3 /* vendorCode */);
-                    args.recycle();
-                    break;
-                }
-
-                case MSG_ON_DISMISSED: {
-                    handleOnDismissed(msg.arg1, (byte[]) msg.obj);
-                    break;
-                }
-
-                case MSG_ON_TRY_AGAIN_PRESSED: {
-                    handleOnTryAgainPressed();
-                    break;
-                }
-
-                case MSG_ON_READY_FOR_AUTHENTICATION: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    handleOnReadyForAuthentication(
-                            args.argi1 /* cookie */);
-                    args.recycle();
-                    break;
-                }
-
-                case MSG_AUTHENTICATE: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    handleAuthenticate(
-                            (IBinder) args.arg1 /* token */,
-                            (long) args.arg6 /* requestId */,
-                            (long) args.arg2 /* operationId */,
-                            args.argi1 /* userid */,
-                            (IBiometricServiceReceiver) args.arg3 /* receiver */,
-                            (String) args.arg4 /* opPackageName */,
-                            (PromptInfo) args.arg5 /* promptInfo */);
-                    args.recycle();
-                    break;
-                }
-
-                case MSG_CANCEL_AUTHENTICATION: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    handleCancelAuthentication((long) args.arg3 /* requestId */);
-                    args.recycle();
-                    break;
-                }
-
-                case MSG_ON_AUTHENTICATION_TIMED_OUT: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    handleAuthenticationTimedOut(
-                            args.argi1 /* sensorId */,
-                            args.argi2 /* cookie */,
-                            args.argi3 /* error */,
-                            args.argi4 /* vendorCode */);
-                    args.recycle();
-                    break;
-                }
-
-                case MSG_ON_DEVICE_CREDENTIAL_PRESSED: {
-                    handleOnDeviceCredentialPressed();
-                    break;
-                }
-
-                case MSG_ON_SYSTEM_EVENT: {
-                    handleOnSystemEvent((int) msg.obj);
-                    break;
-                }
-
-                case MSG_CLIENT_DIED: {
-                    handleClientDied();
-                    break;
-                }
-
-                case MSG_ON_DIALOG_ANIMATED_IN: {
-                    handleOnDialogAnimatedIn();
-                    break;
-                }
-
-                case MSG_ON_START_FINGERPRINT_NOW: {
-                    handleOnStartFingerprintNow();
-                    break;
-                }
-
-                default:
-                    Slog.e(TAG, "Unknown message: " + msg);
-                    break;
-            }
-        }
-    };
+    AuthSession mAuthSession;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
 
     /**
      * Tracks authenticatorId invalidation. For more details, see
@@ -552,93 +416,74 @@
     }
 
     // Receives events from individual biometric sensors.
-    @VisibleForTesting
-    final IBiometricSensorReceiver mBiometricSensorReceiver = new IBiometricSensorReceiver.Stub() {
-        @Override
-        public void onAuthenticationSucceeded(int sensorId, byte[] token) {
-            SomeArgs args = SomeArgs.obtain();
-            args.argi1 = sensorId;
-            args.arg1 = token;
-            mHandler.obtainMessage(MSG_ON_AUTHENTICATION_SUCCEEDED, args).sendToTarget();
-        }
-
-        @Override
-        public void onAuthenticationFailed(int sensorId) {
-            Slog.v(TAG, "onAuthenticationFailed");
-            mHandler.obtainMessage(MSG_ON_AUTHENTICATION_REJECTED).sendToTarget();
-        }
-
-        @Override
-        public void onError(int sensorId, int cookie, @BiometricConstants.Errors int error,
-                int vendorCode) {
-            // Determine if error is hard or soft error. Certain errors (such as TIMEOUT) are
-            // soft errors and we should allow the user to try authenticating again instead of
-            // dismissing BiometricPrompt.
-            if (error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT) {
-                SomeArgs args = SomeArgs.obtain();
-                args.argi1 = sensorId;
-                args.argi2 = cookie;
-                args.argi3 = error;
-                args.argi4 = vendorCode;
-                mHandler.obtainMessage(MSG_ON_AUTHENTICATION_TIMED_OUT, args).sendToTarget();
-            } else {
-                SomeArgs args = SomeArgs.obtain();
-                args.argi1 = sensorId;
-                args.argi2 = cookie;
-                args.argi3 = error;
-                args.argi4 = vendorCode;
-                mHandler.obtainMessage(MSG_ON_ERROR, args).sendToTarget();
+    private IBiometricSensorReceiver createBiometricSensorReceiver(final long requestId) {
+        return new IBiometricSensorReceiver.Stub() {
+            @Override
+            public void onAuthenticationSucceeded(int sensorId, byte[] token) {
+                mHandler.post(() -> handleAuthenticationSucceeded(requestId, sensorId, token));
             }
-        }
 
-        @Override
-        public void onAcquired(int sensorId, int acquiredInfo, int vendorCode) {
-            SomeArgs args = SomeArgs.obtain();
-            args.argi1 = sensorId;
-            args.argi2 = acquiredInfo;
-            args.argi3 = vendorCode;
-            mHandler.obtainMessage(MSG_ON_ACQUIRED, args).sendToTarget();
-        }
-    };
+            @Override
+            public void onAuthenticationFailed(int sensorId) {
+                Slog.v(TAG, "onAuthenticationFailed");
+                mHandler.post(() -> handleAuthenticationRejected(requestId, sensorId));
+            }
 
-    final IBiometricSysuiReceiver mSysuiReceiver = new IBiometricSysuiReceiver.Stub() {
-        @Override
-        public void onDialogDismissed(@BiometricPrompt.DismissedReason int reason,
-                @Nullable byte[] credentialAttestation) {
-            mHandler.obtainMessage(MSG_ON_DISMISSED,
-                    reason,
-                    0 /* arg2 */,
-                    credentialAttestation /* obj */).sendToTarget();
-        }
+            @Override
+            public void onError(int sensorId, int cookie, @BiometricConstants.Errors int error,
+                    int vendorCode) {
+                // Determine if error is hard or soft error. Certain errors (such as TIMEOUT) are
+                // soft errors and we should allow the user to try authenticating again instead of
+                // dismissing BiometricPrompt.
+                if (error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT) {
+                    mHandler.post(() -> handleAuthenticationTimedOut(
+                            requestId, sensorId, cookie, error, vendorCode));
+                } else {
+                    mHandler.post(() -> handleOnError(
+                            requestId, sensorId, cookie, error, vendorCode));
+                }
+            }
 
-        @Override
-        public void onTryAgainPressed() {
-            mHandler.sendEmptyMessage(MSG_ON_TRY_AGAIN_PRESSED);
-        }
+            @Override
+            public void onAcquired(int sensorId, int acquiredInfo, int vendorCode) {
+                mHandler.post(() -> handleOnAcquired(
+                        requestId, sensorId, acquiredInfo, vendorCode));
+            }
+        };
+    }
 
-        @Override
-        public void onDeviceCredentialPressed() {
-            mHandler.sendEmptyMessage(MSG_ON_DEVICE_CREDENTIAL_PRESSED);
-        }
+    private IBiometricSysuiReceiver createSysuiReceiver(final long requestId) {
+        return new IBiometricSysuiReceiver.Stub() {
+            @Override
+            public void onDialogDismissed(@BiometricPrompt.DismissedReason int reason,
+                    @Nullable byte[] credentialAttestation) {
+                mHandler.post(() -> handleOnDismissed(requestId, reason, credentialAttestation));
+            }
 
-        @Override
-        public void onSystemEvent(int event) {
-            mHandler.obtainMessage(MSG_ON_SYSTEM_EVENT, event).sendToTarget();
-        }
+            @Override
+            public void onTryAgainPressed() {
+                mHandler.post(() -> handleOnTryAgainPressed(requestId));
+            }
 
-        @Override
-        public void onDialogAnimatedIn() {
-            mHandler.obtainMessage(MSG_ON_DIALOG_ANIMATED_IN).sendToTarget();
-        }
+            @Override
+            public void onDeviceCredentialPressed() {
+                mHandler.post(() -> handleOnDeviceCredentialPressed(requestId));
+            }
 
-        @Override
-        public void onStartFingerprintNow() {
-            mHandler.obtainMessage(MSG_ON_START_FINGERPRINT_NOW).sendToTarget();
-        }
-    };
+            @Override
+            public void onSystemEvent(int event) {
+                mHandler.post(() -> handleOnSystemEvent(requestId, event));
+            }
 
-    private final AuthSession.ClientDeathReceiver mClientDeathReceiver = () -> {
-        mHandler.sendEmptyMessage(MSG_CLIENT_DIED);
+            @Override
+            public void onDialogAnimatedIn() {
+                mHandler.post(() -> handleOnDialogAnimatedIn(requestId));
+            }
+        };
+    }
+
+    private AuthSession.ClientDeathReceiver createClientDeathReceiver(final long requestId) {
+        return () -> mHandler.post(() -> handleClientDied(requestId));
     };
 
     /**
@@ -679,12 +524,10 @@
         }
 
         @Override // Binder call
-        public void onReadyForAuthentication(int cookie) {
+        public void onReadyForAuthentication(long requestId, int cookie) {
             checkInternalPermission();
 
-            SomeArgs args = SomeArgs.obtain();
-            args.argi1 = cookie;
-            mHandler.obtainMessage(MSG_ON_READY_FOR_AUTHENTICATION, args).sendToTarget();
+            mHandler.post(() -> handleOnReadyForAuthentication(requestId, cookie));
         }
 
         @Override // Binder call
@@ -711,18 +554,9 @@
                 }
             }
 
-            final long requestId = mRequestCounter.incrementAndGet();
-
-            SomeArgs args = SomeArgs.obtain();
-            args.arg1 = token;
-            args.arg2 = operationId;
-            args.argi1 = userId;
-            args.arg3 = receiver;
-            args.arg4 = opPackageName;
-            args.arg5 = promptInfo;
-            args.arg6 = requestId;
-
-            mHandler.obtainMessage(MSG_AUTHENTICATE, args).sendToTarget();
+            final long requestId = mRequestCounter.get();
+            mHandler.post(() -> handleAuthenticate(
+                    token, requestId, operationId, userId, receiver, opPackageName, promptInfo));
 
             return requestId;
         }
@@ -736,7 +570,7 @@
             args.arg2 = opPackageName;
             args.arg3 = requestId;
 
-            mHandler.obtainMessage(MSG_CANCEL_AUTHENTICATION, args).sendToTarget();
+            mHandler.post(() -> handleCancelAuthentication(requestId));
         }
 
         @Override // Binder call
@@ -1002,8 +836,7 @@
                     Slog.d(TAG, "ClearSchedulerBuffer: " + clearSchedulerBuffer);
                     final ProtoOutputStream proto = new ProtoOutputStream(fd);
                     proto.write(BiometricServiceStateProto.AUTH_SESSION_STATE,
-                            mCurrentAuthSession != null ? mCurrentAuthSession.getState()
-                                    : STATE_AUTH_IDLE);
+                            mAuthSession != null ? mAuthSession.getState() : STATE_AUTH_IDLE);
                     for (BiometricSensor sensor : mSensors) {
                         byte[] serviceState = sensor.impl
                                 .dumpSensorServiceStateProto(clearSchedulerBuffer);
@@ -1128,8 +961,9 @@
                     CoexCoordinator.FACE_HAPTIC_DISABLE, 1) != 0;
         }
 
-        public AtomicLong getRequestGenerator() {
-            return new AtomicLong(0);
+        public Supplier<Long> getRequestGenerator() {
+            final AtomicLong generator = new AtomicLong(0);
+            return () -> generator.incrementAndGet();
         }
     }
 
@@ -1202,172 +1036,184 @@
         return false;
     }
 
-    private void handleAuthenticationSucceeded(int sensorId, byte[] token) {
+    @Nullable
+    private AuthSession getAuthSessionIfCurrent(long requestId) {
+        final AuthSession session = mAuthSession;
+        if (session != null && session.getRequestId() == requestId) {
+            return session;
+        }
+        return null;
+    }
+
+    private void handleAuthenticationSucceeded(long requestId, int sensorId, byte[] token) {
         Slog.v(TAG, "handleAuthenticationSucceeded(), sensorId: " + sensorId);
         // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
         // after user dismissed/canceled dialog).
-        if (mCurrentAuthSession == null) {
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
             Slog.e(TAG, "handleAuthenticationSucceeded: AuthSession is null");
             return;
         }
 
-        mCurrentAuthSession.onAuthenticationSucceeded(sensorId, isStrongBiometric(sensorId), token);
+        session.onAuthenticationSucceeded(sensorId, isStrongBiometric(sensorId), token);
     }
 
-    private void handleAuthenticationRejected() {
+    private void handleAuthenticationRejected(long requestId, int sensorId) {
         Slog.v(TAG, "handleAuthenticationRejected()");
 
         // Should never happen, log this to catch bad HAL behavior (e.g. auth rejected
         // after user dismissed/canceled dialog).
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleAuthenticationRejected: AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleAuthenticationRejected: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onAuthenticationRejected();
+        session.onAuthenticationRejected(sensorId);
     }
 
-    private void handleAuthenticationTimedOut(int sensorId, int cookie, int error, int vendorCode) {
+    private void handleAuthenticationTimedOut(long requestId, int sensorId, int cookie, int error,
+            int vendorCode) {
         Slog.v(TAG, "handleAuthenticationTimedOut(), sensorId: " + sensorId
                 + ", cookie: " + cookie
                 + ", error: " + error
                 + ", vendorCode: " + vendorCode);
         // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
         // after user dismissed/canceled dialog).
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleAuthenticationTimedOut: AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleAuthenticationTimedOut: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onAuthenticationTimedOut(sensorId, cookie, error, vendorCode);
+        session.onAuthenticationTimedOut(sensorId, cookie, error, vendorCode);
     }
 
-    private void handleOnError(int sensorId, int cookie, @BiometricConstants.Errors int error,
-            int vendorCode) {
+    private void handleOnError(long requestId, int sensorId, int cookie,
+            @BiometricConstants.Errors int error, int vendorCode) {
         Slog.d(TAG, "handleOnError() sensorId: " + sensorId
                 + ", cookie: " + cookie
                 + ", error: " + error
                 + ", vendorCode: " + vendorCode);
 
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleOnError: AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleOnError: AuthSession is not current");
             return;
         }
 
         try {
-            final boolean finished = mCurrentAuthSession
-                    .onErrorReceived(sensorId, cookie, error, vendorCode);
+            final boolean finished = session.onErrorReceived(sensorId, cookie, error, vendorCode);
             if (finished) {
                 Slog.d(TAG, "handleOnError: AuthSession finished");
-                mCurrentAuthSession = null;
+                mAuthSession = null;
             }
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException", e);
         }
     }
 
-    private void handleOnAcquired(int sensorId, int acquiredInfo, int vendorCode) {
+    private void handleOnAcquired(long requestId, int sensorId, int acquiredInfo, int vendorCode) {
         // Should never happen, log this to catch bad HAL behavior (e.g. auth succeeded
         // after user dismissed/canceled dialog).
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "onAcquired: AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "onAcquired: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onAcquired(sensorId, acquiredInfo, vendorCode);
+        session.onAcquired(sensorId, acquiredInfo, vendorCode);
     }
 
-    private void handleOnDismissed(@BiometricPrompt.DismissedReason int reason,
+    private void handleOnDismissed(long requestId, @BiometricPrompt.DismissedReason int reason,
             @Nullable byte[] credentialAttestation) {
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "onDismissed: " + reason + ", AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.e(TAG, "onDismissed: " + reason + ", AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onDialogDismissed(reason, credentialAttestation);
-        mCurrentAuthSession = null;
+        session.onDialogDismissed(reason, credentialAttestation);
+        mAuthSession = null;
     }
 
-    private void handleOnTryAgainPressed() {
+    private void handleOnTryAgainPressed(long requestId) {
         Slog.d(TAG, "onTryAgainPressed");
         // No need to check permission, since it can only be invoked by SystemUI
         // (or system server itself).
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleOnTryAgainPressed: AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleOnTryAgainPressed: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onTryAgainPressed();
+        session.onTryAgainPressed();
     }
 
-    private void handleOnDeviceCredentialPressed() {
+    private void handleOnDeviceCredentialPressed(long requestId) {
         Slog.d(TAG, "onDeviceCredentialPressed");
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleOnDeviceCredentialPressed: AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleOnDeviceCredentialPressed: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onDeviceCredentialPressed();
+        session.onDeviceCredentialPressed();
     }
 
-    private void handleOnSystemEvent(int event) {
+    private void handleOnSystemEvent(long requestId, int event) {
         Slog.d(TAG, "onSystemEvent: " + event);
 
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleOnSystemEvent: AuthSession is null");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleOnSystemEvent: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onSystemEvent(event);
+        session.onSystemEvent(event);
     }
 
-    private void handleClientDied() {
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleClientDied: AuthSession is null");
+    private void handleClientDied(long requestId) {
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleClientDied: AuthSession is not current");
             return;
         }
 
-        Slog.e(TAG, "Session: " + mCurrentAuthSession);
-        final boolean finished = mCurrentAuthSession.onClientDied();
+        Slog.e(TAG, "Session: " + session);
+        final boolean finished = session.onClientDied();
         if (finished) {
-            mCurrentAuthSession = null;
+            mAuthSession = null;
         }
     }
 
-    private void handleOnDialogAnimatedIn() {
+    private void handleOnDialogAnimatedIn(long requestId) {
         Slog.d(TAG, "handleOnDialogAnimatedIn");
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleOnDialogAnimatedIn: AuthSession is null");
+
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleOnDialogAnimatedIn: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onDialogAnimatedIn();
-    }
-
-    private void handleOnStartFingerprintNow() {
-        Slog.d(TAG, "handleOnStartFingerprintNow");
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleOnStartFingerprintNow: AuthSession is null");
-            return;
-        }
-
-        mCurrentAuthSession.onStartFingerprint();
+        session.onDialogAnimatedIn();
     }
 
     /**
      * Invoked when each service has notified that its client is ready to be started. When
      * all biometrics are ready, this invokes the SystemUI dialog through StatusBar.
      */
-    private void handleOnReadyForAuthentication(int cookie) {
-        if (mCurrentAuthSession == null) {
+    private void handleOnReadyForAuthentication(long requestId, int cookie) {
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
             // Only should happen if a biometric was locked out when authenticate() was invoked.
             // In that case, if device credentials are allowed, the UI is already showing. If not
             // allowed, the error has already been returned to the caller.
-            Slog.w(TAG, "handleOnReadyForAuthentication: AuthSession is null");
+            Slog.w(TAG, "handleOnReadyForAuthentication: AuthSession is not current");
             return;
         }
 
-        mCurrentAuthSession.onCookieReceived(cookie);
+        session.onCookieReceived(cookie);
     }
 
     private void handleAuthenticate(IBinder token, long requestId, long operationId, int userId,
@@ -1428,47 +1274,41 @@
 
         // No need to dismiss dialog / send error yet if we're continuing authentication, e.g.
         // "Try again" is showing due to something like ERROR_TIMEOUT.
-        if (mCurrentAuthSession != null) {
+        if (mAuthSession != null) {
             // Forcefully cancel authentication. Dismiss the UI, and immediately send
             // ERROR_CANCELED to the client. Note that we should/will ignore HAL ERROR_CANCELED.
             // Expect to see some harmless "unknown cookie" errors.
-            Slog.w(TAG, "Existing AuthSession: " + mCurrentAuthSession);
-            mCurrentAuthSession.onCancelAuthSession(true /* force */);
-            mCurrentAuthSession = null;
+            Slog.w(TAG, "Existing AuthSession: " + mAuthSession);
+            mAuthSession.onCancelAuthSession(true /* force */);
+            mAuthSession = null;
         }
 
         final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId);
-        mCurrentAuthSession = new AuthSession(getContext(), mStatusBarService, mSysuiReceiver,
-                mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, token, requestId,
-                operationId, userId, mBiometricSensorReceiver, receiver, opPackageName, promptInfo,
-                debugEnabled, mInjector.getFingerprintSensorProperties(getContext()));
+        mAuthSession = new AuthSession(getContext(), mStatusBarService,
+                createSysuiReceiver(requestId), mKeyStore, mRandom,
+                createClientDeathReceiver(requestId), preAuthInfo, token, requestId,
+                operationId, userId, createBiometricSensorReceiver(requestId), receiver,
+                opPackageName, promptInfo, debugEnabled,
+                mInjector.getFingerprintSensorProperties(getContext()));
         try {
-            mCurrentAuthSession.goToInitialState();
+            mAuthSession.goToInitialState();
         } catch (RemoteException e) {
             Slog.e(TAG, "RemoteException", e);
         }
     }
 
     private void handleCancelAuthentication(long requestId) {
-        if (mCurrentAuthSession == null) {
-            Slog.e(TAG, "handleCancelAuthentication: AuthSession is null");
-            return;
-        }
-        if (mCurrentAuthSession.getRequestId() != requestId) {
-            // TODO: actually cancel the operation
-            // This can happen if the operation has been queued, but is cancelled before
-            // it reaches the head of the scheduler. Consider it a programming error for now
-            // and ignore it.
-            Slog.e(TAG, "handleCancelAuthentication: AuthSession mismatch current requestId: "
-                    + mCurrentAuthSession.getRequestId() + " cancel for: " + requestId
-                    + " (ignoring cancellation)");
+        final AuthSession session = getAuthSessionIfCurrent(requestId);
+        if (session == null) {
+            Slog.w(TAG, "handleCancelAuthentication: AuthSession is not current");
+            // TODO: actually cancel the operation?
             return;
         }
 
-        final boolean finished = mCurrentAuthSession.onCancelAuthSession(false /* force */);
+        final boolean finished = session.onCancelAuthSession(false /* force */);
         if (finished) {
             Slog.d(TAG, "handleCancelAuthentication: AuthSession finished");
-            mCurrentAuthSession = null;
+            mAuthSession = null;
         }
     }
 
@@ -1491,7 +1331,7 @@
             pw.println(" " + sensor);
         }
         pw.println();
-        pw.println("CurrentSession: " + mCurrentAuthSession);
+        pw.println("CurrentSession: " + mAuthSession);
         pw.println();
         pw.println("CoexCoordinator: " + CoexCoordinator.getInstance().toString());
         pw.println();
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 54b79e1..6d68772 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -86,6 +86,7 @@
     private long mStartTimeMs;
 
     private boolean mAuthAttempted;
+    private boolean mAuthSuccess = false;
 
     // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update
     //  the state. We should think of a way to improve this in the future.
@@ -237,6 +238,7 @@
                         "Successful background authentication!");
             }
 
+            mAuthSuccess = true;
             markAlreadyDone();
 
             if (mTaskStackListener != null) {
@@ -502,6 +504,11 @@
         return mAuthAttempted;
     }
 
+    /** If an auth attempt completed successfully. */
+    public boolean wasAuthSuccessful() {
+        return mAuthSuccess;
+    }
+
     protected int getShowOverlayReason() {
         if (isKeyguard()) {
             return BiometricOverlayConstants.REASON_AUTH_KEYGUARD;
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 1a6da94..d0ec447 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -316,7 +316,8 @@
             }
         } else {
             try {
-                mBiometricService.onReadyForAuthentication(cookie);
+                mBiometricService.onReadyForAuthentication(
+                        mCurrentOperation.getClientMonitor().getRequestId(), cookie);
             } catch (RemoteException e) {
                 Slog.e(getTag(), "Remote exception when contacting BiometricService", e);
             }
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
index 812ca8a..15f0cad 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java
@@ -84,6 +84,8 @@
     private final BaseClientMonitor mClientMonitor;
     @Nullable
     private final ClientMonitorCallback mClientCallback;
+    @Nullable
+    private ClientMonitorCallback mOnStartCallback;
     @OperationState
     private int mState;
     @VisibleForTesting
@@ -108,7 +110,8 @@
         mCancelWatchdog = () -> {
             if (!isFinished()) {
                 Slog.e(TAG, "[Watchdog Triggered]: " + this);
-                getWrappedCallback().onClientFinished(mClientMonitor, false /* success */);
+                getWrappedCallback(mOnStartCallback)
+                        .onClientFinished(mClientMonitor, false /* success */);
             }
         };
     }
@@ -174,6 +177,7 @@
     }
 
     private boolean doStart(@NonNull ClientMonitorCallback callback) {
+        mOnStartCallback = callback;
         final ClientMonitorCallback cb = getWrappedCallback(callback);
 
         if (mState == STATE_WAITING_IN_QUEUE_CANCELING) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
index f1c786b49..46d863d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java
@@ -123,7 +123,8 @@
         }
     }
 
-    void onRemoved(BiometricAuthenticator.Identifier identifier, int remaining)
+    /** Called when a user has been removed. */
+    public void onRemoved(BiometricAuthenticator.Identifier identifier, int remaining)
             throws RemoteException {
         if (mFaceServiceReceiver != null) {
             mFaceServiceReceiver.onRemoved((Face) identifier, remaining);
diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
index 25d4a38..5aa9b79 100644
--- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
@@ -173,18 +173,13 @@
     }
 
     // SensorType to AuthenticationClient map
-    private final Map<Integer, AuthenticationClient<?>> mClientMap;
-    @VisibleForTesting final LinkedList<SuccessfulAuth> mSuccessfulAuths;
+    private final Map<Integer, AuthenticationClient<?>> mClientMap = new HashMap<>();
+    @VisibleForTesting final LinkedList<SuccessfulAuth> mSuccessfulAuths = new LinkedList<>();
     private boolean mAdvancedLogicEnabled;
     private boolean mFaceHapticDisabledWhenNonBypass;
-    private final Handler mHandler;
+    private final Handler mHandler = new Handler(Looper.getMainLooper());
 
-    private CoexCoordinator() {
-        // Singleton
-        mClientMap = new HashMap<>();
-        mSuccessfulAuths = new LinkedList<>();
-        mHandler = new Handler(Looper.getMainLooper());
-    }
+    private CoexCoordinator() {}
 
     public void addAuthenticationClient(@BiometricScheduler.SensorType int sensorType,
             @NonNull AuthenticationClient<?> client) {
@@ -221,8 +216,14 @@
     public void onAuthenticationSucceeded(long currentTimeMillis,
             @NonNull AuthenticationClient<?> client,
             @NonNull Callback callback) {
+        final boolean isUsingSingleModality = isSingleAuthOnly(client);
+
         if (client.isBiometricPrompt()) {
-            callback.sendHapticFeedback();
+            if (!isUsingSingleModality && hasMultipleSuccessfulAuthentications()) {
+                // only send feedback on the first one
+            } else {
+                callback.sendHapticFeedback();
+            }
             // For BP, BiometricService will add the authToken to Keystore.
             callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
             callback.handleLifecycleAfterAuth();
@@ -234,7 +235,7 @@
             callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
             callback.handleLifecycleAfterAuth();
         } else if (mAdvancedLogicEnabled && client.isKeyguard()) {
-            if (isSingleAuthOnly(client)) {
+            if (isUsingSingleModality) {
                 // Single sensor authentication
                 callback.sendHapticFeedback();
                 callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
@@ -295,10 +296,10 @@
             @NonNull AuthenticationClient<?> client,
             @LockoutTracker.LockoutMode int lockoutMode,
             @NonNull Callback callback) {
-        final boolean keyguardAdvancedLogic = mAdvancedLogicEnabled && client.isKeyguard();
+        final boolean isUsingSingleModality = isSingleAuthOnly(client);
 
-        if (keyguardAdvancedLogic) {
-            if (isSingleAuthOnly(client)) {
+        if (mAdvancedLogicEnabled && client.isKeyguard()) {
+            if (isUsingSingleModality) {
                 callback.sendHapticFeedback();
                 callback.handleLifecycleAfterAuth();
             } else {
@@ -319,8 +320,7 @@
                         // also done now.
                         callback.sendHapticFeedback();
                         callback.handleLifecycleAfterAuth();
-                    }
-                    else {
+                    } else {
                         // UDFPS auth has never been attempted.
                         if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) {
                             Slog.w(TAG, "Skipping face reject haptic");
@@ -360,6 +360,11 @@
                     callback.handleLifecycleAfterAuth();
                 }
             }
+        } else if (client.isBiometricPrompt() && !isUsingSingleModality) {
+            if (!isCurrentFaceAuth(client)) {
+                callback.sendHapticFeedback();
+            }
+            callback.handleLifecycleAfterAuth();
         } else {
             callback.sendHapticFeedback();
             callback.handleLifecycleAfterAuth();
@@ -380,6 +385,8 @@
      */
     public void onAuthenticationError(@NonNull AuthenticationClient<?> client,
             @BiometricConstants.Errors int error, @NonNull ErrorCallback callback) {
+        final boolean isUsingSingleModality = isSingleAuthOnly(client);
+
         // Figure out non-coex state
         final boolean shouldUsuallyVibrate;
         if (isCurrentFaceAuth(client)) {
@@ -401,25 +408,26 @@
         }
 
         // Figure out coex state
-        final boolean keyguardAdvancedLogic = mAdvancedLogicEnabled && client.isKeyguard();
         final boolean hapticSuppressedByCoex;
-
-        if (keyguardAdvancedLogic) {
-            if (isSingleAuthOnly(client)) {
+        if (mAdvancedLogicEnabled && client.isKeyguard()) {
+            if (isUsingSingleModality) {
                 hapticSuppressedByCoex = false;
             } else {
                 hapticSuppressedByCoex = isCurrentFaceAuth(client)
                         && !client.isKeyguardBypassEnabled();
             }
+        } else if (client.isBiometricPrompt() && !isUsingSingleModality) {
+            hapticSuppressedByCoex = isCurrentFaceAuth(client);
         } else {
             hapticSuppressedByCoex = false;
         }
 
         // Combine and send feedback if appropriate
-        Slog.d(TAG, "shouldUsuallyVibrate: " + shouldUsuallyVibrate
-                + ", hapticSuppressedByCoex: " + hapticSuppressedByCoex);
         if (shouldUsuallyVibrate && !hapticSuppressedByCoex) {
             callback.sendHapticFeedback();
+        } else {
+            Slog.v(TAG, "no haptic shouldUsuallyVibrate: " + shouldUsuallyVibrate
+                    + ", hapticSuppressedByCoex: " + hapticSuppressedByCoex);
         }
     }
 
@@ -504,6 +512,19 @@
         return true;
     }
 
+    private boolean hasMultipleSuccessfulAuthentications() {
+        int count = 0;
+        for (AuthenticationClient<?> c : mClientMap.values()) {
+            if (c.wasAuthSuccessful()) {
+                count++;
+            }
+            if (count > 1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
diff --git a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
index 07ce841..e0d5194 100644
--- a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricConstants;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -71,6 +72,24 @@
 
     @Override
     public void onRemoved(@NonNull BiometricAuthenticator.Identifier identifier, int remaining) {
+        // This happens when we have failed to remove a biometric.
+        if (identifier == null) {
+            Slog.e(TAG, "identifier was null, skipping onRemove()");
+            try {
+                if (getListener() != null) {
+                    getListener().onError(getSensorId(), getCookie(),
+                            BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_REMOVE,
+                            0 /* vendorCode */);
+                } else {
+                    Slog.e(TAG, "Error, listener was null, not sending onError callback");
+                }
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to send error to client for onRemoved", e);
+            }
+            mCallback.onClientFinished(this, false /* success */);
+            return;
+        }
+
         Slog.d(TAG, "onRemoved: " + identifier.getBiometricId() + " remaining: " + remaining);
         mBiometricUtils.removeBiometricForUser(getContext(), getTargetUserId(),
                 identifier.getBiometricId());
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 e0b768d..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;
@@ -467,7 +470,8 @@
             ParceledListSlice<ActivityManager.RecentTaskInfo> recentTasks = null;
 
             try {
-                recentTasks = ActivityTaskManager.getService().getRecentTasks(/*maxNum*/1,
+                // Get 2 recent tasks in case we are running in split mode
+                recentTasks = ActivityTaskManager.getService().getRecentTasks(/*maxNum*/2,
                         /*flags*/ 0, userId);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to query recent tasks!");
@@ -475,23 +479,27 @@
             }
 
             if ((recentTasks != null) && (!recentTasks.getList().isEmpty())) {
-                ActivityManager.RecentTaskInfo task = recentTasks.getList().get(0);
-                if (packageName.equals(task.topActivityInfo.packageName)) {
-                    taskInfo = new TaskInfo();
-                    taskInfo.frontTaskId = task.taskId;
-                    taskInfo.isResizeable =
-                            (task.topActivityInfo.resizeMode != RESIZE_MODE_UNRESIZEABLE);
-                    taskInfo.displayId = task.displayId;
-                    taskInfo.userId = task.userId;
-                    taskInfo.isFixedOrientationLandscape =
-                            ActivityInfo.isFixedOrientationLandscape(
-                                    task.topActivityInfo.screenOrientation);
-                    taskInfo.isFixedOrientationPortrait =
-                            ActivityInfo.isFixedOrientationPortrait(
-                                    task.topActivityInfo.screenOrientation);
-                } else {
-                    Log.e(TAG, "Recent task package name: " + task.topActivityInfo.packageName
-                            + " doesn't match with camera client package name: " + packageName);
+                for (ActivityManager.RecentTaskInfo task : recentTasks.getList()) {
+                    if (packageName.equals(task.topActivityInfo.packageName)) {
+                        taskInfo = new TaskInfo();
+                        taskInfo.frontTaskId = task.taskId;
+                        taskInfo.isResizeable =
+                                (task.topActivityInfo.resizeMode != RESIZE_MODE_UNRESIZEABLE);
+                        taskInfo.displayId = task.displayId;
+                        taskInfo.userId = task.userId;
+                        taskInfo.isFixedOrientationLandscape =
+                                ActivityInfo.isFixedOrientationLandscape(
+                                        task.topActivityInfo.screenOrientation);
+                        taskInfo.isFixedOrientationPortrait =
+                                ActivityInfo.isFixedOrientationPortrait(
+                                        task.topActivityInfo.screenOrientation);
+                        break;
+                    }
+                }
+
+                if (taskInfo == null) {
+                    Log.e(TAG, "Recent tasks don't include camera client package name: " +
+                            packageName);
                     return CaptureRequest.SCALER_ROTATE_AND_CROP_NONE;
                 }
             } else {
@@ -816,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
@@ -1010,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();
@@ -1063,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
@@ -1102,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/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 5de162c..311fa7c 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -109,27 +109,26 @@
     }
 
     /**
-     * Returns the window token of the level of the WindowManager hierarchy to mirror, or null
-     * if layer mirroring by SurfaceFlinger should not be performed.
-     * For now, only used for mirroring started from MediaProjection.
+     * Returns the if WindowManager is responsible for mirroring on this display. If {@code false},
+     * then SurfaceFlinger performs no layer mirroring on this display.
+     * Only used for mirroring started from MediaProjection.
      */
-    @Nullable
-    public IBinder getWindowTokenClientToMirrorLocked() {
-        return null;
+    public boolean isWindowManagerMirroringLocked() {
+        return false;
     }
 
     /**
-     * Updates the window token of the level of the level of the WindowManager hierarchy to mirror.
-     * If windowToken is null, then no layer mirroring by SurfaceFlinger to should be performed.
-     * For now, only used for mirroring started from MediaProjection.
+     * Updates if WindowManager is responsible for mirroring on this display. If {@code false}, then
+     * SurfaceFlinger performs no layer mirroring to this display.
+     * Only used for mirroring started from MediaProjection.
      */
-    public void setWindowTokenClientToMirrorLocked(IBinder windowToken) {
+    public void setWindowManagerMirroringLocked(boolean isMirroring) {
     }
 
     /**
      * Returns the default size of the surface associated with the display, or null if the surface
      * is not provided for layer mirroring by SurfaceFlinger.
-     * For now, only used for mirroring started from MediaProjection.
+     * Only used for mirroring started from MediaProjection.
      */
     @Nullable
     public Point getDisplaySurfaceDefaultSize() {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index f5001102..e21edc9 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -204,8 +204,8 @@
     private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top";
     private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
     // This value needs to be in sync with the threshold
-    // in RefreshRateConfigs::getFrameRateDivider.
-    private static final float THRESHOLD_FOR_REFRESH_RATES_DIVIDERS = 0.0009f;
+    // in RefreshRateConfigs::getFrameRateDivisor.
+    private static final float THRESHOLD_FOR_REFRESH_RATES_DIVISORS = 0.0009f;
 
     private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
     private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
@@ -895,13 +895,13 @@
             return info;
         }
 
-        // Override the refresh rate only if it is a divider of the current
+        // Override the refresh rate only if it is a divisor of the current
         // refresh rate. This calculation needs to be in sync with the native code
-        // in RefreshRateConfigs::getFrameRateDivider
+        // in RefreshRateConfigs::getFrameRateDivisor
         Display.Mode currentMode = info.getMode();
         float numPeriods = currentMode.getRefreshRate() / frameRateHz;
         float numPeriodsRound = Math.round(numPeriods);
-        if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVIDERS) {
+        if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVISORS) {
             return info;
         }
         frameRateHz = currentMode.getRefreshRate() / numPeriodsRound;
@@ -913,9 +913,9 @@
                 continue;
             }
 
-            if (mode.getRefreshRate() >= frameRateHz - THRESHOLD_FOR_REFRESH_RATES_DIVIDERS
+            if (mode.getRefreshRate() >= frameRateHz - THRESHOLD_FOR_REFRESH_RATES_DIVISORS
                     && mode.getRefreshRate()
-                    <= frameRateHz + THRESHOLD_FOR_REFRESH_RATES_DIVIDERS) {
+                    <= frameRateHz + THRESHOLD_FOR_REFRESH_RATES_DIVISORS) {
                 if (DEBUG) {
                     Slog.d(TAG, "found matching modeId " + mode.getModeId());
                 }
@@ -2265,13 +2265,12 @@
         final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
         final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
 
-        // Mirror the part of WM hierarchy that corresponds to the provided window token.
-        IBinder windowTokenClientToMirror = device.getWindowTokenClientToMirrorLocked();
-
         // Find the logical display that the display device is showing.
         // Certain displays only ever show their own content.
         LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device);
-        if (!ownContent && windowTokenClientToMirror == null) {
+        // Proceed with display-managed mirroring only if window manager will not be handling it.
+        if (!ownContent && !device.isWindowManagerMirroringLocked()) {
+            // Only mirror the display if content recording is not taking place in WM.
             if (display != null && !display.hasContentLocked()) {
                 // If the display does not have any content of its own, then
                 // automatically mirror the requested logical display contents if possible.
@@ -2463,7 +2462,7 @@
             pw.println("  mMinimumBrightnessCurve=" + mMinimumBrightnessCurve);
 
             if (mUserPreferredMode != null) {
-                pw.println(mUserPreferredMode);
+                pw.println(" mUserPreferredMode=" + mUserPreferredMode);
             }
 
             pw.println();
@@ -2579,7 +2578,7 @@
 
         boolean getAllowNonNativeRefreshRateOverride() {
             return DisplayProperties
-                    .debug_allow_non_native_refresh_rate_override().orElse(false);
+                    .debug_allow_non_native_refresh_rate_override().orElse(true);
         }
 
         @NonNull
@@ -3864,23 +3863,11 @@
         }
 
         @Override
-        public IBinder getWindowTokenClientToMirror(int displayId) {
-            final DisplayDevice device;
-            synchronized (mSyncRoot) {
-                device = getDeviceForDisplayLocked(displayId);
-                if (device == null) {
-                    return null;
-                }
-            }
-            return device.getWindowTokenClientToMirrorLocked();
-        }
-
-        @Override
-        public void setWindowTokenClientToMirror(int displayId, IBinder windowToken) {
+        public void setWindowManagerMirroring(int displayId, boolean isMirroring) {
             synchronized (mSyncRoot) {
                 final DisplayDevice device = getDeviceForDisplayLocked(displayId);
                 if (device != null) {
-                    device.setWindowTokenClientToMirrorLocked(windowToken);
+                    device.setWindowManagerMirroringLocked(isMirroring);
                 }
             }
         }
@@ -3952,12 +3939,22 @@
      * Listens to changes in device state and reports the state to LogicalDisplayMapper.
      */
     class DeviceStateListener implements DeviceStateManager.DeviceStateCallback {
+        // Base state corresponds to the physical state of the device
+        private int mBaseState = DeviceStateManager.INVALID_DEVICE_STATE;
+
         @Override
         public void onStateChanged(int deviceState) {
+            boolean isDeviceStateOverrideActive = deviceState != mBaseState;
             synchronized (mSyncRoot) {
-                mLogicalDisplayMapper.setDeviceStateLocked(deviceState);
+                mLogicalDisplayMapper
+                        .setDeviceStateLocked(deviceState, isDeviceStateOverrideActive);
             }
         }
+
+        @Override
+        public void onBaseStateChanged(int state) {
+            mBaseState = state;
+        }
     };
 
     private class BrightnessPair {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index d233c5e..7a0cf4b 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -255,10 +255,9 @@
         public boolean updateDisplayPropertiesLocked(SurfaceControl.StaticDisplayInfo staticInfo,
                 SurfaceControl.DynamicDisplayInfo dynamicInfo,
                 SurfaceControl.DesiredDisplayModeSpecs modeSpecs) {
-            boolean changed =
-                    updateSystemPreferredDisplayMode(dynamicInfo.preferredBootDisplayMode);
-            changed |= updateDisplayModesLocked(
-                    dynamicInfo.supportedDisplayModes, dynamicInfo.activeDisplayModeId, modeSpecs);
+            boolean changed = updateDisplayModesLocked(
+                    dynamicInfo.supportedDisplayModes, dynamicInfo.preferredBootDisplayMode,
+                    dynamicInfo.activeDisplayModeId, modeSpecs);
             changed |= updateStaticInfo(staticInfo);
             changed |= updateColorModesLocked(dynamicInfo.supportedColorModes,
                     dynamicInfo.activeColorMode);
@@ -273,10 +272,12 @@
         }
 
         public boolean updateDisplayModesLocked(
-                SurfaceControl.DisplayMode[] displayModes, int activeDisplayModeId,
-                SurfaceControl.DesiredDisplayModeSpecs modeSpecs) {
+                SurfaceControl.DisplayMode[] displayModes, int preferredSfDisplayModeId,
+                int activeSfDisplayModeId, SurfaceControl.DesiredDisplayModeSpecs modeSpecs) {
             mSfDisplayModes = Arrays.copyOf(displayModes, displayModes.length);
-            mActiveSfDisplayMode = getModeById(displayModes, activeDisplayModeId);
+            mActiveSfDisplayMode = getModeById(displayModes, activeSfDisplayModeId);
+            SurfaceControl.DisplayMode preferredSfDisplayMode =
+                        getModeById(displayModes, preferredSfDisplayModeId);
 
             // Build an updated list of all existing modes.
             ArrayList<DisplayModeRecord> records = new ArrayList<>();
@@ -335,6 +336,27 @@
                 }
             }
 
+            boolean preferredModeChanged = false;
+
+            if (preferredSfDisplayModeId != INVALID_MODE_ID && preferredSfDisplayMode != null) {
+                DisplayModeRecord preferredRecord = null;
+                for (DisplayModeRecord record : records) {
+                    if (record.hasMatchingMode(preferredSfDisplayMode)) {
+                        preferredRecord = record;
+                        break;
+                    }
+                }
+
+                if (preferredRecord != null) {
+                    int preferredModeId = preferredRecord.mMode.getModeId();
+                    if (mSurfaceControlProxy.getBootDisplayModeSupport()
+                            && mSystemPreferredModeId != preferredModeId) {
+                        mSystemPreferredModeId = preferredModeId;
+                        preferredModeChanged = true;
+                    }
+                }
+            }
+
             boolean activeModeChanged = false;
 
             // Check whether SurfaceFlinger or the display device changed the active mode out from
@@ -373,7 +395,7 @@
             boolean recordsChanged = records.size() != mSupportedModes.size() || modesAdded;
             // If the records haven't changed then we're done here.
             if (!recordsChanged) {
-                return activeModeChanged;
+                return activeModeChanged || preferredModeChanged;
             }
 
             mSupportedModes.clear();
@@ -386,14 +408,14 @@
                 mDefaultModeId = mSystemPreferredModeId != INVALID_MODE_ID
                         ? mSystemPreferredModeId : activeRecord.mMode.getModeId();
                 mDefaultModeGroup = mSystemPreferredModeId != INVALID_MODE_ID
-                        ? getModeById(mSfDisplayModes, mSystemPreferredModeId).group
+                        ? preferredSfDisplayMode.group
                         : mActiveSfDisplayMode.group;
             } else if (modesAdded && activeModeChanged) {
                 Slog.d(TAG, "New display modes are added and the active mode has changed, "
                         + "use active mode as default mode.");
                 mDefaultModeId = activeRecord.mMode.getModeId();
                 mDefaultModeGroup = mActiveSfDisplayMode.group;
-            } else if (findDisplayModeIdLocked(mDefaultModeId, mDefaultModeGroup) < 0) {
+            } else if (findSfDisplayModeIdLocked(mDefaultModeId, mDefaultModeGroup) < 0) {
                 Slog.w(TAG, "Default display mode no longer available, using currently"
                         + " active mode as default.");
                 mDefaultModeId = activeRecord.mMode.getModeId();
@@ -545,15 +567,6 @@
             return true;
         }
 
-        private boolean updateSystemPreferredDisplayMode(int modeId) {
-            if (!mSurfaceControlProxy.getBootDisplayModeSupport()
-                    || mSystemPreferredModeId == modeId) {
-                return false;
-            }
-            mSystemPreferredModeId = modeId;
-            return true;
-        }
-
         private SurfaceControl.DisplayMode getModeById(SurfaceControl.DisplayMode[] supportedModes,
                 int modeId) {
             for (SurfaceControl.DisplayMode mode : supportedModes) {
@@ -871,24 +884,32 @@
         public void setUserPreferredDisplayModeLocked(Display.Mode mode) {
             final int oldModeId = getPreferredModeId();
             mUserPreferredMode = mode;
-            if (mode != null && (mode.isRefreshRateSet() ^ mode.isResolutionSet())) {
-                mUserPreferredMode = findMode(mode.getPhysicalWidth(),
+            if (mode != null && (mode.isRefreshRateSet() || mode.isResolutionSet())) {
+                Display.Mode matchingSupportedMode;
+                matchingSupportedMode = findMode(mode.getPhysicalWidth(),
                         mode.getPhysicalHeight(), mode.getRefreshRate());
+                if (matchingSupportedMode != null) {
+                    mUserPreferredMode = matchingSupportedMode;
+                }
             }
-            mUserPreferredModeId = findUserPreferredModeIdLocked(mode);
 
-            if (oldModeId != getPreferredModeId()) {
-                updateDeviceInfoLocked();
+            mUserPreferredModeId = findUserPreferredModeIdLocked(mUserPreferredMode);
+
+            if (oldModeId == getPreferredModeId()) {
+                return;
             }
+            updateDeviceInfoLocked();
 
             if (!mSurfaceControlProxy.getBootDisplayModeSupport()) {
                 return;
             }
-            if (mUserPreferredMode == null) {
+            if (mUserPreferredModeId == INVALID_MODE_ID) {
                 mSurfaceControlProxy.clearBootDisplayMode(getDisplayTokenLocked());
             } else {
+                int preferredSfDisplayModeId = findSfDisplayModeIdLocked(
+                        mUserPreferredMode.getModeId(), mDefaultModeGroup);
                 mSurfaceControlProxy.setBootDisplayMode(getDisplayTokenLocked(),
-                        mUserPreferredMode.getModeId());
+                        preferredSfDisplayModeId);
             }
         }
 
@@ -923,9 +944,9 @@
             // mode based on vendor requirements.
             // Note: We prefer the default mode group over the current one as this is the mode
             // group the vendor prefers.
-            int baseModeId = findDisplayModeIdLocked(displayModeSpecs.baseModeId,
+            int baseSfModeId = findSfDisplayModeIdLocked(displayModeSpecs.baseModeId,
                     mDefaultModeGroup);
-            if (baseModeId < 0) {
+            if (baseSfModeId < 0) {
                 // When a display is hotplugged, it's possible for a mode to be removed that was
                 // previously valid. Because of the way display changes are propagated through the
                 // framework, and the caching of the display mode specs in LogicalDisplay, it's
@@ -943,7 +964,7 @@
                 getHandler().sendMessage(PooledLambda.obtainMessage(
                         LocalDisplayDevice::setDesiredDisplayModeSpecsAsync, this,
                         getDisplayTokenLocked(),
-                        new SurfaceControl.DesiredDisplayModeSpecs(baseModeId,
+                        new SurfaceControl.DesiredDisplayModeSpecs(baseSfModeId,
                                 mDisplayModeSpecs.allowGroupSwitching,
                                 mDisplayModeSpecs.primaryRefreshRateRange.min,
                                 mDisplayModeSpecs.primaryRefreshRateRange.max,
@@ -1090,14 +1111,14 @@
             pw.println("mDisplayDeviceConfig=" + mDisplayDeviceConfig);
         }
 
-        private int findDisplayModeIdLocked(int modeId, int modeGroup) {
-            int matchingModeId = INVALID_MODE_ID;
-            DisplayModeRecord record = mSupportedModes.get(modeId);
+        private int findSfDisplayModeIdLocked(int displayModeId, int modeGroup) {
+            int matchingSfDisplayModeId = INVALID_MODE_ID;
+            DisplayModeRecord record = mSupportedModes.get(displayModeId);
             if (record != null) {
                 for (SurfaceControl.DisplayMode mode : mSfDisplayModes) {
                     if (record.hasMatchingMode(mode)) {
-                        if (matchingModeId == INVALID_MODE_ID) {
-                            matchingModeId = mode.id;
+                        if (matchingSfDisplayModeId == INVALID_MODE_ID) {
+                            matchingSfDisplayModeId = mode.id;
                         }
 
                         // Prefer to return a mode that matches the modeGroup
@@ -1107,7 +1128,7 @@
                     }
                 }
             }
-            return matchingModeId;
+            return matchingSfDisplayModeId;
         }
 
         // Returns a mode with id = modeId.
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index 6f5729f..add0a9f 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -359,7 +359,7 @@
         mDeviceStateToLayoutMap.dumpLocked(ipw);
     }
 
-    void setDeviceStateLocked(int state) {
+    void setDeviceStateLocked(int state, boolean isOverrideActive) {
         Slog.i(TAG, "Requesting Transition to state: " + state + ", from state=" + mDeviceState
                 + ", interactive=" + mInteractive);
         // As part of a state transition, we may need to turn off some displays temporarily so that
@@ -370,12 +370,10 @@
             resetLayoutLocked(mDeviceState, state, LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION);
         }
         mPendingDeviceState = state;
-        final boolean wakeDevice = mDeviceStatesOnWhichToWakeUp.get(mPendingDeviceState)
-                && !mDeviceStatesOnWhichToWakeUp.get(mDeviceState)
-                && !mInteractive && mBootCompleted;
-        final boolean sleepDevice = mDeviceStatesOnWhichToSleep.get(mPendingDeviceState)
-                && !mDeviceStatesOnWhichToSleep.get(mDeviceState)
-                && mInteractive && mBootCompleted;
+        final boolean wakeDevice = shouldDeviceBeWoken(mPendingDeviceState, mDeviceState,
+                mInteractive, mBootCompleted);
+        final boolean sleepDevice = shouldDeviceBePutToSleep(mPendingDeviceState, mDeviceState,
+                isOverrideActive, mInteractive, mBootCompleted);
 
         // If all displays are off already, we can just transition here, unless we are trying to
         // wake or sleep the device as part of this transition. In that case defer the final
@@ -429,6 +427,53 @@
         }
     }
 
+    /**
+     * Returns if the device should be woken up or not. Called to check if the device state we are
+     * moving to is one that should awake the device, as well as if we are moving from a device
+     * state that shouldn't have been already woken from.
+     *
+     * @param pendingState device state we are moving to
+     * @param currentState device state we are currently in
+     * @param isInteractive if the device is in an interactive state
+     * @param isBootCompleted is the device fully booted
+     *
+     * @see #shouldDeviceBePutToSleep
+     * @see #setDeviceStateLocked
+     */
+    @VisibleForTesting
+    boolean shouldDeviceBeWoken(int pendingState, int currentState, boolean isInteractive,
+            boolean isBootCompleted) {
+        return mDeviceStatesOnWhichToWakeUp.get(pendingState)
+                && !mDeviceStatesOnWhichToWakeUp.get(currentState)
+                && !isInteractive && isBootCompleted;
+    }
+
+    /**
+     * Returns if the device should be put to sleep or not.
+     *
+     * Includes a check to verify that the device state that we are moving to, {@code pendingState},
+     * is the same as the physical state of the device, {@code baseState}. Different values for
+     * these parameters indicate a device state override is active, and we shouldn't put the device
+     * to sleep to provide a better user experience.
+     *
+     * @param pendingState device state we are moving to
+     * @param currentState device state we are currently in
+     * @param isOverrideActive if a device state override is currently active or not
+     * @param isInteractive if the device is in an interactive state
+     * @param isBootCompleted is the device fully booted
+     *
+     * @see #shouldDeviceBeWoken
+     * @see #setDeviceStateLocked
+     */
+    @VisibleForTesting
+    boolean shouldDeviceBePutToSleep(int pendingState, int currentState, boolean isOverrideActive,
+            boolean isInteractive, boolean isBootCompleted) {
+        return mDeviceStatesOnWhichToSleep.get(pendingState)
+                && !mDeviceStatesOnWhichToSleep.get(currentState)
+                && !isOverrideActive
+                && isInteractive && isBootCompleted;
+    }
+
     private boolean areAllTransitioningDisplaysOffLocked() {
         final int count = mLogicalDisplays.size();
         for (int i = 0; i < count; i++) {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 797c3fb..ea31374 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -33,7 +33,6 @@
 import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP;
 import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED;
 
-import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Point;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -235,7 +234,7 @@
         private Display.Mode mMode;
         private boolean mIsDisplayOn;
         private int mDisplayIdToMirror;
-        private IBinder mWindowTokenClientToMirror;
+        private boolean mIsWindowManagerMirroring;
 
         public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
                 int ownerUid, String ownerPackageName, Surface surface, int flags,
@@ -258,7 +257,7 @@
             mUniqueIndex = uniqueIndex;
             mIsDisplayOn = surface != null;
             mDisplayIdToMirror = virtualDisplayConfig.getDisplayIdToMirror();
-            mWindowTokenClientToMirror = virtualDisplayConfig.getWindowTokenClientToMirror();
+            mIsWindowManagerMirroring = virtualDisplayConfig.isWindowManagerMirroring();
         }
 
         @Override
@@ -289,15 +288,14 @@
         }
 
         @Override
-        @Nullable
-        public IBinder getWindowTokenClientToMirrorLocked() {
-            return mWindowTokenClientToMirror;
+        public boolean isWindowManagerMirroringLocked() {
+            return mIsWindowManagerMirroring;
         }
 
         @Override
-        public void setWindowTokenClientToMirrorLocked(IBinder windowToken) {
-            if (mWindowTokenClientToMirror != windowToken) {
-                mWindowTokenClientToMirror = windowToken;
+        public void setWindowManagerMirroringLocked(boolean mirroring) {
+            if (mIsWindowManagerMirroring != mirroring) {
+                mIsWindowManagerMirroring = mirroring;
                 sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
                 sendTraversalRequestLocked();
             }
@@ -391,7 +389,7 @@
             pw.println("mDisplayState=" + Display.stateToString(mDisplayState));
             pw.println("mStopped=" + mStopped);
             pw.println("mDisplayIdToMirror=" + mDisplayIdToMirror);
-            pw.println("mWindowTokenClientToMirror=" + mWindowTokenClientToMirror);
+            pw.println("mWindowManagerMirroring=" + mIsWindowManagerMirroring);
         }
 
 
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
index fb36dc7..d04b5a2 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
@@ -346,6 +346,7 @@
         writer.println("DisplayWhiteBalanceController");
         writer.println("  mLoggingEnabled=" + mLoggingEnabled);
         writer.println("  mEnabled=" + mEnabled);
+        writer.println("  mStrongModeEnabled=" + mStrongModeEnabled);
         writer.println("  mDisplayPowerControllerCallbacks=" + mDisplayPowerControllerCallbacks);
         mBrightnessSensor.dump(writer);
         mBrightnessFilter.dump(writer);
diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java
index 76754d3..4a1a950 100644
--- a/services/core/java/com/android/server/dreams/DreamController.java
+++ b/services/core/java/com/android/server/dreams/DreamController.java
@@ -104,7 +104,7 @@
             pw.println("  mCurrentDream:");
             pw.println("    mToken=" + mCurrentDream.mToken);
             pw.println("    mName=" + mCurrentDream.mName);
-            pw.println("    mIsTest=" + mCurrentDream.mIsTest);
+            pw.println("    mIsPreviewMode=" + mCurrentDream.mIsPreviewMode);
             pw.println("    mCanDoze=" + mCurrentDream.mCanDoze);
             pw.println("    mUserId=" + mCurrentDream.mUserId);
             pw.println("    mBound=" + mCurrentDream.mBound);
@@ -117,7 +117,7 @@
     }
 
     public void startDream(Binder token, ComponentName name,
-            boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock,
+            boolean isPreviewMode, boolean canDoze, int userId, PowerManager.WakeLock wakeLock,
             ComponentName overlayComponentName) {
         stopDream(true /*immediate*/, "starting new dream");
 
@@ -127,10 +127,10 @@
             mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL);
 
             Slog.i(TAG, "Starting dream: name=" + name
-                    + ", isTest=" + isTest + ", canDoze=" + canDoze
+                    + ", isPreviewMode=" + isPreviewMode + ", canDoze=" + canDoze
                     + ", userId=" + userId);
 
-            mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId, wakeLock);
+            mCurrentDream = new DreamRecord(token, name, isPreviewMode, canDoze, userId, wakeLock);
 
             mDreamStartTime = SystemClock.elapsedRealtime();
             MetricsLogger.visible(mContext,
@@ -140,6 +140,7 @@
             intent.setComponent(name);
             intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
             intent.putExtra(DreamService.EXTRA_DREAM_OVERLAY_COMPONENT, overlayComponentName);
+            intent.putExtra(DreamService.EXTRA_IS_PREVIEW, isPreviewMode);
             try {
                 if (!mContext.bindServiceAsUser(intent, mCurrentDream,
                         Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
@@ -190,7 +191,8 @@
             final DreamRecord oldDream = mCurrentDream;
             mCurrentDream = null;
             Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
-                    + ", isTest=" + oldDream.mIsTest + ", canDoze=" + oldDream.mCanDoze
+                    + ", isPreviewMode=" + oldDream.mIsPreviewMode
+                    + ", canDoze=" + oldDream.mCanDoze
                     + ", userId=" + oldDream.mUserId
                     + ", reason='" + reason + "'"
                     + (mSavedStopReason == null ? "" : "(from '" + mSavedStopReason + "')"));
@@ -247,7 +249,7 @@
 
         mCurrentDream.mService = service;
 
-        if (!mCurrentDream.mIsTest) {
+        if (!mCurrentDream.mIsPreviewMode) {
             mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL);
             mCurrentDream.mSentStartBroadcast = true;
         }
@@ -263,7 +265,7 @@
     private final class DreamRecord implements DeathRecipient, ServiceConnection {
         public final Binder mToken;
         public final ComponentName mName;
-        public final boolean mIsTest;
+        public final boolean mIsPreviewMode;
         public final boolean mCanDoze;
         public final int mUserId;
 
@@ -275,11 +277,11 @@
 
         public boolean mWakingGently;
 
-        public DreamRecord(Binder token, ComponentName name,
-                boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) {
+        DreamRecord(Binder token, ComponentName name, boolean isPreviewMode,
+                boolean canDoze, int userId, PowerManager.WakeLock wakeLock) {
             mToken = token;
             mName = name;
-            mIsTest = isTest;
+            mIsPreviewMode = isPreviewMode;
             mCanDoze = canDoze;
             mUserId  = userId;
             mWakeLock = wakeLock;
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index f0a6af3..22d32a6 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -87,7 +87,7 @@
     private Binder mCurrentDreamToken;
     private ComponentName mCurrentDreamName;
     private int mCurrentDreamUserId;
-    private boolean mCurrentDreamIsTest;
+    private boolean mCurrentDreamIsPreview;
     private boolean mCurrentDreamCanDoze;
     private boolean mCurrentDreamIsDozing;
     private boolean mCurrentDreamIsWaking;
@@ -169,7 +169,7 @@
         pw.println("mCurrentDreamToken=" + mCurrentDreamToken);
         pw.println("mCurrentDreamName=" + mCurrentDreamName);
         pw.println("mCurrentDreamUserId=" + mCurrentDreamUserId);
-        pw.println("mCurrentDreamIsTest=" + mCurrentDreamIsTest);
+        pw.println("mCurrentDreamIsPreview=" + mCurrentDreamIsPreview);
         pw.println("mCurrentDreamCanDoze=" + mCurrentDreamCanDoze);
         pw.println("mCurrentDreamIsDozing=" + mCurrentDreamIsDozing);
         pw.println("mCurrentDreamIsWaking=" + mCurrentDreamIsWaking);
@@ -190,7 +190,7 @@
 
     private boolean isDreamingInternal() {
         synchronized (mLock) {
-            return mCurrentDreamToken != null && !mCurrentDreamIsTest
+            return mCurrentDreamToken != null && !mCurrentDreamIsPreview
                     && !mCurrentDreamIsWaking;
         }
     }
@@ -235,7 +235,7 @@
 
     private void testDreamInternal(ComponentName dream, int userId) {
         synchronized (mLock) {
-            startDreamLocked(dream, true /*isTest*/, false /*canDoze*/, userId);
+            startDreamLocked(dream, true /*isPreviewMode*/, false /*canDoze*/, userId);
         }
     }
 
@@ -244,7 +244,7 @@
         final ComponentName dream = chooseDreamForUser(doze, userId);
         if (dream != null) {
             synchronized (mLock) {
-                startDreamLocked(dream, false /*isTest*/, doze, userId);
+                startDreamLocked(dream, false /*isPreviewMode*/, doze, userId);
             }
         }
     }
@@ -395,10 +395,10 @@
     }
 
     private void startDreamLocked(final ComponentName name,
-            final boolean isTest, final boolean canDoze, final int userId) {
+            final boolean isPreviewMode, final boolean canDoze, final int userId) {
         if (!mCurrentDreamIsWaking
                 && Objects.equals(mCurrentDreamName, name)
-                && mCurrentDreamIsTest == isTest
+                && mCurrentDreamIsPreview == isPreviewMode
                 && mCurrentDreamCanDoze == canDoze
                 && mCurrentDreamUserId == userId) {
             Slog.i(TAG, "Already in target dream.");
@@ -412,7 +412,7 @@
         final Binder newToken = new Binder();
         mCurrentDreamToken = newToken;
         mCurrentDreamName = name;
-        mCurrentDreamIsTest = isTest;
+        mCurrentDreamIsPreview = isPreviewMode;
         mCurrentDreamCanDoze = canDoze;
         mCurrentDreamUserId = userId;
 
@@ -424,7 +424,7 @@
                 .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "startDream");
         mHandler.post(wakeLock.wrap(() -> {
             mAtmInternal.notifyDreamStateChanged(true);
-            mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock,
+            mController.startDream(newToken, name, isPreviewMode, canDoze, userId, wakeLock,
                     mDreamOverlayServiceName);
         }));
     }
@@ -457,7 +457,7 @@
         }
         mCurrentDreamToken = null;
         mCurrentDreamName = null;
-        mCurrentDreamIsTest = false;
+        mCurrentDreamIsPreview = false;
         mCurrentDreamCanDoze = false;
         mCurrentDreamUserId = 0;
         mCurrentDreamIsWaking = false;
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/OWNERS b/services/core/java/com/android/server/infra/OWNERS
new file mode 100644
index 0000000..0466d8a
--- /dev/null
+++ b/services/core/java/com/android/server/infra/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 655446
+
+include /core/java/android/service/cloudsearch/OWNERS
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/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index c15242a..140a28f 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -144,6 +144,7 @@
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.OptionalInt;
 
 /*
  * Wraps the C++ InputManager and provides its callbacks.
@@ -2915,48 +2916,17 @@
 
     // Native callback
     @SuppressWarnings("unused")
-    private void notifyWindowUnresponsive(IBinder token, String reason) {
-        int gestureMonitorPid = -1;
-        synchronized (mInputMonitors) {
-            final GestureMonitorSpyWindow gestureMonitor = mInputMonitors.get(token);
-            if (gestureMonitor != null) {
-                gestureMonitorPid = gestureMonitor.mWindowHandle.ownerPid;
-            }
-        }
-        if (gestureMonitorPid != -1) {
-            mWindowManagerCallbacks.notifyGestureMonitorUnresponsive(gestureMonitorPid, reason);
-            return;
-        }
-        mWindowManagerCallbacks.notifyWindowUnresponsive(token, reason);
+    private void notifyWindowUnresponsive(IBinder token, int pid, boolean isPidValid,
+            String reason) {
+        mWindowManagerCallbacks.notifyWindowUnresponsive(token,
+                isPidValid ? OptionalInt.of(pid) : OptionalInt.empty(), reason);
     }
 
     // Native callback
     @SuppressWarnings("unused")
-    private void notifyMonitorUnresponsive(int pid, String reason) {
-        mWindowManagerCallbacks.notifyGestureMonitorUnresponsive(pid, reason);
-    }
-
-    // Native callback
-    @SuppressWarnings("unused")
-    private void notifyWindowResponsive(IBinder token) {
-        int gestureMonitorPid = -1;
-        synchronized (mInputMonitors) {
-            final GestureMonitorSpyWindow gestureMonitor = mInputMonitors.get(token);
-            if (gestureMonitor != null) {
-                gestureMonitorPid = gestureMonitor.mWindowHandle.ownerPid;
-            }
-        }
-        if (gestureMonitorPid != -1) {
-            mWindowManagerCallbacks.notifyGestureMonitorResponsive(gestureMonitorPid);
-            return;
-        }
-        mWindowManagerCallbacks.notifyWindowResponsive(token);
-    }
-
-    // Native callback
-    @SuppressWarnings("unused")
-    private void notifyMonitorResponsive(int pid) {
-        mWindowManagerCallbacks.notifyGestureMonitorResponsive(pid);
+    private void notifyWindowResponsive(IBinder token, int pid, boolean isPidValid) {
+        mWindowManagerCallbacks.notifyWindowResponsive(token,
+                isPidValid ? OptionalInt.of(pid) : OptionalInt.empty());
     }
 
     // Native callback.
@@ -3329,34 +3299,22 @@
         void notifyNoFocusedWindowAnr(InputApplicationHandle applicationHandle);
 
         /**
-         * Notify the window manager about a gesture monitor that is unresponsive.
-         *
-         * @param pid the pid of the gesture monitor process
-         * @param reason the reason why this connection is unresponsive
-         */
-        void notifyGestureMonitorUnresponsive(int pid, @NonNull String reason);
-
-        /**
          * Notify the window manager about a window that is unresponsive.
          *
          * @param token the token that can be used to look up the window
+         * @param pid the pid of the window owner, if known
          * @param reason the reason why this connection is unresponsive
          */
-        void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull String reason);
-
-        /**
-         * Notify the window manager about a gesture monitor that has become responsive.
-         *
-         * @param pid the pid of the gesture monitor process
-         */
-        void notifyGestureMonitorResponsive(int pid);
+        void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
+                @NonNull String reason);
 
         /**
          * Notify the window manager about a window that has become responsive.
          *
          * @param token the token that can be used to look up the window
+         * @param pid the pid of the window owner, if known
          */
-        void notifyWindowResponsive(@NonNull IBinder token);
+        void notifyWindowResponsive(@NonNull IBinder token, @NonNull OptionalInt pid);
 
         /**
          * This callback is invoked when an event first arrives to InputDispatcher and before it is
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 9846a2b..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);
@@ -82,13 +80,14 @@
         mIsIntercepting = false;
     }
 
-    void startIntercepting() {
-        // TODO(b/210978621): Update the spy window's PID and UID to be associated with the IME so
-        //  that ANRs are correctly attributed to the IME.
-        final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-        mWindowHandle.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
-        t.setInputWindowInfo(mInputSurface, mWindowHandle);
-        t.apply();
+    void startIntercepting(int imePid, int imeUid) {
+        mWindowHandle.ownerPid = imePid;
+        mWindowHandle.ownerUid = imeUid;
+        mWindowHandle.inputConfig &= ~InputConfig.SPY;
+
+        new SurfaceControl.Transaction()
+                .setInputWindowInfo(mInputSurface, mWindowHandle)
+                .apply();
         mIsIntercepting = true;
     }
 
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index d31f7c5..b301d99 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -136,7 +136,7 @@
      */
     @UiThread
     @Nullable
-    HandwritingSession startHandwritingSession(int requestId) {
+    HandwritingSession startHandwritingSession(int requestId, int imePid, int imeUid) {
         if (mHandwritingSurface == null) {
             Slog.e(TAG, "Cannot start handwriting session: Handwriting was not initialized.");
             return null;
@@ -160,7 +160,7 @@
             throw new IllegalStateException(
                     "Handwriting surface should not be already intercepting.");
         }
-        mHandwritingSurface.startIntercepting();
+        mHandwritingSurface.startIntercepting(imePid, imeUid);
 
         return new HandwritingSession(mCurrentRequestId, mHandwritingSurface.getInputChannel(),
                 mHandwritingBuffer);
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/ImePlatformCompatUtils.java b/services/core/java/com/android/server/inputmethod/ImePlatformCompatUtils.java
new file mode 100644
index 0000000..83ca16d
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/ImePlatformCompatUtils.java
@@ -0,0 +1,64 @@
+/*
+ * 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.inputmethodservice.InputMethodService.FINISH_INPUT_NO_FALLBACK_CONNECTION;
+import static android.view.inputmethod.InputMethodManager.CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING;
+
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.compat.IPlatformCompat;
+
+/**
+ * A utility class used by {@link InputMethodManagerService} to manage the platform
+ * compatibility changes on IMF (Input Method Framework) side.
+ */
+final class ImePlatformCompatUtils {
+    private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
+            ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+
+    /**
+     * Whether to finish the {@link android.view.inputmethod.InputConnection} when the device
+     * becomes {@link android.os.PowerManager#isInteractive non-interactive}.
+     *
+     * @param imeUid The uid of the IME application
+     */
+    public boolean shouldFinishInputWithReportToIme(int imeUid) {
+        return isChangeEnabledByUid(FINISH_INPUT_NO_FALLBACK_CONNECTION, imeUid);
+    }
+
+    /**
+     *  Whether to clear {@link android.view.inputmethod.InputMethodManager#SHOW_FORCED} flag
+     *  when the next IME focused application changed.
+     *
+     * @param clientUid The uid of the app
+     */
+    public boolean shouldClearShowForcedFlag(int clientUid) {
+        return isChangeEnabledByUid(CLEAR_SHOW_FORCED_FLAG_WHEN_LEAVING, clientUid);
+    }
+
+    private boolean isChangeEnabledByUid(long changeFlag, int uid) {
+        boolean result = false;
+        try {
+            result = mPlatformCompat.isChangeEnabledByUid(changeFlag, uid);
+        } catch (RemoteException e) {
+        }
+        return result;
+    }
+}
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 0b7e391..77dcbd3 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -15,7 +15,6 @@
 
 package com.android.server.inputmethod;
 
-import static android.inputmethodservice.InputMethodService.FINISH_INPUT_NO_FALLBACK_CONNECTION;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
@@ -122,6 +121,7 @@
 import android.util.Printer;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.util.proto.ProtoOutputStream;
 import android.view.IWindowManager;
 import android.view.InputChannel;
@@ -148,7 +148,6 @@
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.compat.IPlatformCompat;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.infra.AndroidFuture;
 import com.android.internal.inputmethod.DirectBootAwareness;
@@ -157,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;
@@ -276,9 +276,12 @@
     final InputMethodSettings mSettings;
     final SettingsObserver mSettingsObserver;
     final IWindowManager mIWindowManager;
+    private final SparseBooleanArray mLoggedDeniedGetInputMethodWindowVisibleHeightForUid =
+            new SparseBooleanArray(0);
     final WindowManagerInternal mWindowManagerInternal;
     final PackageManagerInternal mPackageManagerInternal;
     final InputManagerInternal mInputManagerInternal;
+    final ImePlatformCompatUtils mImePlatformCompatUtils;
     final boolean mHasFeature;
     private final ArrayMap<String, List<InputMethodSubtype>> mAdditionalSubtypeMap =
             new ArrayMap<>();
@@ -333,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;
@@ -691,8 +698,6 @@
      */
     boolean mIsInteractive = true;
 
-    private final IPlatformCompat mPlatformCompat;
-
     int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
 
     /**
@@ -1381,6 +1386,13 @@
             clearPackageChangeState();
         }
 
+        @Override
+        public void onUidRemoved(int uid) {
+            synchronized (ImfLock.class) {
+                mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.delete(uid);
+            }
+        }
+
         private void clearPackageChangeState() {
             // No need to lock them because we access these fields only on getRegisteredHandler().
             mChangedPackages.clear();
@@ -1627,6 +1639,7 @@
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
         mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
+        mImePlatformCompatUtils = new ImePlatformCompatUtils();
         mImeDisplayValidator = mWindowManagerInternal::getDisplayImePolicy;
         mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
         mUserManager = mContext.getSystemService(UserManager.class);
@@ -1634,8 +1647,7 @@
         mAccessibilityManager = AccessibilityManager.getInstance(context);
         mHasFeature = context.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_INPUT_METHODS);
-        mPlatformCompat = IPlatformCompat.Stub.asInterface(
-                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+
         mSlotIme = mContext.getString(com.android.internal.R.string.status_bar_ime);
 
         Bundle extras = new Bundle();
@@ -1716,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);
 
@@ -1757,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
@@ -1825,6 +1878,8 @@
                     });
                 }
 
+                recreateImeDrawsImeNavBarResIfNecessary(currentUserId);
+
                 mMyPackageMonitor.register(mContext, null, UserHandle.ALL, true);
                 mSettingsObserver.registerContentObserverLocked(currentUserId);
 
@@ -1846,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());
             }
         }
     }
@@ -2405,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,
@@ -2674,7 +2729,7 @@
                     + mCurTokenDisplayId);
         }
         inputMethod.initializeInternal(token, new InputMethodPrivilegedOperationsImpl(this, token),
-                configChanges, supportStylusHw, shouldShowImeSwitcherWhenImeIsShownLocked());
+                configChanges, supportStylusHw, getInputMethodNavButtonFlagsLocked());
     }
 
     @AnyThread
@@ -2931,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")
@@ -3196,7 +3257,7 @@
         // the same enabled IMEs list.
         mSwitchingController.resetCircularListLocked(mContext);
 
-        sendShouldShowImeSwitcherWhenImeIsShownLocked();
+        sendOnNavButtonFlagsChangedLocked();
     }
 
     @GuardedBy("ImfLock.class")
@@ -3620,6 +3681,14 @@
             return InputBindResult.INVALID_USER;
         }
 
+        final boolean shouldClearFlag = mImePlatformCompatUtils.shouldClearShowForcedFlag(cs.uid);
+        // In case mShowForced flag affects the next client to keep IME visible, when the current
+        // client is leaving due to the next focused client, we clear mShowForced flag when the
+        // next client's targetSdkVersion is T or higher.
+        if (mCurFocusedWindow != windowToken && mShowForced && shouldClearFlag) {
+            mShowForced = false;
+        }
+
         // cross-profile access is always allowed here to allow profile-switching.
         if (!mSettings.isCurrentProfile(userId)) {
             Slog.w(TAG, "A background user is requesting window. Hiding IME.");
@@ -4145,13 +4214,26 @@
      * @return {@link WindowManagerInternal#getInputMethodWindowVisibleHeight(int)}
      */
     @Override
-    public int getInputMethodWindowVisibleHeight() {
-        // TODO(yukawa): Should we verify the display ID?
-        final int curTokenDisplayId;
-        synchronized (ImfLock.class) {
-            curTokenDisplayId = mCurTokenDisplayId;
-        }
-        return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId);
+    @Deprecated
+    public int getInputMethodWindowVisibleHeight(@NonNull IInputMethodClient client) {
+        int callingUid = Binder.getCallingUid();
+        return Binder.withCleanCallingIdentity(() -> {
+            final int curTokenDisplayId;
+            synchronized (ImfLock.class) {
+                if (!canInteractWithImeLocked(callingUid, client,
+                        "getInputMethodWindowVisibleHeight")) {
+                    if (!mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.get(callingUid)) {
+                        EventLog.writeEvent(0x534e4554, "204906124", callingUid, "");
+                        mLoggedDeniedGetInputMethodWindowVisibleHeightForUid.put(callingUid, true);
+                    }
+                    return 0;
+                }
+                // This should probably use the caller's display id, but because this is unsupported
+                // and maintained only for compatibility, there's no point in fixing it.
+                curTokenDisplayId = mCurTokenDisplayId;
+            }
+            return mWindowManagerInternal.getInputMethodWindowVisibleHeight(curTokenDisplayId);
+        });
     }
 
     @Override
@@ -4652,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: {
@@ -4697,7 +4779,10 @@
                         return true;
                     }
                     final HandwritingModeController.HandwritingSession session =
-                            mHwController.startHandwritingSession(msg.arg1);
+                            mHwController.startHandwritingSession(
+                                    msg.arg1 /*requestId*/,
+                                    msg.arg2 /*pid*/,
+                                    mBindingController.getCurMethodUid());
                     if (session == null) {
                         Slog.e(TAG,
                                 "Failed to start handwriting session for requestId: " + msg.arg1);
@@ -4717,8 +4802,8 @@
     }
 
     @BinderThread
-    private void onStylusHandwritingReady(int requestId) {
-        mHandler.obtainMessage(MSG_START_HANDWRITING, requestId, 0 /* unused */).sendToTarget();
+    private void onStylusHandwritingReady(int requestId, int pid) {
+        mHandler.obtainMessage(MSG_START_HANDWRITING, requestId, pid).sendToTarget();
     }
 
     private void handleSetInteractive(final boolean interactive) {
@@ -4728,14 +4813,9 @@
 
             // Inform the current client of the change in active status
             if (mCurClient != null && mCurClient.client != null) {
-                boolean reportToImeController = false;
-                try {
-                    reportToImeController = mPlatformCompat.isChangeEnabledByUid(
-                            FINISH_INPUT_NO_FALLBACK_CONNECTION, getCurMethodUidLocked());
-                } catch (RemoteException e) {
-                }
                 scheduleSetActiveToClient(mCurClient, mIsInteractive, mInFullscreenMode,
-                        reportToImeController);
+                        mImePlatformCompatUtils.shouldFinishInputWithReportToIme(
+                                getCurMethodUidLocked()));
             }
         }
     }
@@ -4924,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);
@@ -4933,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")
@@ -6052,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 {
@@ -6304,8 +6382,8 @@
 
         @BinderThread
         @Override
-        public void onStylusHandwritingReady(int requestId) {
-            mImms.onStylusHandwritingReady(requestId);
+        public void onStylusHandwritingReady(int requestId, int pid) {
+            mImms.onStylusHandwritingReady(requestId, pid);
         }
 
         @BinderThread
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/integrity/parser/RuleBinaryParser.java b/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
index a290eb3..ea3a3d5 100644
--- a/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
+++ b/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
@@ -168,6 +168,7 @@
         switch (key) {
             case AtomicFormula.PACKAGE_NAME:
             case AtomicFormula.APP_CERTIFICATE:
+            case AtomicFormula.APP_CERTIFICATE_LINEAGE:
             case AtomicFormula.INSTALLER_NAME:
             case AtomicFormula.INSTALLER_CERTIFICATE:
             case AtomicFormula.STAMP_CERTIFICATE_HASH:
diff --git a/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java b/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java
index 01aee7b..db81393 100644
--- a/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java
+++ b/services/core/java/com/android/server/locales/LocaleManagerBackupHelper.java
@@ -34,7 +34,6 @@
 import android.os.Binder;
 import android.os.HandlerThread;
 import android.os.LocaleList;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.text.TextUtils;
@@ -45,7 +44,6 @@
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -89,32 +87,24 @@
     // SparseArray because it is more memory-efficient than a HashMap.
     private final SparseArray<StagedData> mStagedData;
 
-    private final PackageMonitor mPackageMonitor;
     private final BroadcastReceiver mUserMonitor;
 
     LocaleManagerBackupHelper(LocaleManagerService localeManagerService,
-            PackageManagerInternal pmInternal) {
+            PackageManagerInternal pmInternal, HandlerThread broadcastHandlerThread) {
         this(localeManagerService.mContext, localeManagerService, pmInternal, Clock.systemUTC(),
-                new SparseArray<>());
+                new SparseArray<>(), broadcastHandlerThread);
     }
 
     @VisibleForTesting LocaleManagerBackupHelper(Context context,
             LocaleManagerService localeManagerService,
-            PackageManagerInternal pmInternal, Clock clock, SparseArray<StagedData> stagedData) {
+            PackageManagerInternal pmInternal, Clock clock, SparseArray<StagedData> stagedData,
+            HandlerThread broadcastHandlerThread) {
         mContext = context;
         mLocaleManagerService = localeManagerService;
         mPackageManagerInternal = pmInternal;
         mClock = clock;
         mStagedData = stagedData;
 
-        HandlerThread broadcastHandlerThread = new HandlerThread(TAG,
-                Process.THREAD_PRIORITY_BACKGROUND);
-        broadcastHandlerThread.start();
-
-        mPackageMonitor = new PackageMonitorImpl();
-        mPackageMonitor.register(context, broadcastHandlerThread.getLooper(),
-                UserHandle.ALL,
-                true);
         mUserMonitor = new UserMonitor();
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_REMOVED);
@@ -127,11 +117,6 @@
         return mUserMonitor;
     }
 
-    @VisibleForTesting
-    PackageMonitor getPackageMonitor() {
-        return mPackageMonitor;
-    }
-
     /**
      * @see LocaleManagerInternal#getBackupPayload(int userId)
      */
@@ -267,6 +252,53 @@
         BackupManager.dataChanged(SYSTEM_BACKUP_PACKAGE_KEY);
     }
 
+    /**
+     * <p><b>Note:</b> This is invoked by service's common monitor
+     * {@link LocaleManagerServicePackageMonitor#onPackageAdded} when a new package is
+     * added on device.
+     */
+    void onPackageAdded(String packageName, int uid) {
+        try {
+            synchronized (mStagedDataLock) {
+                cleanStagedDataForOldEntriesLocked();
+
+                int userId = UserHandle.getUserId(uid);
+                if (mStagedData.contains(userId)) {
+                    // Perform lazy restore only if the staged data exists.
+                    doLazyRestoreLocked(packageName, userId);
+                }
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Exception in onPackageAdded.", e);
+        }
+    }
+
+    /**
+     * <p><b>Note:</b> This is invoked by service's common monitor
+     * {@link LocaleManagerServicePackageMonitor#onPackageDataCleared} when a package's data
+     * is cleared.
+     */
+    void onPackageDataCleared() {
+        try {
+            notifyBackupManager();
+        } catch (Exception e) {
+            Slog.e(TAG, "Exception in onPackageDataCleared.", e);
+        }
+    }
+
+    /**
+     * <p><b>Note:</b> This is invoked by service's common monitor
+     * {@link LocaleManagerServicePackageMonitor#onPackageRemoved} when a package is removed
+     * from device.
+     */
+    void onPackageRemoved() {
+        try {
+            notifyBackupManager();
+        } catch (Exception e) {
+            Slog.e(TAG, "Exception in onPackageRemoved.", e);
+        }
+    }
+
     private boolean isPackageInstalledForUser(String packageName, int userId) {
         PackageInfo pkgInfo = null;
         try {
@@ -395,48 +427,6 @@
     }
 
     /**
-     * Helper to monitor package states.
-     *
-     * <p>We're interested in package added, package data cleared and package removed events.
-     */
-    private final class PackageMonitorImpl extends PackageMonitor {
-        @Override
-        public void onPackageAdded(String packageName, int uid) {
-            try {
-                synchronized (mStagedDataLock) {
-                    cleanStagedDataForOldEntriesLocked();
-
-                    int userId = UserHandle.getUserId(uid);
-                    if (mStagedData.contains(userId)) {
-                        // Perform lazy restore only if the staged data exists.
-                        doLazyRestoreLocked(packageName, userId);
-                    }
-                }
-            } catch (Exception e) {
-                Slog.e(TAG, "Exception in onPackageAdded.", e);
-            }
-        }
-
-        @Override
-        public void onPackageDataCleared(String packageName, int uid) {
-            try {
-                notifyBackupManager();
-            } catch (Exception e) {
-                Slog.e(TAG, "Exception in onPackageDataCleared.", e);
-            }
-        }
-
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            try {
-                notifyBackupManager();
-            } catch (Exception e) {
-                Slog.e(TAG, "Exception in onPackageRemoved.", e);
-            }
-        }
-    }
-
-    /**
      * Performs lazy restore from the staged data.
      *
      * <p>This is invoked by the package monitor on the package added callback.
diff --git a/services/core/java/com/android/server/locales/LocaleManagerService.java b/services/core/java/com/android/server/locales/LocaleManagerService.java
index d459f8d..176c08c 100644
--- a/services/core/java/com/android/server/locales/LocaleManagerService.java
+++ b/services/core/java/com/android/server/locales/LocaleManagerService.java
@@ -29,6 +29,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.os.Binder;
+import android.os.HandlerThread;
 import android.os.LocaleList;
 import android.os.Process;
 import android.os.RemoteException;
@@ -38,14 +39,13 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.DumpUtils;
+import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import java.io.FileDescriptor;
-import java.io.PrintWriter;
 
 /**
  * The implementation of ILocaleManager.aidl.
@@ -62,6 +62,8 @@
 
     private LocaleManagerBackupHelper mBackupHelper;
 
+    private final PackageMonitor mPackageMonitor;
+
     public static final boolean DEBUG = false;
 
     public LocaleManagerService(Context context) {
@@ -71,15 +73,36 @@
         mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
+
+        HandlerThread broadcastHandlerThread = new HandlerThread(TAG,
+                Process.THREAD_PRIORITY_BACKGROUND);
+        broadcastHandlerThread.start();
+
+        SystemAppUpdateTracker systemAppUpdateTracker =
+                new SystemAppUpdateTracker(this);
+        broadcastHandlerThread.getThreadHandler().postAtFrontOfQueue(new Runnable() {
+            @Override
+            public void run() {
+                systemAppUpdateTracker.init();
+            }
+        });
+
         mBackupHelper = new LocaleManagerBackupHelper(this,
-                mPackageManagerInternal);
+                mPackageManagerInternal, broadcastHandlerThread);
+
+        mPackageMonitor = new LocaleManagerServicePackageMonitor(mBackupHelper,
+                systemAppUpdateTracker);
+        mPackageMonitor.register(context, broadcastHandlerThread.getLooper(),
+                UserHandle.ALL,
+                true);
     }
 
     @VisibleForTesting
     LocaleManagerService(Context context, ActivityTaskManagerInternal activityTaskManagerInternal,
             ActivityManagerInternal activityManagerInternal,
             PackageManagerInternal packageManagerInternal,
-            LocaleManagerBackupHelper localeManagerBackupHelper) {
+            LocaleManagerBackupHelper localeManagerBackupHelper,
+            PackageMonitor packageMonitor) {
         super(context);
         mContext = context;
         mBinderService = new LocaleManagerBinderService();
@@ -87,6 +110,7 @@
         mActivityManagerInternal = activityManagerInternal;
         mPackageManagerInternal = packageManagerInternal;
         mBackupHelper = localeManagerBackupHelper;
+        mPackageMonitor = packageMonitor;
     }
 
     @Override
@@ -130,11 +154,6 @@
         }
 
         @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            LocaleManagerService.this.dump(fd, pw, args);
-        }
-
-        @Override
         public void onShellCommand(FileDescriptor in, FileDescriptor out,
                 FileDescriptor err, String[] args, ShellCallback callback,
                 ResultReceiver resultReceiver) {
@@ -237,7 +256,7 @@
      * <p><b>Note:</b> This is can be used by installers to deal with cases such as
      * language-based APK Splits.
      */
-    private void notifyInstallerOfAppWhoseLocaleChanged(String appPackageName, int userId,
+    void notifyInstallerOfAppWhoseLocaleChanged(String appPackageName, int userId,
             LocaleList locales) {
         String installingPackageName = getInstallingPackageName(appPackageName);
         if (installingPackageName != null) {
@@ -262,7 +281,7 @@
         mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
     }
 
-    private static Intent createBaseIntent(String intentAction, String appPackageName,
+    static Intent createBaseIntent(String intentAction, String appPackageName,
             LocaleList locales) {
         return new Intent(intentAction)
                 .putExtra(Intent.EXTRA_PACKAGE_NAME, appPackageName)
@@ -397,7 +416,7 @@
     }
 
     @Nullable
-    private String getInstallingPackageName(String packageName) {
+    String getInstallingPackageName(String packageName) {
         try {
             return mContext.getPackageManager()
                     .getInstallSourceInfo(packageName).getInstallingPackageName();
@@ -407,14 +426,6 @@
         return null;
     }
 
-    /**
-     * Dumps useful info related to service.
-     */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        // TODO(b/201766221): Implement when there is state.
-    }
-
     private void logMetric(@NonNull AppLocaleChangedAtomRecord atomRecordForMetrics) {
         FrameworkStatsLog.write(FrameworkStatsLog.APPLICATION_LOCALES_CHANGED,
                 atomRecordForMetrics.mCallingUid,
diff --git a/services/core/java/com/android/server/locales/LocaleManagerServicePackageMonitor.java b/services/core/java/com/android/server/locales/LocaleManagerServicePackageMonitor.java
new file mode 100644
index 0000000..32080ef
--- /dev/null
+++ b/services/core/java/com/android/server/locales/LocaleManagerServicePackageMonitor.java
@@ -0,0 +1,63 @@
+/*
+ * 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.locales;
+
+import com.android.internal.content.PackageMonitor;
+
+/**
+ * Helper to monitor package states inside {@link LocaleManagerService}.
+ *
+ * <p> These listeners forward the call to different aspects of locale service that
+ * handle the business logic.
+ * <p> We're interested in the following events:
+ * <ul>
+ * <li> Package added
+ * <li> Package data cleared
+ * <li> Package removed
+ * <li> Package Updated
+ * </ul>
+ */
+final class LocaleManagerServicePackageMonitor extends PackageMonitor {
+    private LocaleManagerBackupHelper mBackupHelper;
+    private SystemAppUpdateTracker mSystemAppUpdateTracker;
+
+    LocaleManagerServicePackageMonitor(LocaleManagerBackupHelper localeManagerBackupHelper,
+            SystemAppUpdateTracker systemAppUpdateTracker) {
+        mBackupHelper = localeManagerBackupHelper;
+        mSystemAppUpdateTracker = systemAppUpdateTracker;
+    }
+
+    @Override
+    public void onPackageAdded(String packageName, int uid) {
+        mBackupHelper.onPackageAdded(packageName, uid);
+    }
+
+    @Override
+    public void onPackageDataCleared(String packageName, int uid) {
+        mBackupHelper.onPackageDataCleared();
+    }
+
+    @Override
+    public void onPackageRemoved(String packageName, int uid) {
+        mBackupHelper.onPackageRemoved();
+    }
+
+    @Override
+    public void onPackageUpdateFinished(String packageName, int uid) {
+        mSystemAppUpdateTracker.onPackageUpdateFinished(packageName, uid);
+    }
+}
diff --git a/services/core/java/com/android/server/locales/SystemAppUpdateTracker.java b/services/core/java/com/android/server/locales/SystemAppUpdateTracker.java
new file mode 100644
index 0000000..d13b1f4
--- /dev/null
+++ b/services/core/java/com/android/server/locales/SystemAppUpdateTracker.java
@@ -0,0 +1,249 @@
+/*
+ * 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.locales;
+
+import static com.android.server.locales.LocaleManagerService.DEBUG;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+import android.os.LocaleList;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.XmlUtils;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Track if a system app is being updated for the first time after the user completed device setup.
+ *
+ * <p> The entire operation is being done on a background thread from {@link LocaleManagerService}.
+ * If it is the first time that a system app is being updated, then it fetches the app-specific
+ * locales and sends a broadcast to the newly set installer of the app. It maintains a file to store
+ * the name of the apps that have been updated.
+ */
+public class SystemAppUpdateTracker {
+    private static final String TAG = "SystemAppUpdateTracker";
+    private static final String PACKAGE_XML_TAG = "package";
+    private static final String ATTR_NAME = "name";
+    private static final String SYSTEM_APPS_XML_TAG = "system_apps";
+
+    private final Context mContext;
+    private final LocaleManagerService mLocaleManagerService;
+    private final AtomicFile mUpdatedAppsFile;
+
+    // Lock used while writing to the file.
+    private final Object mFileLock = new Object();
+
+    // In-memory list of all the system apps that have been updated once after device setup.
+    // We do not need to store the userid->packages mapping because when updating a system app on
+    // one user updates for all users.
+    private final Set<String> mUpdatedApps = new HashSet<>();
+
+    SystemAppUpdateTracker(LocaleManagerService localeManagerService) {
+        this(localeManagerService.mContext, localeManagerService, new AtomicFile(
+                new File(Environment.getDataSystemDirectory(),
+                        /* child = */ "locale_manager_service_updated_system_apps.xml")));
+    }
+
+    @VisibleForTesting
+    SystemAppUpdateTracker(Context context, LocaleManagerService localeManagerService,
+            AtomicFile file) {
+        mContext = context;
+        mLocaleManagerService = localeManagerService;
+        mUpdatedAppsFile = file;
+    }
+
+    /**
+     * Loads the info of updated system apps from the file.
+     *
+     * <p> Invoked once during device boot from {@link LocaleManagerService} by a background thread.
+     */
+    void init() {
+        if (DEBUG) {
+            Slog.d(TAG, "Loading the app info from storage. ");
+        }
+        loadUpdatedSystemApps();
+    }
+
+    /**
+     * Reads the XML stored in the {@link #mUpdatedAppsFile} and populates it in the in-memory list
+     * {@link #mUpdatedApps}.
+     */
+    private void loadUpdatedSystemApps() {
+        if (!mUpdatedAppsFile.getBaseFile().exists()) {
+            if (DEBUG) {
+                Slog.d(TAG, "loadUpdatedSystemApps: File does not exist.");
+            }
+            return;
+        }
+        InputStream updatedAppNamesInputStream = null;
+        try  {
+            updatedAppNamesInputStream = mUpdatedAppsFile.openRead();
+            readFromXml(updatedAppNamesInputStream);
+        } catch (IOException | XmlPullParserException e) {
+            Slog.e(TAG, "loadUpdatedSystemApps: Could not parse storage file ", e);
+        } finally {
+            IoUtils.closeQuietly(updatedAppNamesInputStream);
+        }
+    }
+
+    /**
+     * Parses the update data from the serialized XML input stream.
+     */
+    private void readFromXml(InputStream updateInfoInputStream)
+            throws XmlPullParserException, IOException {
+        final TypedXmlPullParser parser = Xml.newFastPullParser();
+        parser.setInput(updateInfoInputStream, StandardCharsets.UTF_8.name());
+        XmlUtils.beginDocument(parser, SYSTEM_APPS_XML_TAG);
+        int depth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, depth)) {
+            if (parser.getName().equals(PACKAGE_XML_TAG)) {
+                String packageName = parser.getAttributeValue(/* namespace= */ null,
+                        ATTR_NAME);
+                if (!TextUtils.isEmpty(packageName)) {
+                    mUpdatedApps.add(packageName);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sends a broadcast to the newly set installer with app-locales if it is a system app being
+     * updated for the first time.
+     *
+     * <p><b>Note:</b> Invoked by service's common monitor
+     * {@link LocaleManagerServicePackageMonitor#onPackageUpdateFinished} when a package updated.
+     */
+    void onPackageUpdateFinished(String packageName, int uid) {
+        try {
+            if ((!mUpdatedApps.contains(packageName)) && isUpdatedSystemApp(packageName)) {
+                // If a system app is updated, verify that it has an installer-on-record.
+                String installingPackageName = mLocaleManagerService.getInstallingPackageName(
+                        packageName);
+                if (installingPackageName == null) {
+                    // We want to broadcast the locales info to the installer.
+                    // If this app does not have an installer then do nothing.
+                    return;
+                }
+
+                try {
+                    int userId = UserHandle.getUserId(uid);
+                    // Fetch the app-specific locales.
+                    // If non-empty then send the info to the installer.
+                    LocaleList appLocales = mLocaleManagerService.getApplicationLocales(
+                            packageName, userId);
+                    if (!appLocales.isEmpty()) {
+                        // The broadcast would be sent to the newly set installer of the
+                        // updated system app.
+                        mLocaleManagerService.notifyInstallerOfAppWhoseLocaleChanged(packageName,
+                                userId, appLocales);
+                    }
+                } catch (RemoteException e) {
+                    if (DEBUG) {
+                        Slog.d(TAG, "onPackageUpdateFinished: Error in fetching app locales");
+                    }
+                }
+                updateBroadcastedAppsList(packageName);
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Exception in onPackageUpdateFinished.", e);
+        }
+    }
+
+    /**
+     * Writes in-memory data {@link #mUpdatedApps} to the storage file in a synchronized manner.
+     */
+    private void updateBroadcastedAppsList(String packageName) {
+        synchronized (mFileLock) {
+            mUpdatedApps.add(packageName);
+            writeUpdatedAppsFileLocked();
+        }
+    }
+
+    private void writeUpdatedAppsFileLocked() {
+        FileOutputStream stream = null;
+        try {
+            stream = mUpdatedAppsFile.startWrite();
+            writeToXmlLocked(stream);
+            mUpdatedAppsFile.finishWrite(stream);
+        } catch (IOException e) {
+            mUpdatedAppsFile.failWrite(stream);
+            Slog.e(TAG, "Failed to persist the updated apps list", e);
+        }
+    }
+
+    /**
+     * Converts the list of updated app data into a serialized xml stream.
+     */
+    private void writeToXmlLocked(OutputStream stream) throws IOException {
+        final TypedXmlSerializer xml = Xml.newFastSerializer();
+        xml.setOutput(stream, StandardCharsets.UTF_8.name());
+        xml.startDocument(/* encoding= */ null,  /* standalone= */ true);
+        xml.startTag(/* namespace= */ null, SYSTEM_APPS_XML_TAG);
+
+        for (String packageName : mUpdatedApps) {
+            xml.startTag(/* namespace= */ null, PACKAGE_XML_TAG);
+            xml.attribute(/* namespace= */ null, ATTR_NAME, packageName);
+            xml.endTag(/* namespace= */ null, PACKAGE_XML_TAG);
+        }
+
+        xml.endTag(null, SYSTEM_APPS_XML_TAG);
+        xml.endDocument();
+    }
+
+    private boolean isUpdatedSystemApp(String packageName) {
+        ApplicationInfo appInfo = null;
+        try {
+            appInfo = mContext.getPackageManager().getApplicationInfo(packageName,
+                PackageManager.ApplicationInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY));
+        } catch (PackageManager.NameNotFoundException e) {
+            if (DEBUG) {
+                Slog.d(TAG, "isUpdatedSystemApp: Package not found " + packageName);
+            }
+        }
+        if (appInfo == null) {
+            return false;
+        }
+        return (appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
+    }
+
+    @VisibleForTesting
+    Set<String> getUpdatedApps() {
+        return mUpdatedApps;
+    }
+}
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index 45d9822..fac5106 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -1127,7 +1127,7 @@
             if (provider != null && !provider.equals(manager.getName())) {
                 continue;
             }
-            CallerIdentity identity = manager.getIdentity();
+            CallerIdentity identity = manager.getProviderIdentity();
             if (identity == null) {
                 continue;
             }
@@ -1149,7 +1149,7 @@
             return Collections.emptyList();
         }
 
-        CallerIdentity identity = manager.getIdentity();
+        CallerIdentity identity = manager.getProviderIdentity();
         if (identity == null) {
             return Collections.emptyList();
         }
@@ -1536,7 +1536,7 @@
         if (!enabled) {
             PackageTagsList.Builder builder = new PackageTagsList.Builder();
             for (LocationProviderManager manager : mProviderManagers) {
-                CallerIdentity identity = manager.getIdentity();
+                CallerIdentity identity = manager.getProviderIdentity();
                 if (identity != null) {
                     builder.add(identity.getPackageName(), identity.getAttributionTag());
                 }
@@ -1624,7 +1624,7 @@
                 if (provider != null && !provider.equals(manager.getName())) {
                     continue;
                 }
-                if (identity.equals(manager.getIdentity())) {
+                if (identity.equals(manager.getProviderIdentity())) {
                     return true;
                 }
             }
@@ -1665,7 +1665,7 @@
                 if (listener != null) {
                     ArraySet<Integer> uids = new ArraySet<>(mProviderManagers.size());
                     for (LocationProviderManager manager : mProviderManagers) {
-                        CallerIdentity identity = manager.getIdentity();
+                        CallerIdentity identity = manager.getProviderIdentity();
                         if (identity != null) {
                             uids.add(identity.getUid());
                         }
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
index 5093f5d..b6342a4 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java
@@ -19,7 +19,6 @@
 import static android.location.LocationManager.FUSED_PROVIDER;
 import static android.location.LocationManager.KEY_PROXIMITY_ENTERING;
 
-import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
 import static com.android.server.location.LocationPermissions.PERMISSION_FINE;
 
 import android.annotation.Nullable;
@@ -41,6 +40,7 @@
 import android.util.ArraySet;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.FgThread;
 import com.android.server.PendingIntentUtils;
 import com.android.server.location.LocationPermissions;
 import com.android.server.location.injector.Injector;
@@ -396,7 +396,7 @@
     protected boolean registerWithService(LocationRequest locationRequest,
             Collection<GeofenceRegistration> registrations) {
         getLocationManager().requestLocationUpdates(FUSED_PROVIDER, locationRequest,
-                DIRECT_EXECUTOR, this);
+                FgThread.getExecutor(), this);
         return true;
     }
 
diff --git a/services/core/java/com/android/server/location/provider/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
index 0b8f94c..721ef1e 100644
--- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java
+++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java
@@ -201,18 +201,54 @@
         @Override
         public void deliverOnLocationChanged(LocationResult locationResult,
                 @Nullable IRemoteCallback onCompleteCallback) throws RemoteException {
-            mListener.onLocationChanged(locationResult.asList(), onCompleteCallback);
+            try {
+                mListener.onLocationChanged(locationResult.asList(), onCompleteCallback);
+            } catch (RuntimeException e) {
+                // the only way a runtime exception can be thrown here is if the client is in the
+                // system server process (so that the binder call is executed directly, rather than
+                // asynchronously in another process), and the client is using a direct executor (so
+                // any client exceptions bubble directly back to us). we move any exception onto
+                // another thread so that it can't cause further problems
+                RuntimeException wrapper = new RuntimeException(e);
+                FgThread.getExecutor().execute(() -> {
+                    throw wrapper;
+                });
+            }
         }
 
         @Override
         public void deliverOnFlushComplete(int requestCode) throws RemoteException {
-            mListener.onFlushComplete(requestCode);
+            try {
+                mListener.onFlushComplete(requestCode);
+            } catch (RuntimeException e) {
+                // the only way a runtime exception can be thrown here is if the client is in the
+                // system server process (so that the binder call is executed directly, rather than
+                // asynchronously in another process), and the client is using a direct executor (so
+                // any client exceptions bubble directly back to us). we move any exception onto
+                // another thread so that it can't cause further problems
+                RuntimeException wrapper = new RuntimeException(e);
+                FgThread.getExecutor().execute(() -> {
+                    throw wrapper;
+                });
+            }
         }
 
         @Override
         public void deliverOnProviderEnabledChanged(String provider, boolean enabled)
                 throws RemoteException {
-            mListener.onProviderEnabledChanged(provider, enabled);
+            try {
+                mListener.onProviderEnabledChanged(provider, enabled);
+            } catch (RuntimeException e) {
+                // the only way a runtime exception can be thrown here is if the client is in the
+                // system server process (so that the binder call is executed directly, rather than
+                // asynchronously in another process), and the client is using a direct executor (so
+                // any client exceptions bubble directly back to us). we move any exception onto
+                // another thread so that it can't cause further problems
+                RuntimeException wrapper = new RuntimeException(e);
+                FgThread.getExecutor().execute(() -> {
+                    throw wrapper;
+                });
+            }
         }
     }
 
@@ -294,10 +330,23 @@
                 throws RemoteException {
             // ILocationCallback doesn't currently support completion callbacks
             Preconditions.checkState(onCompleteCallback == null);
-            if (locationResult != null) {
-                mCallback.onLocation(locationResult.getLastLocation());
-            } else {
-                mCallback.onLocation(null);
+
+            try {
+                if (locationResult != null) {
+                    mCallback.onLocation(locationResult.getLastLocation());
+                } else {
+                    mCallback.onLocation(null);
+                }
+            } catch (RuntimeException e) {
+                // the only way a runtime exception can be thrown here is if the client is in the
+                // system server process (so that the binder call is executed directly, rather than
+                // asynchronously in another process), and the client is using a direct executor (so
+                // any client exceptions bubble directly back to us). we move any exception onto
+                // another thread so that it can't cause further problems
+                RuntimeException wrapper = new RuntimeException(e);
+                FgThread.getExecutor().execute(() -> {
+                    throw wrapper;
+                });
             }
         }
 
@@ -1468,7 +1517,7 @@
         return mProvider.getState();
     }
 
-    public @Nullable CallerIdentity getIdentity() {
+    public @Nullable CallerIdentity getProviderIdentity() {
         return mProvider.getState().identity;
     }
 
@@ -1607,7 +1656,7 @@
 
     public @Nullable Location getLastLocation(LastLocationRequest request,
             CallerIdentity identity, @PermissionLevel int permissionLevel) {
-        request = calculateLastLocationRequest(request);
+        request = calculateLastLocationRequest(request, identity);
 
         if (!isActive(request.isBypass(), identity)) {
             return null;
@@ -1636,15 +1685,16 @@
         return location;
     }
 
-    private LastLocationRequest calculateLastLocationRequest(LastLocationRequest baseRequest) {
+    private LastLocationRequest calculateLastLocationRequest(LastLocationRequest baseRequest,
+            CallerIdentity identity) {
         LastLocationRequest.Builder builder = new LastLocationRequest.Builder(baseRequest);
 
         boolean locationSettingsIgnored = baseRequest.isLocationSettingsIgnored();
         if (locationSettingsIgnored) {
             // if we are not currently allowed use location settings ignored, disable it
             if (!mSettingsHelper.getIgnoreSettingsAllowlist().contains(
-                    getIdentity().getPackageName(), getIdentity().getAttributionTag())
-                    && !mLocationManagerInternal.isProvider(null, getIdentity())) {
+                    identity.getPackageName(), identity.getAttributionTag())
+                    && !mLocationManagerInternal.isProvider(null, identity)) {
                 locationSettingsIgnored = false;
             }
 
@@ -1658,7 +1708,7 @@
                 Log.e(TAG, "adas gnss bypass request received in non-gps provider");
                 adasGnssBypass = false;
             } else if (!mLocationSettings.getUserSettings(
-                    getIdentity().getUserId()).isAdasGnssLocationEnabled()) {
+                    identity.getUserId()).isAdasGnssLocationEnabled()) {
                 adasGnssBypass = false;
             }
 
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
index a102406..1203769 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -262,7 +262,7 @@
         long nextAlarmTime = strongAuthTime + dpm.getRequiredStrongAuthTimeout(null, userId);
 
         // schedule a new alarm listener for the user
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextAlarmTime,
                 STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm, mHandler);
     }
 
@@ -303,7 +303,7 @@
             alarm = new NonStrongBiometricTimeoutAlarmListener(userId);
             mNonStrongBiometricTimeoutAlarmListener.put(userId, alarm);
             // schedule a new alarm listener for the user
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
+            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextAlarmTime,
                     NON_STRONG_BIOMETRIC_TIMEOUT_ALARM_TAG, alarm, mHandler);
         }
 
@@ -394,7 +394,7 @@
         }
         // schedule a new alarm listener for the user
         if (DEBUG) Slog.d(TAG, "Schedule a new alarm for non-strong biometric idle timeout");
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextAlarmTime,
                 NON_STRONG_BIOMETRIC_IDLE_TIMEOUT_ALARM_TAG, alarm, mHandler);
     }
 
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..7116ca3
--- /dev/null
+++ b/services/core/java/com/android/server/logcat/LogAccessDialogActivity.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.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.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 = 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/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 074d891..92703ec 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -61,6 +61,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.NoSuchElementException;
 
 /**
  * This is the system implementation of a Session. Apps will interact with the
@@ -792,7 +793,10 @@
         }
         for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
             try {
+                holder.mCallback.asBinder().unlinkToDeath(holder.mDeathMonitor, 0);
                 holder.mCallback.onSessionDestroyed();
+            } catch (NoSuchElementException e) {
+                logCallbackException("error unlinking to binder death", holder, e);
             } catch (DeadObjectException e) {
                 logCallbackException("Removing dead callback in pushSessionDestroyed", holder, e);
             } catch (RemoteException e) {
@@ -1375,12 +1379,22 @@
                     return;
                 }
                 if (getControllerHolderIndexForCb(cb) < 0) {
-                    mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb,
-                            packageName, Binder.getCallingUid()));
+                    ISessionControllerCallbackHolder holder = new ISessionControllerCallbackHolder(
+                        cb, packageName, Binder.getCallingUid(), () -> unregisterCallback(cb));
+                    mControllerCallbackHolders.add(holder);
                     if (DEBUG) {
                         Log.d(TAG, "registering controller callback " + cb + " from controller"
                                 + packageName);
                     }
+                    // Avoid callback leaks
+                    try {
+                        // cb is not referenced outside of the MediaSessionRecord, so the death
+                        // handler won't prevent MediaSessionRecord to be garbage collected.
+                        cb.asBinder().linkToDeath(holder.mDeathMonitor, 0);
+                    } catch (RemoteException e) {
+                        unregisterCallback(cb);
+                        Log.w(TAG, "registerCallback failed to linkToDeath", e);
+                    }
                 }
             }
         }
@@ -1390,6 +1404,12 @@
             synchronized (mLock) {
                 int index = getControllerHolderIndexForCb(cb);
                 if (index != -1) {
+                    try {
+                        cb.asBinder().unlinkToDeath(
+                          mControllerCallbackHolders.get(index).mDeathMonitor, 0);
+                    } catch (NoSuchElementException e) {
+                        Log.w(TAG, "error unlinking to binder death", e);
+                    }
                     mControllerCallbackHolders.remove(index);
                 }
                 if (DEBUG) {
@@ -1600,12 +1620,14 @@
         private final ISessionControllerCallback mCallback;
         private final String mPackageName;
         private final int mUid;
+        private final IBinder.DeathRecipient mDeathMonitor;
 
         ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName,
-                int uid) {
+                int uid, IBinder.DeathRecipient deathMonitor) {
             mCallback = callback;
             mPackageName = packageName;
             mUid = uid;
+            mDeathMonitor = deathMonitor;
         }
     }
 
diff --git a/services/core/java/com/android/server/media/projection/OWNERS b/services/core/java/com/android/server/media/projection/OWNERS
index 7e7335d..9ca3910 100644
--- a/services/core/java/com/android/server/media/projection/OWNERS
+++ b/services/core/java/com/android/server/media/projection/OWNERS
@@ -1 +1,2 @@
 michaelwr@google.com
+santoscordon@google.com
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index 33ac6cd..c963154 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -77,6 +77,8 @@
     private static final int EVENT_FIREWALL_CHAIN_ENABLED = 12;
     private static final int EVENT_UPDATE_METERED_RESTRICTED_PKGS = 13;
     private static final int EVENT_APP_IDLE_WL_CHANGED = 14;
+    private static final int EVENT_METERED_ALLOWLIST_CHANGED = 15;
+    private static final int EVENT_METERED_DENYLIST_CHANGED = 16;
 
     private final LogBuffer mNetworkBlockedBuffer = new LogBuffer(MAX_NETWORK_BLOCKED_LOG_SIZE);
     private final LogBuffer mUidStateChangeBuffer = new LogBuffer(MAX_LOG_SIZE);
@@ -89,7 +91,7 @@
     void networkBlocked(int uid, @Nullable UidBlockedState uidBlockedState) {
         synchronized (mLock) {
             if (LOGD || uid == mDebugUid) {
-                Slog.d(TAG, "Blocked state of uid: " + uidBlockedState.toString());
+                Slog.d(TAG, "Blocked state of " + uid + ": " + uidBlockedState.toString());
             }
             if (uidBlockedState == null) {
                 mNetworkBlockedBuffer.networkBlocked(uid, BLOCKED_REASON_NONE, ALLOWED_REASON_NONE,
@@ -245,6 +247,24 @@
         }
     }
 
+    void meteredAllowlistChanged(int uid, boolean added) {
+        synchronized (mLock) {
+            if (LOGD || mDebugUid == uid) {
+                Slog.d(TAG, getMeteredAllowlistChangedLog(uid, added));
+            }
+            mEventsBuffer.meteredAllowlistChanged(uid, added);
+        }
+    }
+
+    void meteredDenylistChanged(int uid, boolean added) {
+        synchronized (mLock) {
+            if (LOGD || mDebugUid == uid) {
+                Slog.d(TAG, getMeteredDenylistChangedLog(uid, added));
+            }
+            mEventsBuffer.meteredDenylistChanged(uid, added);
+        }
+    }
+
     void setDebugUid(int uid) {
         mDebugUid = uid;
     }
@@ -320,6 +340,14 @@
         return "Firewall chain " + getFirewallChainName(chain) + " state: " + enabled;
     }
 
+    private static String getMeteredAllowlistChangedLog(int uid, boolean added) {
+        return "metered-allowlist for " + uid + " changed to " + added;
+    }
+
+    private static String getMeteredDenylistChangedLog(int uid, boolean added) {
+        return "metered-denylist for " + uid + " changed to " + added;
+    }
+
     private static String getFirewallChainName(int chain) {
         switch (chain) {
             case FIREWALL_CHAIN_DOZABLE:
@@ -520,6 +548,28 @@
             data.timeStamp = System.currentTimeMillis();
         }
 
+        public void meteredAllowlistChanged(int uid, boolean added) {
+            final Data data = getNextSlot();
+            if (data == null) return;
+
+            data.reset();
+            data.type = EVENT_METERED_ALLOWLIST_CHANGED;
+            data.ifield1 = uid;
+            data.bfield1 = added;
+            data.timeStamp = System.currentTimeMillis();
+        }
+
+        public void meteredDenylistChanged(int uid, boolean added) {
+            final Data data = getNextSlot();
+            if (data == null) return;
+
+            data.reset();
+            data.type = EVENT_METERED_DENYLIST_CHANGED;
+            data.ifield1 = uid;
+            data.bfield1 = added;
+            data.timeStamp = System.currentTimeMillis();
+        }
+
         public void reverseDump(IndentingPrintWriter pw) {
             final Data[] allData = toArray();
             for (int i = allData.length - 1; i >= 0; --i) {
@@ -567,6 +617,10 @@
                     return getUidFirewallRuleChangedLog(data.ifield1, data.ifield2, data.ifield3);
                 case EVENT_FIREWALL_CHAIN_ENABLED:
                     return getFirewallChainEnabledLog(data.ifield1, data.bfield1);
+                case EVENT_METERED_ALLOWLIST_CHANGED:
+                    return getMeteredAllowlistChangedLog(data.ifield1, data.bfield1);
+                case EVENT_METERED_DENYLIST_CHANGED:
+                    return getMeteredDenylistChangedLog(data.ifield1, data.bfield1);
                 default:
                     return String.valueOf(data.type);
             }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 60962b1..9f573c2 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -1011,10 +1011,10 @@
             final IntentFilter packageFilter = new IntentFilter();
             packageFilter.addAction(ACTION_PACKAGE_ADDED);
             packageFilter.addDataScheme("package");
-            mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
+            mContext.registerReceiverForAllUsers(mPackageReceiver, packageFilter, null, mHandler);
 
             // listen for UID changes to update policy
-            mContext.registerReceiver(
+            mContext.registerReceiverForAllUsers(
                     mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
 
             // listen for user changes to update policy
@@ -4864,7 +4864,7 @@
                     + ", isAllowed=" + isAllowed
                     + ", isRestrictedByAdmin=" + isRestrictedByAdmin
                     + ", oldBlockedState=" + previousUidBlockedState.toString()
-                    + ", newBlockedState="
+                    + ", newBlockedState=" + uidBlockedState.toString()
                     + ", oldBlockedMeteredReasons=" + NetworkPolicyManager.blockedReasonsToString(
                     uidBlockedState.blockedReasons & BLOCKED_METERED_REASON_MASK)
                     + ", oldBlockedMeteredEffectiveReasons="
@@ -5420,6 +5420,7 @@
         if (LOGV) Slog.v(TAG, "setMeteredNetworkDenylist " + uid + ": " + enable);
         try {
             mNetworkManager.setUidOnMeteredNetworkDenylist(uid, enable);
+            mLogger.meteredAllowlistChanged(uid, enable);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem setting denylist (" + enable + ") rules for " + uid, e);
         } catch (RemoteException e) {
@@ -5431,6 +5432,7 @@
         if (LOGV) Slog.v(TAG, "setMeteredNetworkAllowlist " + uid + ": " + enable);
         try {
             mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, enable);
+            mLogger.meteredDenylistChanged(uid, enable);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem setting allowlist (" + enable + ") rules for " + uid, e);
         } catch (RemoteException e) {
@@ -5563,7 +5565,9 @@
                     .setFirewallUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, uid,
                             FIREWALL_RULE_DEFAULT);
             mNetworkManager.setUidOnMeteredNetworkAllowlist(uid, false);
+            mLogger.meteredAllowlistChanged(uid, false);
             mNetworkManager.setUidOnMeteredNetworkDenylist(uid, false);
+            mLogger.meteredDenylistChanged(uid, false);
         } catch (IllegalStateException e) {
             Log.wtf(TAG, "problem resetting firewall uid rules for " + uid, e);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index 9cb8a01..4f26809 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -82,7 +82,7 @@
         }
         String combinedKey = generatePackageGroupKey(userId, sbn.getPackageName(), group);
         boolean needsOngoingFlag = notifications.size() > 0;
-        mCallback.updateAutogroupSummary(sbn.getKey(), needsOngoingFlag);
+        mCallback.updateAutogroupSummary(userId, sbn.getPackageName(), needsOngoingFlag);
     }
 
     public void onNotificationUpdated(StatusBarNotification childSbn,
@@ -211,6 +211,6 @@
         void removeAutoGroup(String key);
         void addAutoGroupSummary(int userId, String pkg, String triggeringKey);
         void removeAutoGroupSummary(int user, String pkg);
-        void updateAutogroupSummary(String key, boolean needsOngoingFlag);
+        void updateAutogroupSummary(int userId, String pkg, boolean needsOngoingFlag);
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 16b5fb1..265ad7d 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -775,7 +775,7 @@
 
         ArraySet<String> defaultDnds = mConditionProviders.getDefaultPackages();
         for (int i = 0; i < defaultDnds.size(); i++) {
-            allowDndPackage(defaultDnds.valueAt(i));
+            allowDndPackage(userId, defaultDnds.valueAt(i));
         }
 
         setDefaultAssistantForUser(userId);
@@ -875,9 +875,9 @@
         }
     }
 
-    private void allowDndPackage(String packageName) {
+    private void allowDndPackage(int userId, String packageName) {
         try {
-            getBinderService().setNotificationPolicyAccessGranted(packageName, true);
+            getBinderService().setNotificationPolicyAccessGrantedForUser(packageName, userId, true);
         } catch (RemoteException e) {
             e.printStackTrace();
         }
@@ -1623,18 +1623,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 +2121,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;
@@ -2587,19 +2569,11 @@
             }
 
             @Override
-            public void updateAutogroupSummary(String key, boolean needsOngoingFlag) {
-                String pkg;
-                synchronized (mNotificationLock) {
-                    NotificationRecord r = mNotificationsByKey.get(key);
-                    pkg = r != null && r.getSbn() != null ? r.getSbn().getPackageName() : null;
-                }
+            public void updateAutogroupSummary(int userId, String pkg, boolean needsOngoingFlag) {
                 boolean isAppForeground = pkg != null
                         && mActivityManager.getPackageImportance(pkg) == IMPORTANCE_FOREGROUND;
                 synchronized (mNotificationLock) {
-                    NotificationRecord r = mNotificationsByKey.get(key);
-                    if (r == null) return;
-                    updateAutobundledSummaryFlags(r.getUser().getIdentifier(),
-                            r.getSbn().getPackageName(), needsOngoingFlag, isAppForeground);
+                    updateAutobundledSummaryFlags(userId, pkg, needsOngoingFlag, isAppForeground);
                 }
             }
         });
@@ -3417,6 +3391,7 @@
                 }
                 mPermissionHelper.setNotificationPermission(
                         pkg, UserHandle.getUserId(uid), enabled, true);
+                sendAppBlockStateChangedBroadcast(pkg, uid, !enabled);
             } else {
                 synchronized (mNotificationLock) {
                     boolean wasEnabled = mPreferencesHelper.getImportance(pkg, uid)
@@ -3754,6 +3729,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));
@@ -3772,19 +3751,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
             }
@@ -4076,13 +4043,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
@@ -9658,27 +9624,8 @@
         if (uid == Process.ROOT_UID && ROOT_PKG.equals(pkg)) {
             return;
         }
-        try {
-            ApplicationInfo ai = mPackageManager.getApplicationInfo(
-                    pkg, 0, userId);
-            if (ai == null) {
-                throw new SecurityException("Unknown package " + pkg);
-            }
-            if (!UserHandle.isSameApp(ai.uid, uid)) {
-                throw new SecurityException("Calling uid " + uid + " gave package "
-                        + pkg + " which is owned by uid " + ai.uid);
-            }
-        } catch (RemoteException re) {
-            throw new SecurityException("Unknown package " + pkg + "\n" + re);
-        }
-    }
-
-    private boolean isCallerSameApp(String pkg) {
-        try {
-            checkCallerIsSameApp(pkg);
-            return true;
-        } catch (SecurityException e) {
-            return false;
+        if (!mPackageManagerInternal.isSameApp(pkg, uid, userId)) {
+            throw new SecurityException("Package " + pkg + " is not owned by uid " + uid);
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 66c7c50..bbdea32 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -478,6 +478,7 @@
         pw.println(prefix + "opPkg=" + getSbn().getOpPkg());
         pw.println(prefix + "icon=" + notification.getSmallIcon());
         pw.println(prefix + "flags=0x" + Integer.toHexString(notification.flags));
+        pw.println(prefix + "originalFlags=0x" + Integer.toHexString(mOriginalFlags));
         pw.println(prefix + "pri=" + notification.priority);
         pw.println(prefix + "key=" + getSbn().getKey());
         pw.println(prefix + "seen=" + mStats.hasSeen());
@@ -544,6 +545,7 @@
         if (notification == null) {
             pw.println(prefix + "None");
             return;
+
         }
         pw.println(prefix + "fullscreenIntent=" + notification.fullScreenIntent);
         pw.println(prefix + "contentIntent=" + notification.contentIntent);
diff --git a/services/core/java/com/android/server/notification/PermissionHelper.java b/services/core/java/com/android/server/notification/PermissionHelper.java
index 6b9e374..e551f10 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;
@@ -178,13 +179,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) {
@@ -278,6 +282,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");
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/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 9b10058..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;
@@ -348,6 +347,13 @@
     public abstract String getApexModuleNameForPackageName(String apexPackageName);
 
     /**
+     * Returns the package name of the active APEX whose name is {@code apexModuleName}. If not
+     * found, returns {@code null}.
+     */
+    @Nullable
+    public abstract String getActivePackageNameForApexModuleName(String apexModuleName);
+
+    /**
      * Copies the CE apex data directory for the given {@code userId} to a backup location, for use
      * in case of rollback.
      *
@@ -485,6 +491,12 @@
         private ArrayMap<String, String> mPackageNameToApexModuleName;
 
         /**
+         * Reverse mapping of {@link #mPackageNameToApexModuleName}, for active packages only.
+         */
+        @GuardedBy("mLock")
+        private ArrayMap<String, String> mApexModuleNameToActivePackageName;
+
+        /**
          * Whether an APEX package is active or not.
          *
          * @param packageInfo the package to check
@@ -552,6 +564,7 @@
             try {
                 mAllPackagesCache = new ArrayList<>();
                 mPackageNameToApexModuleName = new ArrayMap<>();
+                mApexModuleNameToActivePackageName = new ArrayMap<>();
                 allPkgs = waitForApexService().getAllPackages();
             } catch (RemoteException re) {
                 Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
@@ -634,6 +647,13 @@
                                             + packageInfo.packageName);
                         }
                         activePackagesSet.add(packageInfo.packageName);
+                        if (mApexModuleNameToActivePackageName.containsKey(ai.moduleName)) {
+                            throw new IllegalStateException(
+                                    "Two active packages have the same APEX module name: "
+                                            + ai.moduleName);
+                        }
+                        mApexModuleNameToActivePackageName.put(
+                                ai.moduleName, packageInfo.packageName);
                     }
                     if (ai.isFactory) {
                         // Don't throw when the duplicating APEX is VNDK APEX
@@ -813,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());
             }
         }
@@ -840,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());
             }
         }
@@ -967,6 +987,16 @@
         }
 
         @Override
+        @Nullable
+        public String getActivePackageNameForApexModuleName(String apexModuleName) {
+            synchronized (mLock) {
+                Preconditions.checkState(mApexModuleNameToActivePackageName != null,
+                        "APEX packages have not been scanned");
+                return mApexModuleNameToActivePackageName.get(apexModuleName);
+            }
+        }
+
+        @Override
         public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) {
             String apexModuleName;
             synchronized (mLock) {
@@ -1391,6 +1421,12 @@
         }
 
         @Override
+        @Nullable
+        public String getActivePackageNameForApexModuleName(String apexModuleName) {
+            return null;
+        }
+
+        @Override
         public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) {
             throw new UnsupportedOperationException();
         }
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/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index 31df0a5..ecbb4a9 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -557,7 +557,7 @@
 
     /** Gets the size of a package. */
     private long getPackageSize(PackageManagerService pm, String pkg) {
-        PackageInfo info = pm.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
+        PackageInfo info = pm.snapshotComputer().getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
         long size = 0;
         if (info != null && info.applicationInfo != null) {
             File path = Paths.get(info.applicationInfo.sourceDir).toFile();
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..6103d68 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -284,6 +284,21 @@
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     long updateFlagsForResolve(long flags, int userId, int callingUid, boolean wantInstantApps,
             boolean onlyExposedExplicitly, boolean isImplicitImageCaptureIntentAndNotSetByDpc);
+
+    /**
+     * 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
+     */
     @Computer.LiveImplementation(override = Computer.LiveImplementation.NOT_ALLOWED)
     void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt int userId,
             boolean requireFullPermission, boolean checkShell, String message);
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 30ac1b8..0c9855b 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -2161,8 +2161,8 @@
     private String[] getPackagesForUidInternal(int uid, int callingUid) {
         final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
         final int userId = UserHandle.getUserId(uid);
-        if (Process.isSupplemental(uid)) {
-            uid = getSupplementalProcessUid();
+        if (Process.isSdkSandboxUid(uid)) {
+            uid = getBaseSdkSandboxUid();
         }
         final int appId = UserHandle.getAppId(uid);
         return getPackagesForUidInternalBody(callingUid, userId, appId, isCallerInstantApp);
@@ -2401,9 +2401,9 @@
     }
 
     public final boolean isCallerSameApp(String packageName, int uid) {
-        if (Process.isSupplemental(uid)) {
+        if (Process.isSdkSandboxUid(uid)) {
             return (packageName != null
-                    && packageName.equals(mService.getSupplementalProcessPackageName()));
+                    && packageName.equals(mService.getSdkSandboxPackageName()));
         }
         AndroidPackage pkg = mPackages.get(packageName);
         return pkg != null
@@ -2812,8 +2812,8 @@
                     "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission");
         } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0
                 && isCallerSystemUser
-                && mUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
-            // If the caller wants all packages and has a restricted profile associated with it,
+                && mUserManager.hasProfile(UserHandle.USER_SYSTEM)) {
+            // If the caller wants all packages and has a profile associated with it,
             // then match all users. This is to make sure that launchers that need to access
             //work
             // profile apps don't start breaking. TODO: Remove this hack when launchers stop
@@ -4326,8 +4326,8 @@
         if (getInstantAppPackageName(callingUid) != null) {
             return null;
         }
-        if (Process.isSupplemental(uid)) {
-            uid = getSupplementalProcessUid();
+        if (Process.isSdkSandboxUid(uid)) {
+            uid = getBaseSdkSandboxUid();
         }
         final int callingUserId = UserHandle.getUserId(callingUid);
         final int appId = UserHandle.getAppId(uid);
@@ -4362,8 +4362,8 @@
         final String[] names = new String[uids.length];
         for (int i = uids.length - 1; i >= 0; i--) {
             int uid = uids[i];
-            if (Process.isSupplemental(uid)) {
-                uid = getSupplementalProcessUid();
+            if (Process.isSdkSandboxUid(uid)) {
+                uid = getBaseSdkSandboxUid();
             }
             final int appId = UserHandle.getAppId(uid);
             final Object obj = mSettings.getSettingBase(appId);
@@ -4411,8 +4411,8 @@
         if (getInstantAppPackageName(callingUid) != null) {
             return 0;
         }
-        if (Process.isSupplemental(uid)) {
-            uid = getSupplementalProcessUid();
+        if (Process.isSdkSandboxUid(uid)) {
+            uid = getBaseSdkSandboxUid();
         }
         final int callingUserId = UserHandle.getUserId(callingUid);
         final int appId = UserHandle.getAppId(uid);
@@ -4439,8 +4439,8 @@
         if (getInstantAppPackageName(callingUid) != null) {
             return 0;
         }
-        if (Process.isSupplemental(uid)) {
-            uid = getSupplementalProcessUid();
+        if (Process.isSdkSandboxUid(uid)) {
+            uid = getBaseSdkSandboxUid();
         }
         final int callingUserId = UserHandle.getUserId(callingUid);
         final int appId = UserHandle.getAppId(uid);
@@ -4466,8 +4466,8 @@
         if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return false;
         }
-        if (Process.isSupplemental(uid)) {
-            uid = getSupplementalProcessUid();
+        if (Process.isSdkSandboxUid(uid)) {
+            uid = getBaseSdkSandboxUid();
         }
         final int appId = UserHandle.getAppId(uid);
         final Object obj = mSettings.getSettingBase(appId);
@@ -5597,8 +5597,8 @@
 
     @Override
     public int getUidTargetSdkVersion(int uid) {
-        if (Process.isSupplemental(uid)) {
-            uid = getSupplementalProcessUid();
+        if (Process.isSdkSandboxUid(uid)) {
+            uid = getBaseSdkSandboxUid();
         }
         final int appId = UserHandle.getAppId(uid);
         final SettingBase settingBase = mSettings.getSettingBase(appId);
@@ -5628,8 +5628,8 @@
     @Nullable
     @Override
     public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
-        if (Process.isSupplemental(uid)) {
-            uid = getSupplementalProcessUid();
+        if (Process.isSdkSandboxUid(uid)) {
+            uid = getBaseSdkSandboxUid();
         }
         final int appId = UserHandle.getAppId(uid);
         final SettingBase settingBase = mSettings.getSettingBase(appId);
@@ -5661,8 +5661,8 @@
         }
     }
 
-    private int getSupplementalProcessUid() {
-        return getPackage(mService.getSupplementalProcessPackageName()).getUid();
+    private int getBaseSdkSandboxUid() {
+        return getPackage(mService.getSdkSandboxPackageName()).getUid();
     }
 
     @Nullable
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 58f9bb2c..664c7bb 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;
 
@@ -241,12 +243,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) {
@@ -508,6 +511,7 @@
             outInfo.mRemovedAppId = ps.getAppId();
             outInfo.mRemovedUsers = userIds;
             outInfo.mBroadcastUsers = userIds;
+            outInfo.mIsExternal = ps.isExternalStorage();
         }
     }
 
@@ -597,9 +601,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()
@@ -679,7 +680,8 @@
             return;
         }
 
-        if (!deleteAllUsers && mPm.getBlockUninstallForUser(internalPackageName, userId)) {
+        if (!deleteAllUsers && mPm.mIPackageManager
+                .getBlockUninstallForUser(internalPackageName, userId)) {
             mPm.mHandler.post(() -> {
                 try {
                     observer.onPackageDeleted(packageName,
@@ -699,11 +701,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;
             }
@@ -712,7 +717,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)) {
@@ -763,39 +768,40 @@
         }
         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 == mPm.mIPackageManager.getPackageUid(
+                mPm.mIPackageManager.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 == mPm.mIPackageManager
+                .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 == mPm.mIPackageManager
+                .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 == mPm.mIPackageManager.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 mPm.mIPackageManager.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);
             }
         }
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index 53eb9cf..74ea7cc 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -304,7 +304,8 @@
     /*package*/ boolean performDexOpt(DexoptOptions options) {
         if (mPm.getInstantAppPackageName(Binder.getCallingUid()) != null) {
             return false;
-        } else if (mPm.isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
+        } else if (mPm.mIPackageManager.isInstantApp(options.getPackageName(),
+                UserHandle.getCallingUserId())) {
             return false;
         }
 
@@ -460,7 +461,8 @@
                 | DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES
                 | DexoptOptions.DEXOPT_BOOT_COMPLETE
                 | (force ? DexoptOptions.DEXOPT_FORCE : 0);
-        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
+        return performDexOpt(new DexoptOptions(packageName, REASON_CMDLINE,
+                compilerFilter, null /* splitName */, flags));
     }
 
     // Sort apps by importance for dexopt ordering. Important apps are given
diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java
index 2b46ed4..05ef3c4 100644
--- a/services/core/java/com/android/server/pm/DumpHelper.java
+++ b/services/core/java/com/android/server/pm/DumpHelper.java
@@ -288,6 +288,8 @@
             ipw.decreaseIndent();
         }
 
+        final Computer snapshot = mPm.snapshotComputer();
+
         if (dumpState.isDumping(DumpState.DUMP_VERIFIERS)
                 && packageName == null) {
             final String requiredVerifierPackage = mPm.mRequiredVerifierPackage;
@@ -299,14 +301,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 +326,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();
@@ -405,7 +407,7 @@
         }
 
         if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
-            mPm.mComponentResolver.dumpContentProviders(mPm.snapshotComputer(), pw, dumpState,
+            mPm.mComponentResolver.dumpContentProviders(snapshot, pw, dumpState,
                     packageName);
         }
 
@@ -661,13 +663,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 +685,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/InitAndSystemPackageHelper.java b/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
index 06405ae..6dbe9b6 100644
--- a/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InitAndSystemPackageHelper.java
@@ -30,7 +30,6 @@
 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_FRAMEWORK_RES_SPLITS;
 
 import android.annotation.Nullable;
 import android.content.pm.parsing.ApkLiteParseUtils;
@@ -278,9 +277,8 @@
                     packageParser, executorService);
         }
 
-        List<File> frameworkSplits = getFrameworkResApkSplitFiles();
-        scanDirTracedLI(frameworkDir, frameworkSplits,
-                mSystemParseFlags | PARSE_FRAMEWORK_RES_SPLITS,
+        scanDirTracedLI(frameworkDir, null,
+                mSystemParseFlags,
                 mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
                 packageParser, executorService);
         if (!mPm.mPackages.containsKey("android")) {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index db0b0c58..8667ffd 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) {
@@ -951,10 +958,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;
@@ -1607,6 +1610,13 @@
                                         + oldSharedUid + " to " + newSharedUid);
                     }
 
+                    // APK should not re-join shared UID
+                    if (oldPackage.isLeavingSharedUid() && !parsedPackage.isLeavingSharedUid()) {
+                        throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED,
+                                "Package " + parsedPackage.getPackageName()
+                                        + " attempting to rejoin " + newSharedUid);
+                    }
+
                     // In case of rollback, remember per-user/profile install state
                     allUsers = mPm.mUserManager.getUserIds();
                     installedUsers = ps.queryInstalledUsers(allUsers, true);
@@ -1656,6 +1666,7 @@
                     final int userId = uninstalledUsers[i];
                     res.mRemovedInfo.mUninstallReasons.put(userId, ps.getUninstallReason(userId));
                 }
+                res.mRemovedInfo.mIsExternal = oldPackage.isExternalStorage();
 
                 sysPkg = oldPackage.isSystem();
                 if (sysPkg) {
@@ -1930,21 +1941,6 @@
                         }
                     }
                     // Successfully deleted the old package; proceed with replace.
-
-                    // If deleted package lived in a container, give users a chance to
-                    // relinquish resources before killing.
-                    if (oldPackage.isExternalStorage()) {
-                        if (DEBUG_INSTALL) {
-                            Slog.i(TAG, "upgrading pkg " + oldPackage
-                                    + " is ASEC-hosted -> UNAVAILABLE");
-                        }
-                        final int[] uidArray = new int[]{oldPackage.getUid()};
-                        final ArrayList<String> pkgList = new ArrayList<>(1);
-                        pkgList.add(oldPackage.getPackageName());
-                        mBroadcastHelper.sendResourcesChangedBroadcast(
-                                false, true, pkgList, uidArray, null);
-                    }
-
                     // Update the in-memory copy of the previous code paths.
                     PackageSetting ps1 = mPm.mSettings.getPackageLPr(
                             reconciledPkg.mPrepareResult.mExistingPackage.getPackageName());
@@ -2223,23 +2219,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
@@ -2609,8 +2590,6 @@
         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;
@@ -2640,6 +2619,17 @@
 
             // Send the removed broadcasts
             if (res.mRemovedInfo != null) {
+                if (res.mRemovedInfo.mIsExternal) {
+                    if (DEBUG_INSTALL) {
+                        Slog.i(TAG, "upgrading pkg " + res.mRemovedInfo.mRemovedPackage
+                                + " is ASEC-hosted -> UNAVAILABLE");
+                    }
+                    final int[] uidArray = new int[]{res.mRemovedInfo.mUid};
+                    final ArrayList<String> pkgList = new ArrayList<>(1);
+                    pkgList.add(res.mRemovedInfo.mRemovedPackage);
+                    mBroadcastHelper.sendResourcesChangedBroadcast(
+                            false, true, pkgList, uidArray, null);
+                }
                 res.mRemovedInfo.sendPackageRemovedBroadcasts(killApp, false /*removedBySystem*/);
             }
 
@@ -2707,10 +2697,7 @@
                 // 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);
@@ -2753,27 +2740,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*/,
@@ -2871,13 +2855,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) {
@@ -2886,9 +2871,13 @@
             }
         }
 
-        final boolean deferInstallObserver = succeeded && update && !killApp;
+        final boolean deferInstallObserver = succeeded && update;
         if (deferInstallObserver) {
-            mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
+            if (killApp) {
+                mPm.scheduleDeferredPendingKillInstallObserver(res, installObserver);
+            } else {
+                mPm.scheduleDeferredNoKillInstallObserver(res, installObserver);
+            }
         } else {
             mPm.notifyInstallObserver(res, installObserver);
         }
@@ -2980,7 +2969,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
@@ -2990,8 +2978,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,
@@ -3019,8 +3007,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(),
@@ -3048,7 +3035,7 @@
         return true;
     }
 
-    @GuardedBy({"mPm.mLock", "mPm.mInstallLock"})
+    @GuardedBy("mPm.mInstallLock")
     private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
             @ParsingPackageUtils.ParseFlags int parseFlags,
             @PackageManagerService.ScanFlags int scanFlags)
@@ -3141,27 +3128,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);
                 }
             }
@@ -3189,10 +3175,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 =
@@ -3215,13 +3201,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());
@@ -3255,7 +3240,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) {
@@ -3693,7 +3678,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/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index b028a2c..e8faca9 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -24,6 +24,7 @@
 import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD;
 import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_INSTALL_OBSERVER;
 import static com.android.server.pm.PackageManagerService.DEFERRED_NO_KILL_POST_DELETE;
+import static com.android.server.pm.PackageManagerService.DEFERRED_PENDING_KILL_INSTALL_OBSERVER;
 import static com.android.server.pm.PackageManagerService.DOMAIN_VERIFICATION;
 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS;
 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT;
@@ -126,10 +127,12 @@
                     }
                 }
             } break;
-            case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
-                String packageName = (String) msg.obj;
+            case DEFERRED_NO_KILL_INSTALL_OBSERVER:
+            case DEFERRED_PENDING_KILL_INSTALL_OBSERVER: {
+                final String packageName = (String) msg.obj;
                 if (packageName != null) {
-                    mPm.notifyInstallObserver(packageName);
+                    final boolean killApp = msg.what == DEFERRED_PENDING_KILL_INSTALL_OBSERVER;
+                    mPm.notifyInstallObserver(packageName, killApp);
                 }
             } break;
             case WRITE_SETTINGS: {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index fe2fe09..6613f01 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;
@@ -676,7 +676,7 @@
         String originatingPackageName = null;
         if (params.originatingUid != SessionParams.UID_UNKNOWN
                 && params.originatingUid != callingUid) {
-            String[] packages = mPm.getPackagesForUid(params.originatingUid);
+            String[] packages = mPm.mIPackageManager.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) {
+                && (mPm.mIPackageManager.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);
@@ -1153,7 +1154,8 @@
                     .setAdmin(callerPackageName)
                     .write();
         } else {
-            ApplicationInfo appInfo = mPm.getApplicationInfo(callerPackageName, 0, userId);
+            ApplicationInfo appInfo = mPm.mIPackageManager
+                    .getApplicationInfo(callerPackageName, 0, userId);
             if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
                 mContext.enforceCallingOrSelfPermission(Manifest.permission.REQUEST_DELETE_PACKAGES,
                         null);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index ced1c7d..35a7eaf 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;
@@ -462,7 +461,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 +816,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()
@@ -2009,12 +2009,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");
@@ -2301,6 +2302,15 @@
         });
     }
 
+    private static class InstallResult {
+        public final PackageInstallerSession session;
+        public final Bundle extras;
+        InstallResult(PackageInstallerSession session, Bundle extras) {
+            this.session = session;
+            this.extras = extras;
+        }
+    }
+
     /**
      * Stages installs and do cleanup accordingly depending on whether the installation is
      * successful or not.
@@ -2308,14 +2318,19 @@
      * @return a future that will be completed when the whole process is completed.
      */
     private CompletableFuture<Void> install() {
-        return installNonStaged().whenComplete((r, t) -> {
+        List<CompletableFuture<InstallResult>> futures = installNonStaged();
+        CompletableFuture<InstallResult>[] arr = new CompletableFuture[futures.size()];
+        return CompletableFuture.allOf(futures.toArray(arr)).whenComplete((r, t) -> {
             if (t == null) {
                 setSessionApplied();
-                dispatchSessionFinished(INSTALL_SUCCEEDED, "Session installed", null);
-                maybeFinishChildSessions(INSTALL_SUCCEEDED, "Session installed");
+                for (CompletableFuture<InstallResult> f : futures) {
+                    InstallResult result = f.join();
+                    result.session.dispatchSessionFinished(
+                            INSTALL_SUCCEEDED, "Session installed", result.extras);
+                }
             } 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());
@@ -2326,13 +2341,12 @@
     /**
      * Stages sessions (including child sessions if any) for install.
      *
-     * @return a future that will be completed when the whole session is completed (could be
-     *         success or failure).
+     * @return a list of futures to indicate the install results of each session.
      */
-    private CompletableFuture<Void> installNonStaged() {
+    private List<CompletableFuture<InstallResult>> installNonStaged() {
         try {
-            List<CompletableFuture<Void>> futures = new ArrayList<>();
-            CompletableFuture<Void> future = new CompletableFuture<>();
+            List<CompletableFuture<InstallResult>> futures = new ArrayList<>();
+            CompletableFuture<InstallResult> future = new CompletableFuture<>();
             futures.add(future);
             final InstallParams installingSession = makeInstallParams(future);
             if (isMultiPackage()) {
@@ -2354,12 +2368,11 @@
                 installingSession.installStage();
             }
 
-            CompletableFuture<Void>[] arr = new CompletableFuture[futures.size()];
-            return CompletableFuture.allOf(futures.toArray(arr));
+            return futures;
         } catch (PackageManagerException e) {
-            CompletableFuture<Void> future = new CompletableFuture<>();
-            future.completeExceptionally(e);
-            return future;
+            List<CompletableFuture<InstallResult>> futures = new ArrayList<>();
+            futures.add(CompletableFuture.failedFuture(e));
+            return futures;
         }
     }
 
@@ -2395,7 +2408,7 @@
      * @param future a future that will be completed when this session is completed.
      */
     @Nullable
-    private InstallParams makeInstallParams(CompletableFuture<Void> future)
+    private InstallParams makeInstallParams(CompletableFuture<InstallResult> future)
             throws PackageManagerException {
         synchronized (mLock) {
             if (!mSealed) {
@@ -2407,10 +2420,10 @@
 
         if (isMultiPackage()) {
             // Always treat parent session as success for it has nothing to install
-            future.complete(null);
+            future.complete(new InstallResult(this, null));
         } else if (isApexSession() && params.isStaged) {
             // Staged apex sessions have been handled by apexd
-            future.complete(null);
+            future.complete(new InstallResult(this, null));
             return null;
         }
 
@@ -2424,7 +2437,7 @@
             public void onPackageInstalled(String basePackageName, int returnCode, String msg,
                     Bundle extras) {
                 if (returnCode == INSTALL_SUCCEEDED) {
-                    future.complete(null);
+                    future.complete(new InstallResult(PackageInstallerSession.this, extras));
                 } else {
                     future.completeExceptionally(new PackageManagerException(returnCode, msg));
                 }
@@ -2497,7 +2510,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(),
@@ -2655,7 +2668,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);
 
@@ -2848,6 +2861,9 @@
                 inheritFileLocked(mResolvedBaseFile);
                 // Collect the requiredSplitTypes from base
                 CollectionUtils.addAll(requiredSplitTypes, existing.getBaseRequiredSplitTypes());
+            } else {
+                // Installing base.apk. Make sure the app is restarted.
+                params.setDontKillApp(false);
             }
 
             // Inherit splits if not overridden.
@@ -3544,6 +3560,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;
@@ -3766,8 +3787,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;
@@ -4023,7 +4044,7 @@
             mSessionReady = true;
             mSessionApplied = false;
             mSessionFailed = false;
-            mSessionErrorCode = SessionInfo.SESSION_NO_ERROR;
+            mSessionErrorCode = PackageManager.INSTALL_UNKNOWN;
             mSessionErrorMessage = "";
         }
         mCallback.onSessionChanged(this);
@@ -4051,7 +4072,7 @@
             mSessionReady = false;
             mSessionApplied = true;
             mSessionFailed = false;
-            mSessionErrorCode = SessionInfo.SESSION_NO_ERROR;
+            mSessionErrorCode = INSTALL_SUCCEEDED;
             mSessionErrorMessage = "";
             Slog.d(TAG, "Marking session " + sessionId + " as applied");
         }
@@ -4081,7 +4102,6 @@
     }
 
     /** {@hide} */
-    @SessionErrorCode
     int getSessionErrorCode() {
         synchronized (mLock) {
             return mSessionErrorCode;
@@ -4512,8 +4532,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 =
@@ -4569,7 +4590,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/PackageManagerLocal.java b/services/core/java/com/android/server/pm/PackageManagerLocal.java
new file mode 100644
index 0000000..7b76567
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageManagerLocal.java
@@ -0,0 +1,31 @@
+/*
+ * 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.SystemApi;
+
+/**
+ * In-process API for server side PackageManager related infrastructure.
+ *
+ * For now, avoiding adding methods that rely on package data until we solve the snapshot
+ * consistency problem.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+public interface PackageManagerLocal {
+}
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 c05faf1..e20a861 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -105,11 +105,6 @@
 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;
@@ -203,6 +198,7 @@
 import com.android.permission.persistence.RuntimePermissionsPersistence;
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
+import com.android.server.LocalManagerRegistry;
 import com.android.server.LocalServices;
 import com.android.server.LockGuard;
 import com.android.server.PackageWatchdog;
@@ -217,6 +213,7 @@
 import com.android.server.pm.dex.ArtManagerService;
 import com.android.server.pm.dex.ArtUtils;
 import com.android.server.pm.dex.DexManager;
+import com.android.server.pm.dex.DynamicCodeLogger;
 import com.android.server.pm.dex.ViewCompiler;
 import com.android.server.pm.parsing.PackageCacher;
 import com.android.server.pm.parsing.PackageInfoUtils;
@@ -247,8 +244,8 @@
 import com.android.server.pm.verify.domain.DomainVerificationService;
 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy;
 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyV1;
+import com.android.server.sdksandbox.SdkSandboxManagerLocal;
 import com.android.server.storage.DeviceStorageMonitorInternal;
-import com.android.server.supplementalprocess.SupplementalProcessManagerLocal;
 import com.android.server.utils.SnapshotCache;
 import com.android.server.utils.TimingsTraceAndSlog;
 import com.android.server.utils.Watchable;
@@ -333,8 +330,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;
@@ -647,6 +644,8 @@
      */
     boolean mPromoteSystemApps;
 
+    // TODO: Make IPackageManager reference private to hide discouraged APIs
+    final IPackageManagerImpl mIPackageManager;
     private final PackageManagerInternal mPmInternal;
     private final TestUtilityService mTestUtilityService;
 
@@ -840,6 +839,9 @@
     private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
             mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
 
+    private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
+            mPendingKillInstallObservers = Collections.synchronizedMap(new HashMap<>());
+
     // Internal interface for permission manager
     final PermissionManagerServiceInternal mPermissionManager;
 
@@ -887,9 +889,11 @@
     static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
     static final int DOMAIN_VERIFICATION = 27;
     static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28;
+    static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29;
 
     static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
     private static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
+    private static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS = 1000;
 
     static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
 
@@ -934,7 +938,7 @@
     final @Nullable String mOverlayConfigSignaturePackage;
     final @Nullable String mRecentsPackage;
     final @Nullable String mAmbientContextDetectionPackage;
-    private final @NonNull String mRequiredSupplementalProcessPackage;
+    private final @NonNull String mRequiredSdkSandboxPackage;
 
     @GuardedBy("mLock")
     private final PackageUsage mPackageUsage = new PackageUsage();
@@ -952,6 +956,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.
@@ -1053,7 +1058,7 @@
     private volatile Computer mSnapshotComputer;
 
     // A trampoline that directs callers to either the live or snapshot computer.
-    private final ComputerTracker mComputer = new ComputerTracker(this);
+    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
@@ -1161,18 +1166,10 @@
         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));
-        }
-    }
-
-    void notifyInstallObserver(String packageName) {
-        Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
-                mNoKillInstallObservers.remove(packageName);
+    void notifyInstallObserver(String packageName, boolean killApp) {
+        final Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
+                killApp ? mPendingKillInstallObservers.remove(packageName)
+                        : mNoKillInstallObservers.remove(packageName);
 
         if (pair != null) {
             notifyInstallObserver(pair.first, pair.second);
@@ -1211,21 +1208,20 @@
                 delay ? getPruneUnusedSharedLibrariesDelay() : 0);
     }
 
+    void scheduleDeferredPendingKillInstallObserver(PackageInstalledInfo info,
+            IPackageInstallObserver2 observer) {
+        final String packageName = info.mPkg.getPackageName();
+        mPendingKillInstallObservers.put(packageName, Pair.create(info, observer));
+        final Message message = mHandler.obtainMessage(DEFERRED_PENDING_KILL_INSTALL_OBSERVER,
+                packageName);
+        mHandler.sendMessageDelayed(message, DEFERRED_PENDING_KILL_INSTALL_OBSERVER_DELAY_MS);
+    }
+
     private static long getPruneUnusedSharedLibrariesDelay() {
         return SystemProperties.getLong("debug.pm.prune_unused_shared_libraries_delay",
                 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.
@@ -1273,7 +1269,8 @@
         if (applicationInfo == null) {
             throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
         }
-        final InstallSourceInfo installSourceInfo = getInstallSourceInfo(packageName);
+        final InstallSourceInfo installSourceInfo =
+                mIPackageManager.getInstallSourceInfo(packageName);
         final String installerPackageName =
                 installSourceInfo != null ? installSourceInfo.getInitiatingPackageName() : null;
 
@@ -1415,9 +1412,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",
@@ -1448,10 +1445,10 @@
                 (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(), pm.mIPackageManager,
+                        i.getPackageDexOptimizer(), i.getInstaller(), i.getInstallLock()),
+                (i, pm) -> new ArtManagerService(i.getContext(), pm.mIPackageManager,
                         i.getInstaller(), i.getInstallLock()),
-                (i, pm) -> new ArtManagerService(i.getContext(), pm, i.getInstaller(),
-                        i.getInstallLock()),
                 (i, pm) -> ApexManager.getInstance(),
                 (i, pm) -> new ViewCompiler(i.getInstallLock(), i.getInstaller()),
                 (i, pm) -> (IncrementalManager)
@@ -1473,7 +1470,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(), pm.mIPackageManager),
                 (i, pm) -> LegacyPermissionManagerService.create(i.getContext()),
                 (i, pm) -> domainVerificationService,
                 (i, pm) -> {
@@ -1534,10 +1531,11 @@
                 selinuxChangeListener);
 
         m.installAllowlistedSystemPackages();
-        ServiceManager.addService("package", m);
+        ServiceManager.addService("package", m.mIPackageManager);
         final PackageManagerNative pmn = new PackageManagerNative(m);
         ServiceManager.addService("package_native", pmn);
-        return m;
+        LocalManagerRegistry.addManager(PackageManagerLocal.class, m.new PackageManagerLocalImpl());
+        return Pair.create(m, m.mIPackageManager);
     }
 
     /** Install/uninstall system packages for all users based on their user-type, as applicable. */
@@ -1643,6 +1641,7 @@
         mPackageDexOptimizer = testParams.packageDexOptimizer;
         mPackageParserCallback = testParams.packageParserCallback;
         mPendingBroadcasts = testParams.pendingPackageBroadcasts;
+        mIPackageManager = new IPackageManagerImpl();
         mPmInternal = testParams.pmInternal;
         mTestUtilityService = testParams.testUtilityService;
         mProcessLoggingHandler = testParams.processLoggingHandler;
@@ -1667,7 +1666,7 @@
         mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;
         mOverlayConfigSignaturePackage = testParams.overlayConfigSignaturePackage;
         mResolveComponentName = testParams.resolveComponentName;
-        mRequiredSupplementalProcessPackage = testParams.requiredSupplementalProcessPackage;
+        mRequiredSdkSandboxPackage = testParams.requiredSdkSandboxPackage;
 
         mLiveComputer = createLiveComputer();
         mSnapshotComputer = null;
@@ -1695,6 +1694,8 @@
 
         mSharedLibraries.setDeletePackageHelper(mDeletePackageHelper);
 
+        mIntentResolverInterceptor = null;
+
         registerObservers(false);
         invalidatePackageInfoCache();
     }
@@ -1702,6 +1703,7 @@
     public PackageManagerService(PackageManagerServiceInjector injector, boolean onlyCore,
             boolean factoryTest, final String buildFingerprint, final boolean isEngBuild,
             final boolean isUserDebugBuild, final int sdkVersion, final String incrementalVersion) {
+        mIPackageManager = new IPackageManagerImpl();
         mIsEngBuild = isEngBuild;
         mIsUserDebugBuild = isUserDebugBuild;
         mSdkVersion = sdkVersion;
@@ -1753,7 +1755,7 @@
 
             @Override
             public boolean hasFeature(String feature) {
-                return PackageManagerService.this.hasSystemFeature(feature, 0);
+                return PackageManagerService.this.mIPackageManager.hasSystemFeature(feature, 0);
             }
         };
 
@@ -1980,11 +1982,13 @@
             mSetupWizardPackage = getSetupWizardPackageNameImpl(computer);
             mComponentResolver.fixProtectedFilterPriorities(mPmInternal.getSetupWizardPackageName());
 
-            mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
-            mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
+            mDefaultTextClassifierPackage = mIPackageManager.getDefaultTextClassifierPackageName();
+            mSystemTextClassifierPackageName =
+                    mIPackageManager.getSystemTextClassifierPackageName();
             mConfiguratorPackage = getDeviceConfiguratorPackageName();
-            mAppPredictionServicePackage = getAppPredictionServicePackageName();
-            mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
+            mAppPredictionServicePackage = mIPackageManager.getAppPredictionServicePackageName();
+            mIncidentReportApproverPackage =
+                    mIPackageManager.getIncidentReportApproverPackageName();
             mRetailDemoPackage = getRetailDemoPackageName();
             mOverlayConfigSignaturePackage = getOverlayConfigSignaturePackageName();
             mRecentsPackage = getRecentsPackageName();
@@ -2055,8 +2059,6 @@
                 }
             }
 
-            mPrepareAppDataFuture = mAppDataHelper.fixAppsDataOnBoot();
-
             // If this is first boot after an OTA, and a normal boot, then
             // we need to clear code cache directories.
             // Note that we do *not* clear the application profiles. These remain valid
@@ -2077,6 +2079,9 @@
                 ver.fingerprint = PackagePartitions.FINGERPRINT;
             }
 
+            // Defer the app data fixup until we are done with app data clearing above.
+            mPrepareAppDataFuture = mAppDataHelper.fixAppsDataOnBoot();
+
             // Legacy existing (installed before Q) non-system apps to hide
             // their icons in launcher.
             if (!mOnlyCore && mIsPreQUpgrade) {
@@ -2138,11 +2143,11 @@
             mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr(computer);
 
             mSettings.setPermissionControllerVersion(
-                    getPackageInfo(mRequiredPermissionControllerPackage, 0,
+                    mIPackageManager.getPackageInfo(mRequiredPermissionControllerPackage, 0,
                             UserHandle.USER_SYSTEM).getLongVersionCode());
 
-            // Resolve the supplemental process
-            mRequiredSupplementalProcessPackage = getRequiredSupplementalProcessPackageName();
+            // Resolve the sdk sandbox package
+            mRequiredSdkSandboxPackage = getRequiredSdkSandboxPackageName();
 
             // Initialize InstantAppRegistry's Instant App list for all users.
             for (AndroidPackage pkg : mPackages.values()) {
@@ -2186,7 +2191,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, mIPackageManager.getInstalledPackages(/*flags*/ 0, userId)
+                        .getList());
             }
             mDexManager.load(userPackages);
             if (mIsUpgrade) {
@@ -2222,6 +2228,8 @@
 
         mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
 
+        mIntentResolverInterceptor = new IntentResolverInterceptor(mContext);
+
         Slog.i(TAG, "Fix for b/169414761 is applied");
     }
 
@@ -2237,19 +2245,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.
@@ -2370,8 +2375,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 (mIPackageManager.checkPermission(
+                    android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, packageName,
+                    UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
                 continue;
             }
 
@@ -2399,8 +2405,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.DOMAIN_VERIFICATION_AGENT,
-                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
+            if (mIPackageManager.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;
@@ -2423,14 +2430,6 @@
         return null;
     }
 
-    @Override
-    public @Nullable ComponentName getInstantAppResolverComponent() {
-        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
-            return null;
-        }
-        return getInstantAppResolver();
-    }
-
     private @Nullable ComponentName getInstantAppResolver() {
         final String[] packageArray =
                 mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
@@ -2520,7 +2519,7 @@
         Iterator<ResolveInfo> iter = matches.iterator();
         while (iter.hasNext()) {
             final ResolveInfo rInfo = iter.next();
-            if (checkPermission(
+            if (mIPackageManager.checkPermission(
                     Manifest.permission.INSTALL_PACKAGES,
                     rInfo.activityInfo.packageName, 0) == PERMISSION_GRANTED || mIsEngBuild) {
                 continue;
@@ -2551,17 +2550,18 @@
         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)) {
-                Slog.wtf(TAG, "Package Manager Crash", e);
-            }
-            throw e;
-        }
+    /**
+     * @see #shouldFilterApplication(PackageStateInternal, int, ComponentName, int, int)
+     */
+    boolean shouldFilterApplication(
+            @Nullable PackageStateInternal ps, int callingUid, int userId) {
+        return mComputer.shouldFilterApplication(
+            ps, callingUid, userId);
+    }
+
+    private @PackageStartability int getPackageStartability(String packageName,
+            int callingUid, int userId) {
+        return mComputer.getPackageStartability(mSafeMode, packageName, callingUid, userId);
     }
 
     /**
@@ -2587,118 +2587,11 @@
         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
@@ -2706,18 +2599,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
@@ -2731,61 +2612,6 @@
                 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.
      */
@@ -2822,7 +2648,7 @@
             // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
             if (internalVolume && (aggressive || SystemProperties
                     .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
-                deletePreloadsFileCache();
+                mIPackageManager.deletePreloadsFileCache();
                 if (file.getUsableSpace() >= bytes) return;
             }
 
@@ -2961,17 +2787,6 @@
                 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
@@ -2984,33 +2799,6 @@
                 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,
@@ -3018,95 +2806,15 @@
         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) {
@@ -3120,202 +2828,18 @@
     }
 
     // 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 getSupplementalProcessPackageName() {
-        return mRequiredSupplementalProcessPackage;
+    public String getSdkSandboxPackageName() {
+        return mRequiredSdkSandboxPackage;
     }
 
     String getPackageInstallerPackageName() {
         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,
             Intent origIntent, String resolvedType, String callingPackage,
             @Nullable String callingFeatureId, boolean isRequesterInstantApp,
@@ -3370,38 +2894,6 @@
             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}.
@@ -3410,36 +2902,11 @@
         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) {
+    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(@NonNull Computer snapshot,
+            Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags,
+            @UserIdInt 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*/));
+                snapshot, intent, resolvedType, flags, userId, Binder.getCallingUid()));
     }
 
     @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
@@ -3450,163 +2917,16 @@
                 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);
-    }
-
     public static void reportSettingsProblem(int priority, String msg) {
         logCriticalInfo(priority, msg);
     }
@@ -3656,7 +2976,6 @@
                 requireFullPermission, checkShell, message);
     }
 
-    @Override
     public void performFstrimIfNeeded() {
         PackageManagerServiceUtils.enforceSystemOrRoot("Only the system can request fstrim");
 
@@ -3698,28 +3017,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();
@@ -3728,103 +3029,6 @@
         });
     }
 
-    @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;
     }
@@ -3855,67 +3059,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) {
@@ -4035,159 +3182,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);
@@ -4199,26 +3193,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)) {
@@ -4228,77 +3202,6 @@
         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) {
         if (callingUid == Process.ROOT_UID
@@ -4309,7 +3212,7 @@
 
         final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
         if (ownerPackage != null) {
-            final int ownerUid = getPackageUid(ownerPackage, 0, userId);
+            final int ownerUid = mIPackageManager.getPackageUid(ownerPackage, 0, userId);
             if (ownerUid == callingUid) {
                 return;
             }
@@ -4318,7 +3221,7 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
                 callingMethod);
 
-        final int packageUid = getPackageUid(callingPackage, 0, userId);
+        final int packageUid = mIPackageManager.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
@@ -4330,34 +3233,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
@@ -4412,67 +3287,6 @@
         }
     }
 
-    @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) {
         final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
         msg.arg1 = token;
@@ -4480,223 +3294,6 @@
         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
@@ -4775,21 +3372,12 @@
         }
     }
 
-    @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(
@@ -4806,15 +3394,14 @@
 
     boolean isCallerVerifier(int callingUid) {
         final int callingUserId = UserHandle.getUserId(callingUid);
-        return mRequiredVerifierPackage != null &&
-                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
+        return mRequiredVerifierPackage != null && callingUid == mIPackageManager.getPackageUid(
+                mRequiredVerifierPackage, 0, callingUserId);
     }
 
-    @Override
     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
         final int callingUid = Binder.getCallingUid();
-        if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
-                != PERMISSION_GRANTED) {
+        if (mIPackageManager.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");
@@ -4869,139 +3456,6 @@
         return mDevicePolicyManager;
     }
 
-    @Override
-    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
-            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.");
@@ -5084,106 +3538,14 @@
         }
     }
 
-    @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")
@@ -5203,109 +3565,6 @@
         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);
-    }
-
     /**
      * Variant that takes a {@link WatchedIntentFilter}
      */
@@ -5341,55 +3600,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) {
         // The system owns everything.
         if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
             return;
         }
-        final String[] callerPackageNames = getPackagesForUid(callingUid);
+        final String[] callerPackageNames = mIPackageManager.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 = mIPackageManager.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()) {
@@ -5420,11 +3649,6 @@
                 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);
@@ -5458,8 +3682,8 @@
         }
     }
 
-    private @NonNull String getRequiredSupplementalProcessPackageName() {
-        final Intent intent = new Intent(SupplementalProcessManagerLocal.SERVICE_INTERFACE);
+    private @NonNull String getRequiredSdkSandboxPackageName() {
+        final Intent intent = new Intent(SdkSandboxManagerLocal.SERVICE_INTERFACE);
 
         final List<ResolveInfo> matches = queryIntentServicesInternal(
                 intent,
@@ -5471,89 +3695,22 @@
         if (matches.size() == 1) {
             return matches.get(0).getComponentInfo().packageName;
         } else {
-            throw new RuntimeException("There should exactly one supplemental process; found "
+            throw new RuntimeException("There should exactly one sdk sandbox package; found "
                     + matches.size() + ": matches=" + matches);
         }
     }
 
-    @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());
@@ -5621,8 +3778,10 @@
         }
         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 (mIPackageManager.getPackageInfo(packageName, MATCH_FACTORY_ONLY,
+                    UserHandle.USER_SYSTEM) == null) {
+                PackageInfo packageInfo =
+                        mIPackageManager.getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
                 if (packageInfo != null) {
                     EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
                             "");
@@ -5635,39 +3794,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) {
@@ -5734,25 +3860,6 @@
         }
     }
 
-    @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();
@@ -5822,7 +3929,7 @@
                     continue;
                 }
                 final boolean isCallerTargetApp = ArrayUtils.contains(
-                        getPackagesForUid(callingUid), packageName);
+                        mIPackageManager.getPackagesForUid(callingUid), packageName);
                 final PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
                 // Limit who can change which apps
                 if (!isCallerTargetApp) {
@@ -6030,8 +4137,8 @@
             pkgSetting.setEnabled(newState, userId, callingPackage);
             if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
                     || newState == COMPONENT_ENABLED_STATE_DISABLED)
-                    && checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
-                    == PERMISSION_GRANTED) {
+                    && mIPackageManager.checkPermission(Manifest.permission.SUSPEND_APPS,
+                    packageName, userId) == PERMISSION_GRANTED) {
                 // This app should not generally be allowed to get disabled by the UI, but
                 // if it ever does, we don't want to end up with some of the user's apps
                 // permanently suspended.
@@ -6074,22 +4181,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,100 +4213,17 @@
         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");
@@ -6246,7 +4254,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();
@@ -6378,44 +4386,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) {
@@ -6454,9 +4429,9 @@
             return;
         }
         for (String packageName : apkList) {
-            setSystemAppHiddenUntilInstalled(packageName, true);
+            mIPackageManager.setSystemAppHiddenUntilInstalled(packageName, true);
             for (UserInfo user : mInjector.getUserManagerInternal().getUsers(false)) {
-                setSystemAppInstallState(packageName, false, user.id);
+                mIPackageManager.setSystemAppInstallState(packageName, false, user.id);
             }
         }
     }
@@ -6494,98 +4469,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) {
@@ -6645,18 +4528,6 @@
         }
     }
 
-    @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();
@@ -6673,45 +4544,10 @@
         }
     }
 
-    @Override
-    public IPackageInstaller getPackageInstaller() {
-        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);
         if (ps == null) {
@@ -6768,6 +4604,2515 @@
         return mComputer.canQueryPackage(callingUid, targetPackageName);
     }
 
+    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:
+        }
+    }
+
+    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);
+                }
+            });
+        }
+    }
+
+    public class IPackageManagerImpl extends IPackageManager.Stub {
+
+        @Override
+        public boolean activitySupportsIntent(ComponentName component, Intent intent,
+                String resolvedType) {
+            return mComputer.activitySupportsIntent(mResolveComponentName, component, intent,
+                    resolvedType);
+        }
+
+        @Override
+        public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
+                int sourceUserId, int targetUserId, int flags) {
+            PackageManagerService.this.addCrossProfileIntentFilter(
+                    new WatchedIntentFilter(intentFilter), ownerPackage, sourceUserId, targetUserId,
+                    flags);
+        }
+
+        // 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);
+        }
+
+        @Override
+        public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
+                int userId) {
+            mPreferredActivityHelper.addPersistentPreferredActivity(new WatchedIntentFilter(filter),
+                    activity, userId);
+        }
+
+        @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);
+        }
+
+        /*
+         * 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);
+        }
+
+        @Override
+        public boolean canRequestPackageInstalls(String packageName, int userId) {
+            return mComputer.canRequestPackageInstalls(packageName, Binder.getCallingUid(), userId,
+                    true /* throwIfPermNotDeclared*/);
+        }
+
+        @Override
+        public String[] canonicalToCurrentPackageNames(String[] names) {
+            return mComputer.canonicalToCurrentPackageNames(names);
+        }
+
+        @Override
+        public void checkPackageStartable(String packageName, int userId) {
+            PackageManagerService.this
+                    .checkPackageStartable(snapshotComputer(), packageName, userId);
+        }
+
+        // NOTE: Can't remove due to unsupported app usage
+        @Override
+        public int checkPermission(String permName, String pkgName, int userId) {
+            return PackageManagerService.this.checkPermission(permName, pkgName, userId);
+        }
+
+        @Override
+        public int checkSignatures(@NonNull String pkg1, @NonNull String pkg2) {
+            return mComputer.checkSignatures(pkg1, pkg2);
+        }
+
+        @Override
+        public int checkUidPermission(String permName, int uid) {
+            return mComputer.checkUidPermission(permName, uid);
+        }
+
+        @Override
+        public int checkUidSignatures(int uid1, int uid2) {
+            return mComputer.checkUidSignatures(uid1, uid2);
+        }
+
+        @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
+            });
+        }
+
+        @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);
+        }
+
+        @Override
+        public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
+            mPreferredActivityHelper.clearPackagePersistentPreferredActivities(packageName, userId);
+        }
+
+        @Override
+        public void clearPackagePreferredActivities(String packageName) {
+            mPreferredActivityHelper.clearPackagePreferredActivities(packageName);
+        }
+
+        @Override
+        public String[] currentToCanonicalPackageNames(String[] names) {
+            return mComputer.currentToCanonicalPackageNames(names);
+        }
+
+        @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 deleteExistingPackageAsUser(VersionedPackage versionedPackage,
+                final IPackageDeleteObserver2 observer, final int userId) {
+            PackageManagerService.this.deleteExistingPackageAsUser(versionedPackage, observer,
+                    userId);
+        }
+
+        @Override
+        public 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
+        public void deletePackageVersioned(VersionedPackage versionedPackage,
+                final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
+            PackageManagerService.this.deletePackageVersioned(versionedPackage, observer,
+                    userId, deleteFlags);
+        }
+
+        @Override
+        public 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);
+        }
+
+        @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 = mComputer.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);
+                }
+            });
+        }
+
+        @Override
+        public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
+            return mPreferredActivityHelper.findPersistentPreferredActivity(intent, userId);
+        }
+
+        @Override
+        public 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);
+        }
+
+        @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);
+            }
+        }
+
+        @Override
+        public void forceDexOpt(String packageName) {
+            mDexOptHelper.forceDexOpt(packageName);
+        }
+
+
+        @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 ActivityInfo getActivityInfo(ComponentName component,
+                @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
+            return mComputer.getActivityInfo(component, flags, userId);
+        }
+
+        @NonNull
+        @Override
+        public ParceledListSlice<IntentFilter> getAllIntentFilters(@NonNull String packageName) {
+            return mComputer.getAllIntentFilters(packageName);
+        }
+
+        @Override
+        public List<String> getAllPackages() {
+            return mComputer.getAllPackages();
+        }
+
+        // NOTE: Can't remove due to unsupported app usage
+        @NonNull
+        @Override
+        public String[] getAppOpPermissionPackages(@NonNull String permissionName) {
+            return mComputer.getAppOpPermissionPackages(permissionName);
+        }
+
+        @Override
+        public String getAppPredictionServicePackageName() {
+            return ensureSystemPackageName(
+                    getPackageFromComponentString(R.string.config_defaultAppPredictionService));
+        }
+
+        @PackageManager.EnabledState
+        @Override
+        public int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId) {
+            return mComputer.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
+        public boolean getApplicationHiddenSettingAsUser(@NonNull String packageName,
+                @UserIdInt int userId) {
+            return mComputer.getApplicationHiddenSettingAsUser(packageName, userId);
+        }
+
+        @Override
+        public ApplicationInfo getApplicationInfo(String packageName,
+                @PackageManager.ApplicationInfoFlagsBits long flags, int userId) {
+            return mComputer.getApplicationInfo(packageName, flags, userId);
+        }
+
+        @Override
+        public IArtManager getArtManager() {
+            return mArtManagerService;
+        }
+
+        @Override
+        public @Nullable String getAttentionServicePackageName() {
+            return ensureSystemPackageName(
+                    getPackageFromComponentString(R.string.config_defaultAttentionService));
+        }
+
+        @Override
+        public boolean getBlockUninstallForUser(@NonNull String packageName, @UserIdInt int userId) {
+            return mComputer.getBlockUninstallForUser(packageName, userId);
+        }
+
+        @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 int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
+            return mComputer.getComponentEnabledSetting(component, Binder.getCallingUid(), userId);
+        }
+
+        @Override
+        public String getContentCaptureServicePackageName() {
+            return ensureSystemPackageName(
+                    getPackageFromComponentString(R.string.config_defaultContentCaptureService));
+        }
+
+        @Nullable
+        @Override
+        public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
+                @NonNull String packageName, @PackageManager.PackageInfoFlagsBits long flags,
+                @NonNull int userId) {
+            return mComputer.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
+        public byte[] getDefaultAppsBackup(int userId) {
+            return mPreferredActivityHelper.getDefaultAppsBackup(userId);
+        }
+
+        @Override
+        public String getDefaultTextClassifierPackageName() {
+            return ensureSystemPackageName(
+                    mContext.getString(R.string.config_servicesExtensionPackage));
+        }
+
+        @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 int getFlagsForUid(int uid) {
+            return mComputer.getFlagsForUid(uid);
+        }
+
+        @Nullable
+        @Override
+        public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) {
+            return mComputer.getHarmfulAppWarning(packageName, userId);
+        }
+
+        @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 ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
+            if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+                return null;
+            }
+            return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
+        }
+
+        public String getIncidentReportApproverPackageName() {
+            return ensureSystemPackageName(mContext.getString(
+                    R.string.config_incidentReportApproverPackage));
+        }
+
+        @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);
+        }
+
+        @PackageManager.InstallReason
+        @Override
+        public int getInstallReason(@NonNull String packageName, @UserIdInt int userId) {
+            return mComputer.getInstallReason(packageName, userId);
+        }
+
+        @Override
+        @Nullable
+        public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
+            return mComputer.getInstallSourceInfo(packageName);
+        }
+
+        @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 List<ModuleInfo> getInstalledModules(int flags) {
+            return mModuleInfoProvider.getInstalledModules(flags);
+        }
+
+        @Override
+        public ParceledListSlice<PackageInfo> getInstalledPackages(
+                @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+            return mComputer.getInstalledPackages(flags, userId);
+        }
+
+        @Nullable
+        @Override
+        public String getInstallerPackageName(@NonNull String packageName) {
+            return mComputer.getInstallerPackageName(packageName);
+        }
+
+        @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 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 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);
+        }
+
+        @Override
+        public ComponentName getInstantAppInstallerComponent() {
+            if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+                return null;
+            }
+            return mInstantAppInstallerActivity == null
+                    ? null : mInstantAppInstallerActivity.getComponentName();
+        }
+
+        @Override
+        public @Nullable ComponentName getInstantAppResolverComponent() {
+            if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+                return null;
+            }
+            return getInstantAppResolver();
+        }
+
+        @Override
+        public ComponentName getInstantAppResolverSettingsComponent() {
+            return mInstantAppResolverSettingsComponent;
+        }
+
+        @Override
+        public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
+            if (PackageManagerService.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;
+        }
+
+        @Nullable
+        @Override
+        public InstrumentationInfo getInstrumentationInfo(@NonNull ComponentName component, int flags) {
+            return mComputer.getInstrumentationInfo(component, flags);
+        }
+
+        @Deprecated
+        @Override
+        public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
+                String packageName) {
+            return ParceledListSlice.emptyList();
+        }
+
+        @Deprecated
+        @Override
+        public int getIntentVerificationStatus(String packageName, int userId) {
+            return mDomainVerificationManager.getLegacyState(packageName, userId);
+        }
+
+        @Nullable
+        @Override
+        public KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias) {
+            return mComputer.getKeySetByAlias(packageName, alias);
+        }
+
+        @Override
+        public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
+            return mPreferredActivityHelper.getLastChosenActivity(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) {
+            enforceOwnerRights(packageName, Binder.getCallingUid());
+            return getMimeGroupInternal(packageName, mimeGroup);
+        }
+
+        @Override
+        public ModuleInfo getModuleInfo(String packageName, @PackageManager.ModuleInfoFlags int flags) {
+            return PackageManagerService.this.getModuleInfo(packageName, flags);
+        }
+
+        @Override
+        public int getMoveStatus(int moveId) {
+            mContext.enforceCallingOrSelfPermission(
+                    Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+            return mMoveCallbacks.mLastStatus.get(moveId);
+        }
+
+        @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[] getPackageGids(String packageName, @PackageManager.PackageInfoFlagsBits long flags,
+                int userId) {
+            return mComputer.getPackageGids(packageName, flags, 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);
+        }
+
+        @Override
+        public IPackageInstaller getPackageInstaller() {
+            // Return installer service for internal calls.
+            if (PackageManagerServiceUtils.isSystemOrRoot()) {
+                return mInstallerService;
+            }
+            // Return null for InstantApps.
+            if (snapshotComputer().getInstantAppPackageName(Binder.getCallingUid()) != null) {
+                return null;
+            }
+            return mInstallerService;
+        }
+
+        @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!");
+        }
+
+        @Override
+        public int getPackageUid(@NonNull String packageName,
+                @PackageManager.PackageInfoFlagsBits long flags, @UserIdInt int userId) {
+            return mComputer.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
+        public String[] getPackagesForUid(int uid) {
+            final int callingUid = Binder.getCallingUid();
+            final int userId = UserHandle.getUserId(uid);
+            mComputer.enforceCrossUserOrProfilePermission(callingUid, userId,
+                    /* requireFullPermission */ false,
+                    /* checkShell */ false, "getPackagesForUid");
+            return mComputer.getPackagesForUid(uid);
+        }
+
+        @Override
+        public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
+                @NonNull String[] permissions, @PackageManager.PackageInfoFlagsBits long flags,
+                @UserIdInt int userId) {
+            return mComputer.getPackagesHoldingPermissions(permissions, flags, userId);
+        }
+
+        @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");
+        }
+
+        // NOTE: Can't remove due to unsupported app usage
+        @Override
+        public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
+            return PackageManagerService.this.getPermissionGroupInfo(groupName, flags);
+        }
+
+        @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 int getPreferredActivities(List<IntentFilter> outFilters,
+                List<ComponentName> outActivities, String packageName) {
+            return mPreferredActivityHelper.getPreferredActivities(outFilters, outActivities,
+                    packageName, snapshotComputer());
+        }
+
+        /**
+         * 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 int getPrivateFlagsForUid(int uid) {
+            return mComputer.getPrivateFlagsForUid(uid);
+        }
+
+        @Override
+        public PackageManager.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);
+        }
+
+        @Nullable
+        @Override
+        public ProviderInfo getProviderInfo(@NonNull ComponentName component,
+                @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
+            return mComputer.getProviderInfo(component, flags, userId);
+        }
+
+        @Override
+        public ActivityInfo getReceiverInfo(ComponentName component,
+                @PackageManager.ComponentInfoFlagsBits long flags, int userId) {
+            return mComputer.getReceiverInfo(component, flags, userId);
+        }
+
+        @Override
+        public @Nullable String getRotationResolverPackageName() {
+            return ensureSystemPackageName(
+                    getPackageFromComponentString(R.string.config_defaultRotationResolverService));
+        }
+
+        @Override
+        public int getRuntimePermissionsVersion(@UserIdInt int userId) {
+            Preconditions.checkArgumentNonnegative(userId);
+            enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
+                    "getRuntimePermissionVersion");
+            return mSettings.getDefaultRuntimePermissionsVersion(userId);
+        }
+
+        @Nullable
+        @Override
+        public ServiceInfo getServiceInfo(@NonNull ComponentName component,
+                @PackageManager.ComponentInfoFlagsBits long flags, @UserIdInt int userId) {
+            return mComputer.getServiceInfo(component, flags, userId);
+        }
+
+        @Override
+        public @NonNull String getServicesSystemSharedLibraryPackageName() {
+            return mServicesExtensionPackageName;
+        }
+
+        @Override
+        public String getSetupWizardPackageName() {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                throw new SecurityException("Non-system caller");
+            }
+            return mPmInternal.getSetupWizardPackageName();
+        }
+
+        @Override
+        public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
+                @PackageManager.PackageInfoFlagsBits long flags, int userId) {
+            return mComputer.getSharedLibraries(packageName, flags, userId);
+        }
+
+        @Override
+        public @NonNull String getSharedSystemSharedLibraryPackageName() {
+            return mSharedSystemSharedLibraryPackageName;
+        }
+
+        @Nullable
+        @Override
+        public KeySet getSigningKeySet(@NonNull String packageName) {
+            return mComputer.getSigningKeySet(packageName);
+        }
+
+        @Override
+        public String getSplashScreenTheme(@NonNull String packageName, int userId) {
+            PackageStateInternal packageState =
+                    getPackageStateInstalledFiltered(packageName, Binder.getCallingUid(), userId);
+            return packageState == null ? null
+                    : packageState.getUserStateOrDefault(userId).getSplashScreenTheme();
+        }
+
+        @Override
+        public String getSdkSandboxPackageName() {
+            return mRequiredSdkSandboxPackage;
+        }
+
+        @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 @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 getSystemCaptionsServicePackageName() {
+            return ensureSystemPackageName(
+                    getPackageFromComponentString(R.string.config_defaultSystemCaptionsService));
+        }
+
+        @Nullable
+        @Override
+        public String[] getSystemSharedLibraryNames() {
+            return mComputer.getSystemSharedLibraryNames();
+        }
+
+        @Override
+        public String getSystemTextClassifierPackageName() {
+            return ensureSystemPackageName(
+                    mContext.getString(R.string.config_defaultTextClassifierPackage));
+        }
+
+        @Override
+        public int getTargetSdkVersion(@NonNull String packageName)  {
+            return mComputer.getTargetSdkVersion(packageName);
+        }
+
+        @Override
+        public int getUidForSharedUser(@NonNull String sharedUserName) {
+            return mComputer.getUidForSharedUser(sharedUserName);
+        }
+
+        @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 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 void grantImplicitAccess(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 */);
+        }
+
+        // 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 hasSigningCertificate(@NonNull String packageName, @NonNull byte[] certificate,
+                @PackageManager.CertificateInputType int type) {
+            return mComputer.hasSigningCertificate(packageName, certificate, type);
+        }
+
+        @Override
+        public boolean hasSystemFeature(String name, int version) {
+            return PackageManagerService.this.hasSystemFeature(name, version);
+        }
+
+        @Override
+        public boolean hasSystemUidErrors() {
+            // allow instant applications
+            return false;
+        }
+
+        @Override
+        public boolean hasUidSigningCertificate(int uid, @NonNull byte[] certificate,
+                @PackageManager.CertificateInputType int type) {
+            return mComputer.hasUidSigningCertificate(uid, certificate, type);
+        }
+
+        @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 isDeviceUpgrading() {
+            return PackageManagerService.this.isDeviceUpgrading();
+        }
+
+        @Override
+        public boolean isFirstBoot() {
+            return PackageManagerService.this.isFirstBoot();
+        }
+
+        @Override
+        public boolean isInstantApp(String packageName, int userId) {
+            return mComputer.isInstantApp(packageName, userId);
+        }
+
+        @Override
+        public boolean isOnlyCoreApps() {
+            return PackageManagerService.this.isOnlyCoreApps();
+        }
+
+        @Override
+        public boolean isPackageAvailable(String packageName, int userId) {
+            return mComputer.isPackageAvailable(packageName, userId);
+        }
+
+        @Override
+        public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
+            return PackageManagerService.this.isPackageDeviceAdminOnAnyUser(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);
+        }
+
+        @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 boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId) {
+            return mComputer.isPackageSuspendedForUser(packageName, 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 boolean isSafeMode() {
+            // allow instant applications
+            return mSafeMode;
+        }
+
+        @Override
+        public boolean isStorageLow() {
+            return PackageManagerService.this.isStorageLow();
+        }
+
+        @Override
+        public boolean isUidPrivileged(int uid) {
+            return mComputer.isUidPrivileged(uid);
+        }
+
+        /**
+         * 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);
+        }
+
+        @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 = 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);
+            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);
+        }
+
+        @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);
+        }
+
+        /**
+         * 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);
+        }
+
+        @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);
+        }
+
+        @NonNull
+        @Override
+        public ParceledListSlice<InstrumentationInfo> queryInstrumentation(
+                @NonNull String targetPackage, int flags) {
+            return mComputer.queryInstrumentation(targetPackage, flags);
+        }
+
+        @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);
+            }
+        }
+
+        @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> queryIntentContentProviders(Intent intent,
+                String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+            return new ParceledListSlice<>(mResolveIntentHelper.queryIntentContentProvidersInternal(
+                    snapshotComputer(), 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 @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
+                String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            return new ParceledListSlice<>(snapshotComputer().queryIntentServicesInternal(
+                    intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
+        }
+
+        @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 List<PackageManager.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);
+        }
+
+        @Deprecated
+        public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
+            mComputer.querySyncProviders(mSafeMode, outNames, outInfo);
+        }
+
+        /**
+         * 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);
+        }
+
+        @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(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);
+        }
+
+        // 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);
+        }
+
+        @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 resetApplicationPreferences(int userId) {
+            mPreferredActivityHelper.resetApplicationPreferences(userId);
+        }
+
+        @Override
+        public ProviderInfo resolveContentProvider(String name,
+                @PackageManager.ResolveInfoFlagsBits long flags, int userId) {
+            return mComputer.resolveContentProvider(name, flags, userId, Binder.getCallingUid());
+        }
+
+        @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 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 void restoreDefaultApps(byte[] backup, int userId) {
+            mPreferredActivityHelper.restoreDefaultApps(backup, userId);
+        }
+
+        @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 restorePreferredActivities(byte[] backup, int userId) {
+            mPreferredActivityHelper.restorePreferredActivities(backup, 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) {
+            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();
+            }
+        }
+
+        @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();
+            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 boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
+                int userId) {
+            mContext.enforceCallingOrSelfPermission(
+                    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(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");
+            if (restrictionFlags != 0
+                    && !mSuspendPackageHelper.isSuspendAllowedForUser(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<>();
+            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(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);
+
+            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);
+        }
+
+        @Override
+        public void setHomeActivity(ComponentName comp, int userId) {
+            mPreferredActivityHelper.setHomeActivity(comp, 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 = 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(
+                                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 = 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;
+            }
+
+            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 void setKeepUninstalledPackages(List<String> packageList) {
+            mContext.enforceCallingPermission(
+                    Manifest.permission.KEEP_UNINSTALLED_PACKAGES,
+                    "setKeepUninstalledPackages requires KEEP_UNINSTALLED_PACKAGES permission");
+            Objects.requireNonNull(packageList);
+
+            setKeepUninstalledPackagesInternal(packageList);
+        }
+
+        @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 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 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();
+            enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
+                    "setPackagesSuspendedAsUser");
+            return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), 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();
+            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 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 PackageManager.LegacyPackageDeleteObserver(null).getBinder(),
+                        userId,
+                        PackageManager.DELETE_SYSTEM_APP);
+                return true;
+            } finally {
+                Binder.restoreCallingIdentity(callingId);
+            }
+        }
+
+        @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);
+        }
+
+        @Deprecated
+        @Override
+        public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
+            return mDomainVerificationManager.setLegacyUserState(packageName, userId, status);
+        }
+
+        @Deprecated
+        @Override
+        public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains) {
+            DomainVerificationProxyV1.queueLegacyVerifyResult(mContext, mDomainVerificationConnection,
+                    id, verificationCode, failedDomains, Binder.getCallingUid());
+        }
+
+        @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(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 canPackageQuery(@NonNull String sourcePackageName,
+                @NonNull String targetPackageName, @UserIdInt int userId) {
+            return mComputer.canPackageQuery(sourcePackageName, targetPackageName, userId);
+        }
+
+        @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(mIPackageManager,
+                    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 {
         @Override
         public List<ApplicationInfo> getInstalledApplications(
@@ -6828,7 +7173,7 @@
 
         @Override
         public boolean isInstantApp(String packageName, int userId) {
-            return PackageManagerService.this.isInstantApp(packageName, userId);
+            return PackageManagerService.this.mIPackageManager.isInstantApp(packageName, userId);
         }
 
         @Override
@@ -6943,6 +7288,19 @@
         }
 
         @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);
@@ -7176,7 +7534,7 @@
 
         @Override
         public String getNameForUid(int uid) {
-            return PackageManagerService.this.getNameForUid(uid);
+            return mIPackageManager.getNameForUid(uid);
         }
 
         @Override
@@ -7393,6 +7751,12 @@
         }
 
         @Override
+        public void onPackageProcessKilledForUninstall(String packageName) {
+            mHandler.post(() -> PackageManagerService.this.notifyInstallObserver(packageName,
+                    true /* killApp */));
+        }
+
+        @Override
         public SparseArray<String> getAppsWithSharedUserIds() {
             return mComputer.getAppsWithSharedUserIds();
         }
@@ -7415,7 +7779,7 @@
 
         @Override
         public boolean isOnlyCoreApps() {
-            return PackageManagerService.this.isOnlyCoreApps();
+            return mIPackageManager.isOnlyCoreApps();
         }
 
         @Override
@@ -7425,6 +7789,11 @@
         }
 
         @Override
+        public void freeAllAppCacheAboveQuota(@NonNull String volumeUuid) throws IOException {
+            PackageManagerService.this.freeAllAppCacheAboveQuota(volumeUuid);
+        }
+
+        @Override
         public void forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
             PackageManagerService.this.forEachPackageSetting(actionLocked);
         }
@@ -7502,7 +7871,7 @@
 
         @Override
         public void finishPackageInstall(int token, boolean didLaunch) {
-            PackageManagerService.this.finishPackageInstall(token, didLaunch);
+            mIPackageManager.finishPackageInstall(token, didLaunch);
         }
 
         @Nullable
@@ -7747,6 +8116,16 @@
         public Computer snapshot() {
             return snapshotComputer();
         }
+
+        @Override
+        public void shutdown() {
+            PackageManagerService.this.shutdown();
+        }
+
+        @Override
+        public DynamicCodeLogger getDynamicCodeLogger() {
+            return PackageManagerService.this.getDexManager().getDynamicCodeLogger();
+        }
     }
 
     private boolean setEnabledOverlayPackages(@UserIdInt int userId,
@@ -7830,23 +8209,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(
@@ -7975,23 +8337,6 @@
         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());
     }
@@ -8000,26 +8345,6 @@
         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.
@@ -8028,45 +8353,35 @@
         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) {
+    private 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) {
@@ -8092,100 +8407,6 @@
         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);
         if (packageState == null) {
@@ -8201,32 +8422,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.
@@ -8240,21 +8435,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");
@@ -8269,15 +8449,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 {
@@ -8375,16 +8546,6 @@
         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) {
         Preconditions.checkNotNull(packageList);
         synchronized (mKeepUninstalledPackages) {
@@ -8406,19 +8567,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;
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
index d12c826..5bdda0b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
@@ -89,7 +89,7 @@
     public @Nullable String defaultTextClassifierPackage;
     public @Nullable String systemTextClassifierPackage;
     public @Nullable String overlayConfigSignaturePackage;
-    public @NonNull String requiredSupplementalProcessPackage;
+    public @NonNull String requiredSdkSandboxPackage;
     public ViewCompiler viewCompiler;
     public @Nullable String retailDemoPackage;
     public @Nullable String recentsPackage;
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index a9471cf..8d3fbf7 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -1250,6 +1250,14 @@
     }
 
     /**
+     * Check if the Binder caller is system UID or root's UID.
+     */
+    public static boolean isSystemOrRoot() {
+        final int uid = Binder.getCallingUid();
+        return uid == Process.SYSTEM_UID || uid == Process.ROOT_UID;
+    }
+
+    /**
      * Enforces that only the system UID or root's UID can call a method exposed
      * via Binder.
      *
@@ -1257,8 +1265,7 @@
      * @throws SecurityException if the caller is not system or root
      */
     public static void enforceSystemOrRoot(String message) {
-        final int uid = Binder.getCallingUid();
-        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
+        if (!isSystemOrRoot()) {
             throw new SecurityException(message);
         }
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 500b4ec..b92f51b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -159,9 +159,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;
diff --git a/services/core/java/com/android/server/pm/PackageRemovedInfo.java b/services/core/java/com/android/server/pm/PackageRemovedInfo.java
index cdaf99c..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;
@@ -51,6 +49,7 @@
     boolean mDataRemoved;
     boolean mRemovedForAllUsers;
     boolean mIsStaticSharedLib;
+    boolean mIsExternal;
     // a two dimensional array mapping userId to the set of appIds that can receive notice
     // of package changes
     SparseArray<int[]> mBroadcastAllowList;
@@ -66,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) {
@@ -89,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());
@@ -133,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,
@@ -164,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/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..7253ae4 100644
--- a/services/core/java/com/android/server/pm/PreferredActivityHelper.java
+++ b/services/core/java/com/android/server/pm/PreferredActivityHelper.java
@@ -151,7 +151,8 @@
         if (TextUtils.equals(currentPackageName, packageName)) {
             return false;
         }
-        final String[] callingPackages = mPm.getPackagesForUid(Binder.getCallingUid());
+        final String[] callingPackages = mPm.mIPackageManager
+                .getPackagesForUid(Binder.getCallingUid());
         if (callingPackages != null && ArrayUtils.contains(callingPackages,
                 mPm.mRequiredPermissionControllerPackage)) {
             // PermissionController manages default home directly.
diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java
index 079903e..88df843 100644
--- a/services/core/java/com/android/server/pm/RemovePackageHelper.java
+++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java
@@ -239,6 +239,7 @@
                     && deletedPkg.getStaticSharedLibName() != null;
             outInfo.populateUsers(deletedPs.queryInstalledUsers(
                     mUserManagerInternal.getUserIds(), true), deletedPs);
+            outInfo.mIsExternal = deletedPs.isExternalStorage();
         }
 
         removePackageLI(deletedPs.getPackageName(), (flags & PackageManager.DELETE_CHATTY) != 0);
@@ -283,7 +284,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);
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 394c8fb..021c3db 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;
@@ -410,7 +411,7 @@
         int[] excludedUserIds;
     }
 
-    private static int mFirstAvailableUid = 0;
+    private static int mFirstAvailableUid = Process.FIRST_APPLICATION_UID;
 
     /** Map from volume UUID to {@link VersionInfo} */
     @Watched
@@ -1424,6 +1425,35 @@
         }
     }
 
+    /**
+     * 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);
+        replaceAppIdLPw(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);
+        }
+        mSharedUsers.remove(sharedUser.getName());
+    }
+
+    /**
+     * 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);
+        }
+    }
+
     PreferredIntentResolver editPreferredActivitiesLPw(int userId) {
         PreferredIntentResolver pir = mPreferredActivities.get(userId);
         if (pir == null) {
@@ -3906,13 +3936,17 @@
                 } else if (tagName.equals(TAG_PERMISSIONS)) {
                     final LegacyPermissionState legacyState;
                     if (packageSetting.hasSharedUser()) {
-                        legacyState = getSettingLPr(
-                                packageSetting.getSharedUserAppId()).getLegacyPermissionState();
+                        final SettingBase sharedUserSettings = getSettingLPr(
+                                packageSetting.getSharedUserAppId());
+                        legacyState = sharedUserSettings != null
+                                ? sharedUserSettings.getLegacyPermissionState() : null;
                     } else {
                         legacyState = packageSetting.getLegacyPermissionState();
                     }
-                    readInstallPermissionsLPr(parser, legacyState, users);
-                    packageSetting.setInstallPermissionsFixed(true);
+                    if (legacyState != null) {
+                        readInstallPermissionsLPr(parser, legacyState, users);
+                        packageSetting.setInstallPermissionsFixed(true);
+                    }
                 } else if (tagName.equals("proper-signing-keyset")) {
                     long id = parser.getAttributeLong(null, "identifier");
                     Integer refCt = mKeySetRefs.get(id);
@@ -4186,10 +4220,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
@@ -4271,7 +4306,7 @@
     private int acquireAndRegisterNewAppIdLPw(SettingBase obj) {
         // Let's be stupidly inefficient for now...
         final int size = mAppIds.size();
-        for (int i = mFirstAvailableUid; i < size; i++) {
+        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;
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/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/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 9c74dd7..88a298a 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -52,6 +52,9 @@
       "options": [
         {
           "include-filter": "com.google.android.security.gts.PackageVerifierTest"
+        },
+        {
+          "exclude-filter": "com.google.android.security.gts.PackageVerifierTest#testAdbInstall_timeout_allowed"
         }
       ]
     },
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 b7c55c5..a8d24fa 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;
@@ -1059,7 +1088,7 @@
         intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode);
         intent.putExtra(Intent.EXTRA_USER, profileHandle);
         intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
-        getDevicePolicyManagerInternal().broadcastIntentToCrossProfileManifestReceiversAsUser(
+        getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers(
                 intent, parentHandle, /* requiresPermission= */ true);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
         mContext.sendBroadcastAsUser(intent, parentHandle);
@@ -1399,21 +1428,28 @@
     }
 
     /**
-     * Returns a UserInfo object with the name filled in, for Owner, or the original
+     * Returns a UserInfo object with the name filled in, for Owner and Guest, or the original
      * if the name is already set.
      */
     private UserInfo userWithName(UserInfo orig) {
-        if (orig != null && orig.name == null && orig.id == UserHandle.USER_SYSTEM) {
-            if (DBG_ALLOCATION) {
-                final int number = mUser0Allocations.incrementAndGet();
-                Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
+        if (orig != null && orig.name == null) {
+            String name = null;
+            if (orig.id == UserHandle.USER_SYSTEM) {
+                if (DBG_ALLOCATION) {
+                    final int number = mUser0Allocations.incrementAndGet();
+                    Slog.w(LOG_TAG, "System user instantiated at least " + number + " times");
+                }
+                name = getOwnerName();
+            } else if (orig.isGuest()) {
+                name = getGuestName();
             }
-            UserInfo withName = new UserInfo(orig);
-            withName.name = getOwnerName();
-            return withName;
-        } else {
-            return orig;
+            if (name != null) {
+                final UserInfo withName = new UserInfo(orig);
+                withName.name = name;
+                return withName;
+            }
         }
+        return orig;
     }
 
     /** Returns whether the given user type is one of the FULL user types. */
@@ -3259,6 +3295,10 @@
         return mOwnerName.get();
     }
 
+    private String getGuestName() {
+        return mContext.getString(com.android.internal.R.string.guest_name);
+    }
+
     private void invalidateOwnerNameIfNecessary(@NonNull Resources res, boolean forceUpdate) {
         final int configChanges = mLastConfiguration.updateFrom(res.getConfiguration());
         if (forceUpdate || (configChanges & mOwnerNameTypedValue.changingConfigurations) != 0) {
@@ -3397,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();
@@ -3506,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;
@@ -3584,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());
+                    }
                 }
             }
         }
@@ -3611,6 +3661,9 @@
         userData.persistSeedData = persistSeedData;
         userData.seedAccountOptions = seedAccountOptions;
         userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp);
+        if (ignorePrepareStorageErrors) {
+            userData.setIgnorePrepareStorageErrors();
+        }
 
         synchronized (mRestrictionsLock) {
             if (baseRestrictions != null) {
@@ -4766,7 +4819,7 @@
         managedProfileIntent.putExtra(Intent.EXTRA_USER, new UserHandle(removedUserId));
         managedProfileIntent.putExtra(Intent.EXTRA_USER_HANDLE, removedUserId);
         final UserHandle parentHandle = new UserHandle(parentUserId);
-        getDevicePolicyManagerInternal().broadcastIntentToCrossProfileManifestReceiversAsUser(
+        getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers(
                 managedProfileIntent, parentHandle, /* requiresPermission= */ false);
         managedProfileIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                 | Intent.FLAG_RECEIVER_FOREGROUND);
@@ -5721,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) {
@@ -6124,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();
+            }
+        }
     }
 
     /**
@@ -6263,11 +6327,11 @@
     }
 
     /**
-     * Checks if the given user has a managed profile associated with it.
+     * Checks if the given user has a profile associated with it.
      * @param userId The parent user
      * @return
      */
-    boolean hasManagedProfile(@UserIdInt int userId) {
+    boolean hasProfile(@UserIdInt int userId) {
         synchronized (mUsersLock) {
             UserInfo userInfo = getUserInfoLU(userId);
             final int userSize = mUsers.size();
@@ -6286,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/VerificationParams.java b/services/core/java/com/android/server/pm/VerificationParams.java
index 4334cbd..bc93611 100644
--- a/services/core/java/com/android/server/pm/VerificationParams.java
+++ b/services/core/java/com/android/server/pm/VerificationParams.java
@@ -372,9 +372,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 +392,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 "
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/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 49553f4..36633cc 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1021,7 +1021,8 @@
         }
         for (String packageName : packageNames) {
             grantPermissionsToSystemPackage(NO_PM_CACHE, packageName, userId,
-                    PHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS, SMS_PERMISSIONS);
+                    PHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS, SMS_PERMISSIONS,
+                    NOTIFICATION_PERMISSIONS);
         }
     }
 
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 87494a6..9084261 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -89,6 +89,7 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -125,7 +126,6 @@
 import com.android.server.SystemConfig;
 import com.android.server.Watchdog;
 import com.android.server.pm.ApexManager;
-import com.android.server.pm.PackageSetting;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.UserManagerService;
 import com.android.server.pm.parsing.PackageInfoUtils;
@@ -175,10 +175,6 @@
 
     private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
 
-    // For automotive products, CarService enforces allow-listing of the privileged permissions
-    // com.android.car is the package name which declares auto specific permissions
-    private static final String CAR_PACKAGE_NAME = "com.android.car";
-
     /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
     private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
     /** Empty array to avoid allocations */
@@ -388,7 +384,12 @@
         // PackageManager.hasSystemFeature() is not used here because PackageManagerService
         // isn't ready yet.
         if (availableFeatures.containsKey(PackageManager.FEATURE_AUTOMOTIVE)) {
-            mPrivilegedPermissionAllowlistSourcePackageNames.add(CAR_PACKAGE_NAME);
+            // The property defined in car api surface, so use the string directly.
+            String carServicePackage = SystemProperties.get("ro.android.car.carservice.package",
+                    null);
+            if (carServicePackage != null) {
+                mPrivilegedPermissionAllowlistSourcePackageNames.add(carServicePackage);
+            }
         }
 
         mHandlerThread = new ServiceThread(TAG,
@@ -1402,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);
                 }
 
@@ -2536,33 +2537,41 @@
             }
         }
 
+        Collection<String> uidRequestedPermissions;
+        Collection<String> uidImplicitPermissions;
+        int uidTargetSdkVersion;
+        if (!ps.hasSharedUser()) {
+            uidRequestedPermissions = pkg.getRequestedPermissions();
+            uidImplicitPermissions = pkg.getImplicitPermissions();
+            uidTargetSdkVersion = pkg.getTargetSdkVersion();
+        } else {
+            uidRequestedPermissions = new ArraySet<>();
+            uidImplicitPermissions = new ArraySet<>();
+            uidTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+            final ArraySet<PackageStateInternal> packages =
+                    mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId());
+            int packagesSize = packages.size();
+            for (int i = 0; i < packagesSize; i++) {
+                AndroidPackageApi sharedUserPackage =
+                        packages.valueAt(i).getAndroidPackage();
+                if (sharedUserPackage == null) {
+                    continue;
+                }
+                uidRequestedPermissions.addAll(
+                        sharedUserPackage.getRequestedPermissions());
+                uidImplicitPermissions.addAll(
+                        sharedUserPackage.getImplicitPermissions());
+                uidTargetSdkVersion = Math.min(uidTargetSdkVersion,
+                        sharedUserPackage.getTargetSdkVersion());
+            }
+        }
+
         synchronized (mLock) {
             for (final int userId : userIds) {
                 final UserPermissionState userState = mState.getOrCreateUserState(userId);
                 final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId());
 
                 if (uidState.isMissing()) {
-                    Collection<String> uidRequestedPermissions;
-                    int targetSdkVersion;
-                    if (!ps.hasSharedUser()) {
-                        uidRequestedPermissions = pkg.getRequestedPermissions();
-                        targetSdkVersion = pkg.getTargetSdkVersion();
-                    } else {
-                        uidRequestedPermissions = new ArraySet<>();
-                        targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
-                        final ArraySet<PackageStateInternal> packages =
-                                mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId());
-                        int packagesSize = packages.size();
-                        for (int i = 0; i < packagesSize; i++) {
-                            AndroidPackageApi sharedUserPackage =
-                                    packages.valueAt(i).getAndroidPackage();
-                            uidRequestedPermissions.addAll(
-                                    sharedUserPackage.getRequestedPermissions());
-                            targetSdkVersion = Math.min(targetSdkVersion,
-                                    sharedUserPackage.getTargetSdkVersion());
-                        }
-                    }
-
                     for (String permissionName : uidRequestedPermissions) {
                         Permission permission = mRegistry.getPermission(permissionName);
                         if (permission == null) {
@@ -2576,7 +2585,7 @@
                                         FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
                                         FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
                             }
-                            if (targetSdkVersion < Build.VERSION_CODES.M) {
+                            if (uidTargetSdkVersion < Build.VERSION_CODES.M) {
                                 uidState.updatePermissionFlags(permission,
                                         PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
                                                 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
@@ -2606,8 +2615,7 @@
                         // the runtime ones are written only if changed. The only cases of
                         // changed runtime permissions here are promotion of an install to
                         // runtime and revocation of a runtime from a shared user.
-                        if (revokeUnusedSharedUserPermissionsLocked(
-                                mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId()),
+                        if (revokeUnusedSharedUserPermissionsLocked(uidRequestedPermissions,
                                 uidState)) {
                             updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
                             runtimePermissionsRevoked = true;
@@ -2909,8 +2917,9 @@
                     userState.setInstallPermissionsFixed(ps.getPackageName(), true);
                 }
 
-                updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState, pkg,
-                        userId, updatedUserIds);
+                updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState,
+                        pkg.getPackageName(), uidImplicitPermissions, uidTargetSdkVersion, userId,
+                        updatedUserIds);
                 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState,
                         uidState, pkg, newImplicitPermissions, userId, updatedUserIds);
             }
@@ -2947,7 +2956,9 @@
      * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
      *
      * @param ps The state of the permissions of the package
-     * @param pkg The package that is currently looked at
+     * @param packageName The name of the package
+     * @param uidImplicitPermissions The implicit permissions of all packages in the UID
+     * @param uidTargetSdkVersion The lowest target SDK version of all packages in the UID
      * @param userIds All user IDs in the system, must be passed in because this method is locked
      * @param updatedUserIds a list of user ids that needs to be amended if the permission state
      *                       for a user is changed.
@@ -2957,14 +2968,12 @@
     @NonNull
     @GuardedBy("mLock")
     private int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps,
-            @NonNull AndroidPackage pkg, int userId, @NonNull int[] updatedUserIds) {
-        String pkgName = pkg.getPackageName();
-        boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
-                >= Build.VERSION_CODES.M;
+            @NonNull String packageName, @NonNull Collection<String> uidImplicitPermissions,
+            int uidTargetSdkVersion, int userId, @NonNull int[] updatedUserIds) {
+        boolean supportsRuntimePermissions = uidTargetSdkVersion >= Build.VERSION_CODES.M;
 
         for (String permission : ps.getGrantedPermissions()) {
-            if (pkg.getRequestedPermissions().contains(permission)
-                    && !pkg.getImplicitPermissions().contains(permission)) {
+            if (!uidImplicitPermissions.contains(permission)) {
                 Permission bp = mRegistry.getPermission(permission);
                 if (bp != null && bp.isRuntime()) {
                     int flags = ps.getPermissionFlags(permission);
@@ -2991,7 +3000,7 @@
                             if (ps.revokePermission(bp)) {
                                 if (DEBUG_PERMISSIONS) {
                                     Slog.i(TAG, "Revoking runtime permission "
-                                            + permission + " for " + pkgName
+                                            + permission + " for " + packageName
                                             + " as it is now requested");
                                 }
                             }
@@ -3523,8 +3532,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;
     }
@@ -3822,27 +3832,8 @@
 
     @GuardedBy("mLock")
     private boolean revokeUnusedSharedUserPermissionsLocked(
-            ArraySet<PackageStateInternal> pkgList, UidPermissionState uidState) {
-        // Collect all used permissions in the UID
-        final ArraySet<String> usedPermissions = new ArraySet<>();
-        if (pkgList == null || pkgList.size() == 0) {
-            return false;
-        }
-        for (PackageStateInternal pkgState : pkgList) {
-            final AndroidPackageApi pkg = pkgState.getAndroidPackage();
-            if (pkg.getRequestedPermissions().isEmpty()) {
-                continue;
-            }
-            final int requestedPermCount = pkg.getRequestedPermissions().size();
-            for (int j = 0; j < requestedPermCount; j++) {
-                String permission = pkg.getRequestedPermissions().get(j);
-                Permission bp = mRegistry.getPermission(permission);
-                if (bp != null) {
-                    usedPermissions.add(permission);
-                }
-            }
-        }
-
+            @NonNull Collection<String> uidRequestedPermissions,
+            @NonNull UidPermissionState uidState) {
         boolean runtimePermissionChanged = false;
 
         // Prune permissions
@@ -3850,7 +3841,7 @@
         final int permissionStatesSize = permissionStates.size();
         for (int i = permissionStatesSize - 1; i >= 0; i--) {
             PermissionState permissionState = permissionStates.get(i);
-            if (!usedPermissions.contains(permissionState.getName())) {
+            if (!uidRequestedPermissions.contains(permissionState.getName())) {
                 Permission bp = mRegistry.getPermission(permissionState.getName());
                 if (bp != null) {
                     if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) {
diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackageApi.java b/services/core/java/com/android/server/pm/pkg/AndroidPackageApi.java
index d3c8c7b..a0bb8dc 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackageApi.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackageApi.java
@@ -268,6 +268,9 @@
     List<FeatureGroupInfo> getFeatureGroups();
 
     @NonNull
+    List<String> getImplicitPermissions();
+
+    @NonNull
     List<ParsedInstrumentation> getInstrumentations();
 
     long getLongVersionCode();
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..cbba346 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);
 
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..1484df8 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
@@ -494,7 +494,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 +546,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) {
@@ -2394,11 +2392,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 +2545,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);
     }
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..112b9e0 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;
@@ -893,9 +894,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();
@@ -1047,8 +1046,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)
diff --git a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
index 13218ea..67aed45 100644
--- a/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
+++ b/services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java
@@ -256,8 +256,8 @@
     public DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName)
             throws NameNotFoundException {
         mEnforcer.assertApprovedQuerent(mConnection.getCallingUid(), mProxy);
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(packageName);
             AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
             if (pkg == null) {
@@ -315,8 +315,8 @@
             @NonNull Set<String> domains, int state)
             throws NameNotFoundException {
         mEnforcer.assertApprovedVerifier(callingUid, mProxy);
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             List<String> verifiedDomains = new ArrayList<>();
 
             GetAttachedResult result = getAndValidateAttachedLocked(domainSetId, domains,
@@ -369,8 +369,8 @@
 
         ArraySet<String> verifiedDomains = new ArraySet<>();
         if (packageName == null) {
+            final Computer snapshot = mConnection.snapshot();
             synchronized (mLock) {
-                final Computer snapshot = mConnection.snapshot();
                 ArraySet<String> validDomains = new ArraySet<>();
 
                 int size = mAttachedPkgStates.size();
@@ -403,8 +403,8 @@
                 }
             }
         } else {
+            final Computer snapshot = mConnection.snapshot();
             synchronized (mLock) {
-                final Computer snapshot = mConnection.snapshot();
                 DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
                 if (pkgState == null) {
                     throw DomainVerificationUtils.throwPackageUnavailable(packageName);
@@ -539,8 +539,8 @@
             return DomainVerificationManager.ERROR_DOMAIN_SET_ID_INVALID;
         }
 
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             GetAttachedResult result = getAndValidateAttachedLocked(domainSetId, domains,
                     false /* forAutoVerify */, callingUid, userId, snapshot);
             if (result.isError()) {
@@ -578,8 +578,8 @@
             @NonNull String packageName, boolean enabled, @Nullable ArraySet<String> domains)
             throws NameNotFoundException {
         mEnforcer.assertInternal(mConnection.getCallingUid());
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
             if (pkgState == null) {
                 throw DomainVerificationUtils.throwPackageUnavailable(packageName);
@@ -682,8 +682,8 @@
             throw DomainVerificationUtils.throwPackageUnavailable(packageName);
         }
 
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(packageName);
             AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
             if (pkg == null) {
@@ -1179,8 +1179,8 @@
     public void printOwnersForPackage(@NonNull IndentingPrintWriter writer,
             @Nullable String packageName, @Nullable @UserIdInt Integer userId)
             throws NameNotFoundException {
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             if (packageName == null) {
                 int size = mAttachedPkgStates.size();
                 for (int index = 0; index < size; index++) {
@@ -1227,8 +1227,8 @@
     @Override
     public void printOwnersForDomains(@NonNull IndentingPrintWriter writer,
             @NonNull List<String> domains, @Nullable @UserIdInt Integer userId) {
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             int size = domains.size();
             for (int index = 0; index < size; index++) {
                 printOwnersForDomain(writer, domains.get(index), userId, snapshot);
@@ -1403,8 +1403,8 @@
     @Override
     public void clearDomainVerificationState(@Nullable List<String> packageNames) {
         mEnforcer.assertInternal(mConnection.getCallingUid());
+        final Computer snapshot = mConnection.snapshot();
         synchronized (mLock) {
-            final Computer snapshot = mConnection.snapshot();
             if (packageNames == null) {
                 int size = mAttachedPkgStates.size();
                 for (int index = 0; index < size; index++) {
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index 4ad6ed1..70d69c6 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -55,6 +55,7 @@
 import com.android.internal.util.function.UndecFunction;
 import com.android.server.LocalServices;
 
+import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -283,6 +284,33 @@
                 attributionSource, skipProxyOperation);
     }
 
+    /**
+     * Write location and activity recognition tags to console.
+     * See also {@code adb shell dumpsys appops}.
+     */
+    public void dumpTags(PrintWriter writer) {
+        if (!mLocationTags.isEmpty()) {
+            writer.println("  AppOps policy location tags:");
+            writeTags(mLocationTags, writer);
+            writer.println();
+        }
+        if (!mActivityRecognitionTags.isEmpty()) {
+            writer.println("  AppOps policy activity recognition tags:");
+            writeTags(mActivityRecognitionTags, writer);
+            writer.println();
+        }
+    }
+
+    private void writeTags(Map<Integer, PackageTagsList> tags, PrintWriter writer) {
+        int counter = 0;
+        for (Map.Entry<Integer, PackageTagsList> tagEntry : tags.entrySet()) {
+            writer.print("    #"); writer.print(counter++); writer.print(": ");
+            writer.print(tagEntry.getKey().toString()); writer.print("=");
+            tagEntry.getValue().dump(writer);
+        }
+    }
+
+
     private int resolveDatasourceOp(int code, int uid, @NonNull String packageName,
             @Nullable String attributionTag) {
         code = resolveRecordAudioOp(code, uid);
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 c637c67..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;
@@ -34,6 +36,7 @@
 import android.app.ActivityTaskManager;
 import android.app.AppOpsManager;
 import android.app.AppOpsManagerInternal;
+import android.app.KeyguardManager;
 import android.app.TaskInfo;
 import android.app.compat.CompatChanges;
 import android.compat.annotation.ChangeId;
@@ -53,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;
@@ -108,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();
 
@@ -148,15 +154,19 @@
     private List<String> mAppOpPermissions;
 
     private Context mContext;
+    private Handler mHandler;
     private PackageManagerInternal mPackageManagerInternal;
     private NotificationManagerInternal mNotificationManager;
+    private final KeyguardManager mKeyguardManager;
     private final PackageManager mPackageManager;
 
     public PermissionPolicyService(@NonNull Context context) {
         super(context);
 
         mContext = context;
+        mHandler = new Handler(Looper.getMainLooper());
         mPackageManager = context.getPackageManager();
+        mKeyguardManager = context.getSystemService(KeyguardManager.class);
         LocalServices.addService(PermissionPolicyInternal.class, new Internal());
     }
 
@@ -1013,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;
                         }
@@ -1030,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))
@@ -1046,12 +1056,21 @@
                     }
 
                     @Override
-                    public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo) {
-                        super.onActivityLaunched(taskInfo, activityInfo);
-                        clearNotificationReviewFlagsIfNeeded(activityInfo.packageName,
-                                UserHandle.of(taskInfo.userId));
-                        showNotificationPromptIfNeeded(activityInfo.packageName,
-                                taskInfo.userId, taskInfo.taskId);
+                    public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo,
+                            ActivityInterceptorInfo info) {
+                        super.onActivityLaunched(taskInfo, activityInfo, info);
+                        if (!shouldShowNotificationDialogOrClearFlags(taskInfo,
+                                activityInfo.packageName, info.intent, info.checkedOptions, true)) {
+                            return;
+                        }
+                        UserHandle user = UserHandle.of(taskInfo.userId);
+                        if (CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID,
+                                activityInfo.packageName, user)) {
+                            clearNotificationReviewFlagsIfNeeded(activityInfo.packageName, user);
+                        } else {
+                            showNotificationPromptIfNeeded(activityInfo.packageName,
+                                    taskInfo.userId, taskInfo.taskId);
+                        }
                     }
                 };
 
@@ -1073,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;
             }
@@ -1092,10 +1111,58 @@
             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 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), 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(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)
+                    || intent.getCategories().contains(Intent.CATEGORY_LEANBACK_LAUNCHER)
+                    || intent.getCategories().contains(Intent.CATEGORY_CAR_LAUNCHER));
+        }
+
         private void clearNotificationReviewFlagsIfNeeded(String packageName, UserHandle user) {
-            if (!CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID, packageName, user)
-                    || ((mPackageManager.getPermissionFlags(POST_NOTIFICATIONS, packageName, user)
-                    & FLAG_PERMISSION_REVIEW_REQUIRED) == 0)) {
+            if ((mPackageManager.getPermissionFlags(POST_NOTIFICATIONS, packageName, user)
+                    & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
                 return;
             }
             try {
@@ -1114,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);
@@ -1140,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.
@@ -1210,8 +1272,8 @@
             }
 
             if (!pkg.getRequestedPermissions().contains(POST_NOTIFICATIONS)
-                    || CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID,
-                    pkg.getPackageName(), user)) {
+                    || CompatChanges.isChangeEnabled(NOTIFICATION_PERM_CHANGE_ID, pkgName, user)
+                    || mKeyguardManager.isKeyguardLocked()) {
                 return false;
             }
 
@@ -1220,7 +1282,7 @@
                 mNotificationManager = LocalServices.getService(NotificationManagerInternal.class);
             }
             boolean hasCreatedNotificationChannels = mNotificationManager
-                    .getNumNotificationChannelsForPackage(pkg.getPackageName(), uid, true) > 0;
+                    .getNumNotificationChannelsForPackage(pkgName, uid, true) > 0;
             int flags = mPackageManager.getPermissionFlags(POST_NOTIFICATIONS, pkgName, user);
             boolean explicitlySet = (flags & PermissionManager.EXPLICIT_SET_FLAGS) != 0;
             boolean needsReview = (flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 4387249..e79148d 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -330,6 +330,7 @@
     static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
     static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
     static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
+    static public final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
 
     private static final String TALKBACK_LABEL = "TalkBack";
 
@@ -2123,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);
 
@@ -2214,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(
@@ -2228,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/PowerGroup.java b/services/core/java/com/android/server/power/PowerGroup.java
index c1bfdf7..fec61ac 100644
--- a/services/core/java/com/android/server/power/PowerGroup.java
+++ b/services/core/java/com/android/server/power/PowerGroup.java
@@ -22,12 +22,25 @@
 import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
 import static android.os.PowerManagerInternal.isInteractive;
 
+import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN;
+import static com.android.server.power.PowerManagerService.TRACE_SCREEN_ON;
+import static com.android.server.power.PowerManagerService.USER_ACTIVITY_SCREEN_BRIGHT;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_DRAW;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT;
+
+import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.os.PowerManager;
+import android.os.PowerManagerInternal;
+import android.os.PowerSaveState;
 import android.os.Trace;
 import android.util.Slog;
 import android.view.Display;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.LatencyTracker;
+
 /**
  * Used to store power related requests to every display in a
  * {@link com.android.server.display.DisplayGroup}.
@@ -40,8 +53,11 @@
     private static final String TAG = PowerGroup.class.getSimpleName();
     private static final boolean DEBUG = false;
 
-    private final DisplayPowerRequest mDisplayPowerRequest;
+    @VisibleForTesting
+    final DisplayPowerRequest mDisplayPowerRequest = new DisplayPowerRequest();
     private final PowerGroupListener mWakefulnessListener;
+    private final Notifier mNotifier;
+    private final DisplayManagerInternal mDisplayManagerInternal;
     private final boolean mSupportsSandman;
     private final int mGroupId;
     /** True if DisplayManagerService has applied all the latest display states that were requested
@@ -63,12 +79,13 @@
     /** Timestamp (milliseconds since boot) of the last time the power group was put to sleep. */
     private long mLastSleepTime;
 
-    PowerGroup(int groupId, PowerGroupListener wakefulnessListener,
-            DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready,
+    PowerGroup(int groupId, PowerGroupListener wakefulnessListener, Notifier notifier,
+            DisplayManagerInternal displayManagerInternal, int wakefulness, boolean ready,
             boolean supportsSandman, long eventTime) {
         mGroupId = groupId;
         mWakefulnessListener = wakefulnessListener;
-        mDisplayPowerRequest = displayPowerRequest;
+        mNotifier = notifier;
+        mDisplayManagerInternal = displayManagerInternal;
         mWakefulness = wakefulness;
         mReady = ready;
         mSupportsSandman = supportsSandman;
@@ -76,18 +93,17 @@
         mLastSleepTime = eventTime;
     }
 
-    PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, long eventTime) {
+    PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, Notifier notifier,
+            DisplayManagerInternal displayManagerInternal, long eventTime) {
         mGroupId = Display.DEFAULT_DISPLAY_GROUP;
         mWakefulnessListener = wakefulnessListener;
-        mDisplayPowerRequest = new DisplayPowerRequest();
+        mNotifier = notifier;
+        mDisplayManagerInternal = displayManagerInternal;
         mWakefulness = wakefulness;
         mReady = false;
         mSupportsSandman = true;
         mLastWakeTime = eventTime;
-        mLastSleepTime = eventTime;    }
-
-    DisplayPowerRequest getDisplayPowerRequestLocked() {
-        return mDisplayPowerRequest;
+        mLastSleepTime = eventTime;
     }
 
     long getLastWakeTimeLocked() {
@@ -185,6 +201,32 @@
         mIsSandmanSummoned = isSandmanSummoned;
     }
 
+    void wakeUpLocked(long eventTime, @PowerManager.WakeReason int reason, String details, int uid,
+            String opPackageName, int opUid, LatencyTracker latencyTracker) {
+        if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE) {
+            return;
+        }
+
+        Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakePowerGroup" + mGroupId);
+        try {
+            Slog.i(TAG, "Waking up power group from "
+                    + PowerManagerInternal.wakefulnessToString(mWakefulness)
+                    + " (groupId=" + mGroupId
+                    + ", uid=" + uid
+                    + ", reason=" + PowerManager.wakeReasonToString(reason)
+                    + ", details=" + details
+                    + ")...");
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, mGroupId);
+            // The instrument will be timed out automatically after 2 seconds.
+            latencyTracker.onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(mGroupId));
+
+            setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
+                    opPackageName, details);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_POWER);
+        }
+    }
+
     boolean dreamLocked(long eventTime, int uid) {
         if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) {
             return false;
@@ -261,6 +303,23 @@
         return mUserActivitySummary;
     }
 
+    public boolean isPolicyBrightLocked() {
+        return mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT;
+    }
+
+    public boolean isPolicyDimLocked() {
+        return mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM;
+    }
+
+    public boolean isPolicyVrLocked() {
+        return mDisplayPowerRequest.isVr();
+
+    }
+
+    public boolean isBrightOrDimLocked() {
+        return mDisplayPowerRequest.isBrightOrDim();
+    }
+
     public void setUserActivitySummaryLocked(int summary) {
         mUserActivitySummary = summary;
     }
@@ -281,6 +340,108 @@
         return mSupportsSandman;
     }
 
+    /**
+     * Return true if we must keep a suspend blocker active on behalf of a power group.
+     * We do so if the screen is on or is in transition between states.
+     */
+    boolean needSuspendBlockerLocked(boolean proximityPositive,
+            boolean suspendWhenScreenOffDueToProximityConfig) {
+        if (isBrightOrDimLocked()) {
+            // If we asked for the screen to be on but it is off due to the proximity
+            // sensor then we may suspend but only if the configuration allows it.
+            // On some hardware it may not be safe to suspend because the proximity
+            // sensor may not be correctly configured as a wake-up source.
+            if (!mDisplayPowerRequest.useProximitySensor || !proximityPositive
+                    || !suspendWhenScreenOffDueToProximityConfig) {
+                return true;
+            }
+        }
+
+        if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
+                && mDisplayPowerRequest.dozeScreenState == Display.STATE_ON) {
+            // Although we are in DOZE and would normally allow the device to suspend,
+            // the doze service has explicitly requested the display to remain in the ON
+            // state which means we should hold the display suspend blocker.
+            return true;
+        }
+        return false;
+    }
+
+    @VisibleForTesting
+    int getDesiredScreenPolicyLocked(boolean quiescent, boolean dozeAfterScreenOff,
+            boolean vrModeEnabled, boolean bootCompleted, boolean screenBrightnessBoostInProgress) {
+        final int wakefulness = getWakefulnessLocked();
+        final int wakeLockSummary = getWakeLockSummaryLocked();
+        if (wakefulness == WAKEFULNESS_ASLEEP || quiescent) {
+            return DisplayPowerRequest.POLICY_OFF;
+        } else if (wakefulness == WAKEFULNESS_DOZING) {
+            if ((wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
+                return DisplayPowerRequest.POLICY_DOZE;
+            }
+            if (dozeAfterScreenOff) {
+                return DisplayPowerRequest.POLICY_OFF;
+            }
+            // Fall through and preserve the current screen policy if not configured to
+            // doze after screen off.  This causes the screen off transition to be skipped.
+        }
+
+        // It is important that POLICY_VR check happens after the wakefulness checks above so
+        // that VR-mode does not prevent displays from transitioning to the correct state when
+        // dozing or sleeping.
+        if (vrModeEnabled) {
+            return DisplayPowerRequest.POLICY_VR;
+        }
+
+        if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
+                || !bootCompleted
+                || (getUserActivitySummaryLocked() & USER_ACTIVITY_SCREEN_BRIGHT) != 0
+                || screenBrightnessBoostInProgress) {
+            return DisplayPowerRequest.POLICY_BRIGHT;
+        }
+
+        return DisplayPowerRequest.POLICY_DIM;
+    }
+
+    int getPolicyLocked() {
+        return mDisplayPowerRequest.policy;
+    }
+
+    boolean updateLocked(float screenBrightnessOverride, boolean autoBrightness,
+            boolean useProximitySensor, boolean boostScreenBrightness, int dozeScreenState,
+            float dozeScreenBrightness, boolean overrideDrawWakeLock,
+            PowerSaveState powerSaverState, boolean quiescent, boolean dozeAfterScreenOff,
+            boolean vrModeEnabled, boolean bootCompleted, boolean screenBrightnessBoostInProgress,
+            boolean waitForNegativeProximity) {
+        mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(quiescent, dozeAfterScreenOff,
+                vrModeEnabled, bootCompleted, screenBrightnessBoostInProgress);
+        mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
+        mDisplayPowerRequest.useAutoBrightness = autoBrightness;
+        mDisplayPowerRequest.useProximitySensor = useProximitySensor;
+        mDisplayPowerRequest.boostScreenBrightness = boostScreenBrightness;
+
+        if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
+            mDisplayPowerRequest.dozeScreenState = dozeScreenState;
+            if ((getWakeLockSummaryLocked() & WAKE_LOCK_DRAW) != 0 && !overrideDrawWakeLock) {
+                if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
+                    mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
+                }
+                if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
+                    mDisplayPowerRequest.dozeScreenState = Display.STATE_ON;
+                }
+            }
+            mDisplayPowerRequest.dozeScreenBrightness = dozeScreenBrightness;
+        } else {
+            mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
+            mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+        }
+        mDisplayPowerRequest.lowPowerMode = powerSaverState.batterySaverEnabled;
+        mDisplayPowerRequest.screenLowPowerBrightnessFactor = powerSaverState.brightnessFactor;
+        boolean ready = mDisplayManagerInternal.requestPowerState(mGroupId, mDisplayPowerRequest,
+                waitForNegativeProximity);
+        mNotifier.onScreenPolicyUpdate(mGroupId, mDisplayPowerRequest.policy);
+        return ready;
+    }
+
     protected interface PowerGroupListener {
         /**
          * Informs the recipient about a wakefulness change of a {@link PowerGroup}.
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index bd58472..048f8d6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -54,7 +54,6 @@
 import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.hardware.display.DisplayManagerInternal;
-import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
 import android.hardware.power.Boost;
 import android.hardware.power.Mode;
 import android.net.Uri;
@@ -196,19 +195,19 @@
     private static final int DIRTY_DISPLAY_GROUP_WAKEFULNESS = 1 << 16;
 
     // Summarizes the state of all active wakelocks.
-    private static final int WAKE_LOCK_CPU = 1 << 0;
-    private static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
-    private static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
-    private static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
-    private static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
-    private static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
-    private static final int WAKE_LOCK_DOZE = 1 << 6;
-    private static final int WAKE_LOCK_DRAW = 1 << 7;
+    static final int WAKE_LOCK_CPU = 1 << 0;
+    static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;
+    static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;
+    static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;
+    static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;
+    static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
+    static final int WAKE_LOCK_DOZE = 1 << 6;
+    static final int WAKE_LOCK_DRAW = 1 << 7;
 
     // Summarizes the user activity state.
-    private static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
-    private static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
-    private static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;
+    static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
+    static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;
+    static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;
 
     // Default timeout in milliseconds.  This is only used until the settings
     // provider populates the actual default value (R.integer.def_screen_off_timeout).
@@ -247,7 +246,7 @@
     private static final String REASON_LOW_BATTERY = "shutdown,battery";
     private static final String REASON_BATTERY_THERMAL_STATE = "shutdown,thermal,battery";
 
-    private static final String TRACE_SCREEN_ON = "Screen turning on";
+    static final String TRACE_SCREEN_ON = "Screen turning on";
 
     /** If turning screen on takes more than this long, we show a warning on logcat. */
     private static final int SCREEN_ON_LATENCY_WARNING_MS = 200;
@@ -696,7 +695,8 @@
                 final PowerGroup powerGroup = new PowerGroup(
                         groupId,
                         mPowerGroupWakefulnessChangeListener,
-                        new DisplayPowerRequest(),
+                        mNotifier,
+                        mDisplayManagerInternal,
                         WAKEFULNESS_AWAKE,
                         /* ready= */ false,
                         supportsSandman,
@@ -1176,14 +1176,14 @@
 
     @Override
     public void onBootPhase(int phase) {
-        synchronized (mLock) {
-            if (phase == PHASE_SYSTEM_SERVICES_READY) {
-                systemReady();
+        if (phase == PHASE_SYSTEM_SERVICES_READY) {
+            systemReady();
 
-            } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
-                incrementBootCount();
+        } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+            incrementBootCount();
 
-            } else if (phase == PHASE_BOOT_COMPLETED) {
+        } else if (phase == PHASE_BOOT_COMPLETED) {
+            synchronized (mLock) {
                 final long now = mClock.uptimeMillis();
                 mBootCompleted = true;
                 mDirty |= DIRTY_BOOT_COMPLETED;
@@ -1214,12 +1214,6 @@
             mPolicy = getLocalService(WindowManagerPolicy.class);
             mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
             mAttentionDetector.systemReady(mContext);
-            mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP,
-                    new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener,
-                            mClock.uptimeMillis()));
-            DisplayGroupPowerChangeListener displayGroupPowerChangeListener =
-                    new DisplayGroupPowerChangeListener();
-            mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener);
 
             SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
 
@@ -1230,6 +1224,13 @@
                     mInjector.createSuspendBlocker(this, "PowerManagerService.Broadcasts"),
                     mPolicy, mFaceDownDetector, mScreenUndimDetector);
 
+            mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP,
+                    new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener,
+                            mNotifier, mDisplayManagerInternal, mClock.uptimeMillis()));
+            DisplayGroupPowerChangeListener displayGroupPowerChangeListener =
+                    new DisplayGroupPowerChangeListener();
+            mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener);
+
             mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
                     mInjector.createSuspendBlocker(
                             this, "PowerManagerService.WirelessChargerDetector"),
@@ -1944,45 +1945,15 @@
     @GuardedBy("mLock")
     private void wakePowerGroupLocked(final PowerGroup powerGroup, long eventTime,
             @WakeReason int reason, String details, int uid, String opPackageName, int opUid) {
-        final int groupId = powerGroup.getGroupId();
         if (DEBUG_SPEW) {
             Slog.d(TAG, "wakePowerGroupLocked: eventTime=" + eventTime
-                    + ", groupId=" + groupId + ", uid=" + uid);
+                    + ", groupId=" + powerGroup.getGroupId() + ", uid=" + uid);
         }
-
-        if (eventTime < powerGroup.getLastSleepTimeLocked() || mForceSuspendActive
-                || !mSystemReady) {
+        if (mForceSuspendActive || !mSystemReady) {
             return;
         }
-
-        final int currentWakefulness = powerGroup.getWakefulnessLocked();
-        if (currentWakefulness == WAKEFULNESS_AWAKE) {
-            if (!mBootCompleted && sQuiescent) {
-                mDirty |= DIRTY_QUIESCENT;
-                updatePowerStateLocked();
-            }
-            return;
-        }
-
-        Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOnDisplay");
-        try {
-            Slog.i(TAG, "Waking up power group from "
-                    + PowerManagerInternal.wakefulnessToString(currentWakefulness)
-                    + " (groupId=" + groupId
-                    + ", uid=" + uid
-                    + ", reason=" + PowerManager.wakeReasonToString(reason)
-                    + ", details=" + details
-                    + ")...");
-            Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId);
-            // The instrument will be timed out automatically after 2 seconds.
-            LatencyTracker.getInstance(mContext)
-                    .onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(groupId));
-
-            powerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
-                    opPackageName, details);
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_POWER);
-        }
+        powerGroup.wakeUpLocked(eventTime, reason, details, uid, opPackageName, opUid,
+                LatencyTracker.getInstance(mContext));
     }
 
     @GuardedBy("mLock")
@@ -2242,7 +2213,7 @@
 
     @GuardedBy("mLock")
     private void finishWakefulnessChangeIfNeededLocked() {
-        if (mWakefulnessChanging && areAllDisplaysReadyLocked()) {
+        if (mWakefulnessChanging && areAllPowerGroupsReadyLocked()) {
             if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING
                     && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                 return; // wait until dream has enabled dozing
@@ -2259,9 +2230,12 @@
         }
     }
 
-    /** Returns {@code true} if every display has its requested state matching its actual state. */
+    /**
+     * Returns {@code true} if all {@link PowerGroup}s are ready, i.e. every display has its
+     * requested state matching its actual state.
+     */
     @GuardedBy("mLock")
-    private boolean areAllDisplaysReadyLocked() {
+    private boolean areAllPowerGroupsReadyLocked() {
         final int size = mPowerGroups.size();
         for (int i = 0; i < size; i++) {
             if (!mPowerGroups.valueAt(i).isReadyLocked()) {
@@ -2318,11 +2292,11 @@
             // Phase 2: Lock profiles that became inactive/not kept awake.
             updateProfilesLocked(now);
 
-            // Phase 3: Update display power state.
-            final boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);
+            // Phase 3: Update power state of all PowerGroups.
+            final boolean powerGroupsBecameReady = updatePowerGroupsLocked(dirtyPhase2);
 
-            // Phase 4: Update dream state (depends on display ready signal).
-            updateDreamLocked(dirtyPhase2, displayBecameReady);
+            // Phase 4: Update dream state (depends on power group ready signal).
+            updateDreamLocked(dirtyPhase2, powerGroupsBecameReady);
 
             // Phase 5: Send notifications, if needed.
             finishWakefulnessChangeIfNeededLocked();
@@ -2513,7 +2487,7 @@
             final int numWakeLocks = mWakeLocks.size();
             for (int i = 0; i < numWakeLocks; i++) {
                 final WakeLock wakeLock = mWakeLocks.get(i);
-                final Integer groupId = wakeLock.getDisplayGroupId();
+                final Integer groupId = wakeLock.getPowerGroupId();
                 // a wakelock with an invalid group ID should affect all groups
                 if (groupId == null || (groupId != Display.INVALID_DISPLAY_GROUP
                         && !mPowerGroups.contains(groupId))) {
@@ -2727,12 +2701,9 @@
                         >= powerGroup.getLastWakeTimeLocked()) {
                     groupNextTimeout = lastUserActivityTimeNoChangeLights + screenOffTimeout;
                     if (now < groupNextTimeout) {
-                        final DisplayPowerRequest displayPowerRequest =
-                                powerGroup.getDisplayPowerRequestLocked();
-                        if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
-                                || displayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
+                        if (powerGroup.isPolicyBrightLocked() || powerGroup.isPolicyVrLocked()) {
                             groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
-                        } else if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
+                        } else if (powerGroup.isPolicyDimLocked()) {
                             groupUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
                         }
                     }
@@ -3102,7 +3073,7 @@
      * Determines whether to post a message to the sandman to update the dream state.
      */
     @GuardedBy("mLock")
-    private void updateDreamLocked(int dirty, boolean displayBecameReady) {
+    private void updateDreamLocked(int dirty, boolean powerGroupBecameReady) {
         if ((dirty & (DIRTY_WAKEFULNESS
                 | DIRTY_USER_ACTIVITY
                 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED
@@ -3113,8 +3084,8 @@
                 | DIRTY_IS_POWERED
                 | DIRTY_STAY_ON
                 | DIRTY_PROXIMITY_POSITIVE
-                | DIRTY_BATTERY_STATE)) != 0 || displayBecameReady) {
-            if (areAllDisplaysReadyLocked()) {
+                | DIRTY_BATTERY_STATE)) != 0 || powerGroupBecameReady) {
+            if (areAllPowerGroupsReadyLocked()) {
                 scheduleSandmanLocked();
             }
         }
@@ -3266,13 +3237,12 @@
      */
     @GuardedBy("mLock")
     private boolean canDreamLocked(final PowerGroup powerGroup) {
-        final DisplayPowerRequest displayPowerRequest = powerGroup.getDisplayPowerRequestLocked();
         if (!mBootCompleted
                 || getGlobalWakefulnessLocked() != WAKEFULNESS_DREAMING
                 || !mDreamsSupportedConfig
                 || !mDreamsEnabledSetting
-                || !displayPowerRequest.isBrightOrDim()
-                || displayPowerRequest.isVr()
+                || !(powerGroup.isBrightOrDimLocked())
+                || powerGroup.isPolicyVrLocked()
                 || (powerGroup.getUserActivitySummaryLocked() & (USER_ACTIVITY_SCREEN_BRIGHT
                 | USER_ACTIVITY_SCREEN_DIM | USER_ACTIVITY_SCREEN_DREAM)) == 0) {
             return false;
@@ -3303,24 +3273,24 @@
     }
 
     /**
-     * Updates the display power state asynchronously.
-     * When the update is finished, the ready state of the displays will be updated.  The display
-     * controllers post a message to tell us when the actual display power state
+     * Updates the state of all {@link PowerGroup}s asynchronously.
+     * When the update is finished, the ready state of the {@link PowerGroup} will be updated.
+     * The display controllers post a message to tell us when the actual display power state
      * has been updated so we come back here to double-check and finish up.
      *
-     * This function recalculates the display power state each time.
+     * This function recalculates the {@link PowerGroup} state each time.
      *
-     * @return {@code true} if all displays became ready; {@code false} otherwise
+     * @return {@code true} if all {@link PowerGroup}s became ready; {@code false} otherwise
      */
     @GuardedBy("mLock")
-    private boolean updateDisplayPowerStateLocked(int dirty) {
-        final boolean oldDisplayReady = areAllDisplaysReadyLocked();
+    private boolean updatePowerGroupsLocked(int dirty) {
+        final boolean oldPowerGroupsReady = areAllPowerGroupsReadyLocked();
         if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
                 | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
                 | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |
                 DIRTY_QUIESCENT | DIRTY_DISPLAY_GROUP_WAKEFULNESS)) != 0) {
             if ((dirty & DIRTY_QUIESCENT) != 0) {
-                if (areAllDisplaysReadyLocked()) {
+                if (areAllPowerGroupsReadyLocked()) {
                     sQuiescent = false;
                 } else {
                     mDirty |= DIRTY_QUIESCENT;
@@ -3330,9 +3300,6 @@
             for (int idx = 0; idx < mPowerGroups.size(); idx++) {
                 final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
                 final int groupId = powerGroup.getGroupId();
-                final DisplayPowerRequest displayPowerRequest =
-                        powerGroup.getDisplayPowerRequestLocked();
-                displayPowerRequest.policy = getDesiredScreenPolicyLocked(powerGroup);
 
                 // Determine appropriate screen brightness and auto-brightness adjustments.
                 final boolean autoBrightness;
@@ -3350,43 +3317,19 @@
                             == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
                     screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
                 }
-
-                // Update display power request.
-                displayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
-                displayPowerRequest.useAutoBrightness = autoBrightness;
-                displayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
-                displayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
-
-                updatePowerRequestFromBatterySaverPolicy(displayPowerRequest);
-
-                if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
-                    displayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
-                    if ((powerGroup.getWakeLockSummaryLocked() & WAKE_LOCK_DRAW) != 0
-                            && !mDrawWakeLockOverrideFromSidekick) {
-                        if (displayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
-                            displayPowerRequest.dozeScreenState = Display.STATE_DOZE;
-                        }
-                        if (displayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
-                            displayPowerRequest.dozeScreenState = Display.STATE_ON;
-                        }
-                    }
-                    displayPowerRequest.dozeScreenBrightness =
-                            mDozeScreenBrightnessOverrideFromDreamManagerFloat;
-                } else {
-                    displayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
-                    displayPowerRequest.dozeScreenBrightness =
-                            PowerManager.BRIGHTNESS_INVALID_FLOAT;
-                }
-
-                final boolean ready = mDisplayManagerInternal.requestPowerState(groupId,
-                        displayPowerRequest, mRequestWaitForNegativeProximity);
-                mNotifier.onScreenPolicyUpdate(powerGroup.getGroupId(), displayPowerRequest.policy);
+                boolean ready = powerGroup.updateLocked(screenBrightnessOverride, autoBrightness,
+                        shouldUseProximitySensorLocked(), shouldBoostScreenBrightness(),
+                        mDozeScreenStateOverrideFromDreamManager,
+                        mDozeScreenBrightnessOverrideFromDreamManagerFloat,
+                        mDrawWakeLockOverrideFromSidekick,
+                        mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS),
+                        sQuiescent, mDozeAfterScreenOff, mIsVrModeEnabled, mBootCompleted,
+                        mScreenBrightnessBoostInProgress, mRequestWaitForNegativeProximity);
                 int wakefulness = powerGroup.getWakefulnessLocked();
-
                 if (DEBUG_SPEW) {
                     Slog.d(TAG, "updateDisplayPowerStateLocked: displayReady=" + ready
                             + ", groupId=" + groupId
-                            + ", policy=" + policyToString(displayPowerRequest.policy)
+                            + ", policy=" + policyToString(powerGroup.getPolicyLocked())
                             + ", mWakefulness="
                             + PowerManagerInternal.wakefulnessToString(wakefulness)
                             + ", mWakeLockSummary=0x" + Integer.toHexString(
@@ -3394,9 +3337,8 @@
                             + ", mUserActivitySummary=0x" + Integer.toHexString(
                             powerGroup.getUserActivitySummaryLocked())
                             + ", mBootCompleted=" + mBootCompleted
-                            + ", screenBrightnessOverride="
-                            + displayPowerRequest.screenBrightnessOverride
-                            + ", useAutoBrightness=" + displayPowerRequest.useAutoBrightness
+                            + ", screenBrightnessOverride=" + screenBrightnessOverride
+                            + ", useAutoBrightness=" + autoBrightness
                             + ", mScreenBrightnessBoostInProgress="
                             + mScreenBrightnessBoostInProgress
                             + ", mIsVrModeEnabled= " + mIsVrModeEnabled
@@ -3420,7 +3362,7 @@
             mRequestWaitForNegativeProximity = false;
         }
 
-        return areAllDisplaysReadyLocked() && !oldDisplayReady;
+        return areAllPowerGroupsReadyLocked() && !oldPowerGroupsReady;
     }
 
     @GuardedBy("mLock")
@@ -3457,40 +3399,9 @@
     @VisibleForTesting
     @GuardedBy("mLock")
     int getDesiredScreenPolicyLocked(int groupId) {
-        return getDesiredScreenPolicyLocked(mPowerGroups.get(groupId));
-    }
-
-    int getDesiredScreenPolicyLocked(final PowerGroup powerGroup) {
-        final int wakefulness = powerGroup.getWakefulnessLocked();
-        final int wakeLockSummary = powerGroup.getWakeLockSummaryLocked();
-        if (wakefulness == WAKEFULNESS_ASLEEP || sQuiescent) {
-            return DisplayPowerRequest.POLICY_OFF;
-        } else if (wakefulness == WAKEFULNESS_DOZING) {
-            if ((wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
-                return DisplayPowerRequest.POLICY_DOZE;
-            }
-            if (mDozeAfterScreenOff) {
-                return DisplayPowerRequest.POLICY_OFF;
-            }
-            // Fall through and preserve the current screen policy if not configured to
-            // doze after screen off.  This causes the screen off transition to be skipped.
-        }
-
-        // It is important that POLICY_VR check happens after the wakefulness checks above so
-        // that VR-mode does not prevent displays from transitioning to the correct state when
-        // dozing or sleeping.
-        if (mIsVrModeEnabled) {
-            return DisplayPowerRequest.POLICY_VR;
-        }
-
-        if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
-                || !mBootCompleted
-                || (powerGroup.getUserActivitySummaryLocked() & USER_ACTIVITY_SCREEN_BRIGHT) != 0
-                || mScreenBrightnessBoostInProgress) {
-            return DisplayPowerRequest.POLICY_BRIGHT;
-        }
-
-        return DisplayPowerRequest.POLICY_DIM;
+        return mPowerGroups.get(groupId).getDesiredScreenPolicyLocked(sQuiescent,
+                mDozeAfterScreenOff, mIsVrModeEnabled, mBootCompleted,
+                mScreenBrightnessBoostInProgress);
     }
 
     private final DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks =
@@ -3578,11 +3489,11 @@
     @GuardedBy("mLock")
     private void updateSuspendBlockerLocked() {
         final boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
-        final boolean needDisplaySuspendBlocker = needDisplaySuspendBlockerLocked();
+        final boolean needDisplaySuspendBlocker = needSuspendBlockerLocked();
         final boolean autoSuspend = !needDisplaySuspendBlocker;
         boolean interactive = false;
         for (int idx = 0; idx < mPowerGroups.size() && !interactive; idx++) {
-            interactive = mPowerGroups.valueAt(idx).getDisplayPowerRequestLocked().isBrightOrDim();
+            interactive = mPowerGroups.valueAt(idx).isBrightOrDimLocked();
         }
 
         // Disable auto-suspend if needed.
@@ -3617,7 +3528,7 @@
             // until the display is actually ready so that all transitions have
             // completed.  This is probably a good sign that things have gotten
             // too tangled over here...
-            if (interactive || areAllDisplaysReadyLocked()) {
+            if (interactive || areAllPowerGroupsReadyLocked()) {
                 setHalInteractiveModeLocked(interactive);
             }
         }
@@ -3643,12 +3554,11 @@
     }
 
     /**
-     * Return true if we must keep a suspend blocker active on behalf of the display.
-     * We do so if the screen is on or is in transition between states.
+     * Return true if we must keep a suspend blocker active on behalf of a power group.
      */
     @GuardedBy("mLock")
-    private boolean needDisplaySuspendBlockerLocked() {
-        if (!areAllDisplaysReadyLocked()) {
+    private boolean needSuspendBlockerLocked() {
+        if (!areAllPowerGroupsReadyLocked()) {
             return true;
         }
 
@@ -3666,24 +3576,9 @@
         }
 
         for (int idx = 0; idx < mPowerGroups.size(); idx++) {
-            final DisplayPowerRequest displayPowerRequest =
-                    mPowerGroups.valueAt(idx).getDisplayPowerRequestLocked();
-            if (displayPowerRequest.isBrightOrDim()) {
-                // If we asked for the screen to be on but it is off due to the proximity
-                // sensor then we may suspend but only if the configuration allows it.
-                // On some hardware it may not be safe to suspend because the proximity
-                // sensor may not be correctly configured as a wake-up source.
-                if (!displayPowerRequest.useProximitySensor || !mProximityPositive
-                        || !mSuspendWhenScreenOffDueToProximityConfig) {
-                    return true;
-                }
-            }
-
-            if (displayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE
-                    && displayPowerRequest.dozeScreenState == Display.STATE_ON) {
-                // Although we are in DOZE and would normally allow the device to suspend,
-                // the doze service has explicitly requested the display to remain in the ON
-                // state which means we should hold the display suspend blocker.
+            final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
+            if (powerGroup.needSuspendBlockerLocked(mProximityPositive,
+                    mSuspendWhenScreenOffDueToProximityConfig)) {
                 return true;
             }
         }
@@ -3832,14 +3727,6 @@
         }
     }
 
-    @VisibleForTesting
-    void updatePowerRequestFromBatterySaverPolicy(DisplayPowerRequest displayPowerRequest) {
-        PowerSaveState state = mBatterySaverPolicy.
-                getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS);
-        displayPowerRequest.lowPowerMode = state.batterySaverEnabled;
-        displayPowerRequest.screenLowPowerBrightnessFactor = state.brightnessFactor;
-    }
-
     void setStayOnSettingInternal(int val) {
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val);
@@ -5170,8 +5057,8 @@
             mWorkSource = copyWorkSource(workSource);
         }
 
-        /** Returns the DisplayGroup Id of this wakeLock or {@code null} if info not available. */
-        public Integer getDisplayGroupId() {
+        /** Returns the PowerGroup Id of this wakeLock or {@code null} if info not available.. */
+        public Integer getPowerGroupId() {
             if (!mSystemReady || mDisplayId == Display.INVALID_DISPLAY) {
                 return Display.INVALID_DISPLAY_GROUP;
             }
@@ -5614,6 +5501,11 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
+                    if (!mBootCompleted && sQuiescent) {
+                        mDirty |= DIRTY_QUIESCENT;
+                        updatePowerStateLocked();
+                        return;
+                    }
                     wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), eventTime,
                             reason, details, uid, opPackageName, uid);
                 }
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index b03db66..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;
@@ -315,15 +316,15 @@
                             com.android.internal.R.string.reboot_to_update_reboot));
             }
         } else if (mReason != null && mReason.equals(PowerManager.REBOOT_RECOVERY)) {
-            if (showSysuiReboot()) {
-                return null;
-            } else if (RescueParty.isAttemptingFactoryReset()) {
+            if (RescueParty.isAttemptingFactoryReset()) {
                 // We're not actually doing a factory reset yet; we're rebooting
                 // to ask the user if they'd like to reset, so give them a less
                 // scary dialog message.
                 pd.setTitle(context.getText(com.android.internal.R.string.power_off));
                 pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));
                 pd.setIndeterminate(true);
+            } else if (showSysuiReboot()) {
+                return null;
             } else {
                 // Factory reset path. Set the dialog message accordingly.
                 pd.setTitle(context.getText(com.android.internal.R.string.reboot_to_reset_title));
@@ -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/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 2491565d..8755662 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -27,6 +27,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
@@ -51,8 +52,13 @@
     private static final boolean DEBUG = false;
     @VisibleForTesting final long mHintSessionPreferredRate;
 
+    // Multi-levle map storing all active AppHintSessions.
+    // First level is keyed by the UID of the client process creating the session.
+    // Second level is keyed by an IBinder passed from client process. This is used to observe
+    // when the process exits. The client generally uses the same IBinder object across multiple
+    // sessions, so the value is a set of AppHintSessions.
     @GuardedBy("mLock")
-    private final ArrayMap<Integer, ArrayMap<IBinder, AppHintSession>> mActiveSessions;
+    private final ArrayMap<Integer, ArrayMap<IBinder, ArraySet<AppHintSession>>> mActiveSessions;
 
     /** Lock to protect HAL handles and listen list. */
     private final Object mLock = new Object();
@@ -201,13 +207,16 @@
         public void onUidGone(int uid, boolean disabled) {
             FgThread.getHandler().post(() -> {
                 synchronized (mLock) {
-                    ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(uid);
+                    ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(uid);
                     if (tokenMap == null) {
                         return;
                     }
                     for (int i = tokenMap.size() - 1; i >= 0; i--) {
                         // Will remove the session from tokenMap
-                        tokenMap.valueAt(i).close();
+                        ArraySet<AppHintSession> sessionSet = tokenMap.valueAt(i);
+                        for (int j = sessionSet.size() - 1; j >= 0; j--) {
+                            sessionSet.valueAt(j).close();
+                        }
                     }
                     mProcStatesCache.delete(uid);
                 }
@@ -231,12 +240,14 @@
             FgThread.getHandler().post(() -> {
                 synchronized (mLock) {
                     mProcStatesCache.put(uid, procState);
-                    ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(uid);
+                    ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(uid);
                     if (tokenMap == null) {
                         return;
                     }
-                    for (AppHintSession s : tokenMap.values()) {
-                        s.onProcStateChanged();
+                    for (ArraySet<AppHintSession> sessionSet : tokenMap.values()) {
+                        for (AppHintSession s : sessionSet) {
+                            s.onProcStateChanged();
+                        }
                     }
                 }
             });
@@ -305,17 +316,25 @@
 
                 long halSessionPtr = mNativeWrapper.halCreateHintSession(callingTgid, callingUid,
                         tids, durationNanos);
-                if (halSessionPtr == 0) return null;
+                if (halSessionPtr == 0) {
+                    return null;
+                }
 
                 AppHintSession hs = new AppHintSession(callingUid, callingTgid, tids, token,
                         halSessionPtr, durationNanos);
                 synchronized (mLock) {
-                    ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(callingUid);
+                    ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
+                            mActiveSessions.get(callingUid);
                     if (tokenMap == null) {
                         tokenMap = new ArrayMap<>(1);
                         mActiveSessions.put(callingUid, tokenMap);
                     }
-                    tokenMap.put(token, hs);
+                    ArraySet<AppHintSession> sessionSet = tokenMap.get(token);
+                    if (sessionSet == null) {
+                        sessionSet = new ArraySet<>(1);
+                        tokenMap.put(token, sessionSet);
+                    }
+                    sessionSet.add(hs);
                     return hs;
                 }
             } finally {
@@ -339,10 +358,14 @@
                 pw.println("Active Sessions:");
                 for (int i = 0; i < mActiveSessions.size(); i++) {
                     pw.println("Uid " + mActiveSessions.keyAt(i).toString() + ":");
-                    ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.valueAt(i);
+                    ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap =
+                            mActiveSessions.valueAt(i);
                     for (int j = 0; j < tokenMap.size(); j++) {
-                        pw.println("  Session " + j + ":");
-                        tokenMap.valueAt(j).dump(pw, "    ");
+                        ArraySet<AppHintSession> sessionSet = tokenMap.valueAt(j);
+                        for (int k = 0; k < sessionSet.size(); ++k) {
+                            pw.println("  Session:");
+                            sessionSet.valueAt(k).dump(pw, "    ");
+                        }
                     }
                 }
             }
@@ -432,11 +455,18 @@
                 mNativeWrapper.halCloseHintSession(mHalSessionPtr);
                 mHalSessionPtr = 0;
                 mToken.unlinkToDeath(this, 0);
-                ArrayMap<IBinder, AppHintSession> tokenMap = mActiveSessions.get(mUid);
+                ArrayMap<IBinder, ArraySet<AppHintSession>> tokenMap = mActiveSessions.get(mUid);
                 if (tokenMap == null) {
-                    Slogf.w(TAG, "UID %d is note present in active session map", mUid);
+                    Slogf.w(TAG, "UID %d is not present in active session map", mUid);
+                    return;
                 }
-                tokenMap.remove(mToken);
+                ArraySet<AppHintSession> sessionSet = tokenMap.get(mToken);
+                if (sessionSet == null) {
+                    Slogf.w(TAG, "Token %s is not present in token map", mToken.toString());
+                    return;
+                }
+                sessionSet.remove(this);
+                if (sessionSet.isEmpty()) tokenMap.remove(mToken);
                 if (tokenMap.isEmpty()) mActiveSessions.remove(mUid);
             }
         }
diff --git a/services/core/java/com/android/server/security/AndroidKeystoreAttestationVerificationAttributes.java b/services/core/java/com/android/server/security/AndroidKeystoreAttestationVerificationAttributes.java
new file mode 100644
index 0000000..3543e93
--- /dev/null
+++ b/services/core/java/com/android/server/security/AndroidKeystoreAttestationVerificationAttributes.java
@@ -0,0 +1,468 @@
+/*
+ * 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.security;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.framework.protobuf.ByteString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Boolean;
+import com.android.internal.org.bouncycastle.asn1.ASN1Encodable;
+import com.android.internal.org.bouncycastle.asn1.ASN1Enumerated;
+import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.internal.org.bouncycastle.asn1.ASN1Integer;
+import com.android.internal.org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import com.android.internal.org.bouncycastle.asn1.ASN1OctetString;
+import com.android.internal.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.internal.org.bouncycastle.asn1.ASN1Set;
+import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
+import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
+
+import java.nio.charset.StandardCharsets;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Parsed {@link X509Certificate} attestation extension values for Android Keystore attestations.
+ *
+ * Pull fields out of the top-level sequence. A full description of this structure is at
+ * https://source.android.com/security/keystore/attestation.
+ *
+ * If a value is null or empty, then it was not set/found in the extension values.
+ *
+ */
+class AndroidKeystoreAttestationVerificationAttributes {
+    // The OID for the extension Android Keymaster puts into device-generated certificates.
+    private static final String ANDROID_KEYMASTER_KEY_DESCRIPTION_EXTENSION_OID =
+            "1.3.6.1.4.1.11129.2.1.17";
+
+    // ASN.1 sequence index values for the Android Keymaster extension.
+    private static final int ATTESTATION_VERSION_INDEX = 0;
+    private static final int ATTESTATION_SECURITY_LEVEL_INDEX = 1;
+    private static final int KEYMASTER_VERSION_INDEX = 2;
+    private static final int KEYMASTER_SECURITY_LEVEL_INDEX = 3;
+    private static final int ATTESTATION_CHALLENGE_INDEX = 4;
+    private static final int KEYMASTER_UNIQUE_ID_INDEX = 5;
+    private static final int SW_ENFORCED_INDEX = 6;
+    private static final int HW_ENFORCED_INDEX = 7;
+    private static final int VERIFIED_BOOT_KEY_INDEX = 0;
+    private static final int VERIFIED_BOOT_LOCKED_INDEX = 1;
+    private static final int VERIFIED_BOOT_STATE_INDEX = 2;
+    private static final int VERIFIED_BOOT_HASH_INDEX = 3;
+
+    // ASN.1 sequence index values for the Android Keystore application id.
+    private static final int PACKAGE_INFO_SET_INDEX = 0;
+    private static final int PACKAGE_SIGNATURE_SET_INDEX = 1;
+    private static final int PACKAGE_INFO_NAME_INDEX = 0;
+    private static final int PACKAGE_INFO_VERSION_INDEX = 1;
+
+    // See these AOSP files: hardware/libhardware/include/hardware/hw_auth_token.h
+    private static final int HW_AUTH_NONE = 0;
+
+    // Some keymaster constants. See this AOSP file:
+    // hardware/libhardware/include/hardware/keymaster_defs.h
+    private static final int KM_TAG_NO_AUTH_REQUIRED = 503;
+    private static final int KM_TAG_UNLOCKED_DEVICE_REQUIRED = 509;
+    private static final int KM_TAG_ALL_APPLICATIONS = 600;
+    private static final int KM_TAG_ROOT_OF_TRUST = 704;
+    private static final int KM_TAG_OS_VERSION = 705;
+    private static final int KM_TAG_OS_PATCHLEVEL = 706;
+    private static final int KM_TAG_ATTESTATION_APPLICATION_ID = 709;
+    private static final int KM_TAG_ATTESTATION_ID_BRAND = 710;
+    private static final int KM_TAG_ATTESTATION_ID_DEVICE = 711;
+    private static final int KM_TAG_ATTESTATION_ID_PRODUCT = 712;
+    private static final int KM_TAG_VENDOR_PATCHLEVEL = 718;
+    private static final int KM_TAG_BOOT_PATCHLEVEL = 719;
+
+    private static final int KM_SECURITY_LEVEL_SOFTWARE = 0;
+    private static final int KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT = 1;
+    private static final int KM_SECURITY_LEVEL_STRONG_BOX = 2;
+    private static final int KM_VERIFIED_BOOT_STATE_VERIFIED = 0;
+    private static final int KM_VERIFIED_BOOT_STATE_SELF_SIGNED = 1;
+    private static final int KM_VERIFIED_BOOT_STATE_UNVERIFIED = 2;
+    private static final int KM_VERIFIED_BOOT_STATE_FAILED = 3;
+
+    private Integer mAttestationVersion = null;
+    private SecurityLevel mAttestationSecurityLevel = null;
+    private boolean mAttestationHardwareBacked = false;
+    private Integer mKeymasterVersion = null;
+    private SecurityLevel mKeymasterSecurityLevel = null;
+    private boolean mKeymasterHardwareBacked = false;
+    private ByteString mAttestationChallenge = null;
+    private ByteString mKeymasterUniqueId = null;
+    private String mDeviceBrand = null;
+    private String mDeviceName = null;
+    private String mDeviceProductName = null;
+    private boolean mKeyAllowedForAllApplications = false;
+    private Integer mKeyAuthenticatorType = null;
+    private Integer mKeyBootPatchLevel = null;
+    private Integer mKeyOsPatchLevel = null;
+    private Integer mKeyOsVersion = null;
+    private Integer mKeyVendorPatchLevel = null;
+    private Boolean mKeyRequiresUnlockedDevice = null;
+    private ByteString mVerifiedBootHash = null;
+    private ByteString mVerifiedBootKey = null;
+    private Boolean mVerifiedBootLocked = null;
+    private VerifiedBootState mVerifiedBootState = null;
+    private Map<String, Long> mApplicationPackageNameVersion = null;
+    private List<ByteString> mApplicationCertificateDigests = null;
+
+    enum VerifiedBootState {
+        VERIFIED,
+        SELF_SIGNED,
+        UNVERIFIED,
+        FAILED
+    }
+
+    enum SecurityLevel {
+        SOFTWARE,
+        TRUSTED_ENVIRONMENT,
+        STRONG_BOX
+    }
+
+    /**
+     * Extracts attestation extension properties from {@link X509Certificate}
+     * and returns a {@link AndroidKeystoreAttestationVerificationAttributes} that encapsulates the
+     * properties.
+     */
+    @NonNull
+    static AndroidKeystoreAttestationVerificationAttributes fromCertificate(
+            @NonNull X509Certificate x509Certificate)
+            throws Exception {
+        return new AndroidKeystoreAttestationVerificationAttributes(x509Certificate);
+    }
+
+    int getAttestationVersion() {
+        return mAttestationVersion;
+    }
+
+    @Nullable
+    SecurityLevel getAttestationSecurityLevel() {
+        return mAttestationSecurityLevel;
+    }
+
+    boolean isAttestationHardwareBacked() {
+        return mAttestationHardwareBacked;
+    }
+
+    int getKeymasterVersion() {
+        return mKeymasterVersion;
+    }
+
+    @Nullable
+    SecurityLevel getKeymasterSecurityLevel() {
+        return mKeymasterSecurityLevel;
+    }
+
+    boolean isKeymasterHardwareBacked() {
+        return mKeymasterHardwareBacked;
+    }
+
+    @Nullable
+    ByteString getAttestationChallenge() {
+        return mAttestationChallenge;
+    }
+
+    @Nullable
+    ByteString getKeymasterUniqueId() {
+        return mKeymasterUniqueId;
+    }
+
+    @Nullable
+    String getDeviceBrand() {
+        return mDeviceBrand;
+    }
+
+    @Nullable
+    String getDeviceName() {
+        return mDeviceName;
+    }
+
+    @Nullable
+    String getDeviceProductName() {
+        return mDeviceProductName;
+    }
+
+    boolean isKeyAllowedForAllApplications() {
+        return mKeyAllowedForAllApplications;
+    }
+
+    int getKeyAuthenticatorType() {
+        if (mKeyAuthenticatorType == null) {
+            throw new IllegalStateException("KeyAuthenticatorType is not set.");
+        }
+        return mKeyAuthenticatorType;
+    }
+
+    int getKeyBootPatchLevel() {
+        if (mKeyBootPatchLevel == null) {
+            throw new IllegalStateException("KeyBootPatchLevel is not set.");
+        }
+        return mKeyBootPatchLevel;
+    }
+
+    int getKeyOsPatchLevel() {
+        if (mKeyOsPatchLevel == null) {
+            throw new IllegalStateException("KeyOsPatchLevel is not set.");
+        }
+        return mKeyOsPatchLevel;
+    }
+
+    int getKeyVendorPatchLevel() {
+        if (mKeyVendorPatchLevel == null) {
+            throw new IllegalStateException("KeyVendorPatchLevel is not set.");
+        }
+        return mKeyVendorPatchLevel;
+    }
+
+    int getKeyOsVersion() {
+        if (mKeyOsVersion == null) {
+            throw new IllegalStateException("KeyOsVersion is not set.");
+        }
+        return mKeyOsVersion;
+    }
+
+    boolean isKeyRequiresUnlockedDevice() {
+        if (mKeyRequiresUnlockedDevice == null) {
+            throw new IllegalStateException("KeyRequiresUnlockedDevice is not set.");
+        }
+        return mKeyRequiresUnlockedDevice;
+    }
+
+    @Nullable
+    ByteString getVerifiedBootHash() {
+        return mVerifiedBootHash;
+    }
+
+    @Nullable
+    ByteString getVerifiedBootKey() {
+        return mVerifiedBootKey;
+    }
+
+    boolean isVerifiedBootLocked() {
+        if (mVerifiedBootLocked == null) {
+            throw new IllegalStateException("VerifiedBootLocked is not set.");
+        }
+        return mVerifiedBootLocked;
+    }
+
+    @Nullable
+    VerifiedBootState getVerifiedBootState() {
+        return mVerifiedBootState;
+    }
+
+    @Nullable
+    Map<String, Long> getApplicationPackageNameVersion() {
+        return Collections.unmodifiableMap(mApplicationPackageNameVersion);
+    }
+
+    @Nullable
+    List<ByteString> getApplicationCertificateDigests() {
+        return Collections.unmodifiableList(mApplicationCertificateDigests);
+    }
+
+    private AndroidKeystoreAttestationVerificationAttributes(X509Certificate x509Certificate)
+            throws Exception {
+        Certificate certificate = Certificate.getInstance(
+                new ASN1InputStream(x509Certificate.getEncoded()).readObject());
+        ASN1Sequence keyAttributes = (ASN1Sequence) certificate.getTBSCertificate().getExtensions()
+                .getExtensionParsedValue(
+                        new ASN1ObjectIdentifier(ANDROID_KEYMASTER_KEY_DESCRIPTION_EXTENSION_OID));
+        if (keyAttributes == null) {
+            throw new CertificateEncodingException(
+                    "No attestation extension found in certificate.");
+        }
+        this.mAttestationVersion = getIntegerFromAsn1(
+                keyAttributes.getObjectAt(ATTESTATION_VERSION_INDEX));
+        this.mAttestationSecurityLevel = getSecurityLevelEnum(
+                keyAttributes.getObjectAt(ATTESTATION_SECURITY_LEVEL_INDEX));
+        this.mAttestationHardwareBacked =
+                this.mAttestationSecurityLevel == SecurityLevel.TRUSTED_ENVIRONMENT;
+        this.mAttestationChallenge = getOctetsFromAsn1(
+                keyAttributes.getObjectAt(ATTESTATION_CHALLENGE_INDEX));
+        this.mKeymasterVersion = getIntegerFromAsn1(
+                keyAttributes.getObjectAt(KEYMASTER_VERSION_INDEX));
+        this.mKeymasterUniqueId = getOctetsFromAsn1(
+                keyAttributes.getObjectAt(KEYMASTER_UNIQUE_ID_INDEX));
+        this.mKeymasterSecurityLevel = getSecurityLevelEnum(
+                keyAttributes.getObjectAt(KEYMASTER_SECURITY_LEVEL_INDEX));
+        this.mKeymasterHardwareBacked =
+                this.mKeymasterSecurityLevel == SecurityLevel.TRUSTED_ENVIRONMENT;
+
+        ASN1Encodable[] softwareEnforced = ((ASN1Sequence)
+                keyAttributes.getObjectAt(SW_ENFORCED_INDEX)).toArray();
+        for (ASN1Encodable entry : softwareEnforced) {
+            ASN1TaggedObject taggedEntry = (ASN1TaggedObject) entry;
+            switch (taggedEntry.getTagNo()) {
+                case KM_TAG_ATTESTATION_APPLICATION_ID:
+                    parseAttestationApplicationId(
+                            getOctetsFromAsn1(taggedEntry.getObject()).toByteArray());
+                    break;
+                case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
+                    this.mKeyRequiresUnlockedDevice = getBoolFromAsn1(taggedEntry.getObject());
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        ASN1Encodable[] hardwareEnforced = ((ASN1Sequence)
+                keyAttributes.getObjectAt(HW_ENFORCED_INDEX)).toArray();
+        for (ASN1Encodable entry : hardwareEnforced) {
+            ASN1TaggedObject taggedEntry = (ASN1TaggedObject) entry;
+            switch (taggedEntry.getTagNo()) {
+                case KM_TAG_NO_AUTH_REQUIRED:
+                    this.mKeyAuthenticatorType = HW_AUTH_NONE;
+                    break;
+                case KM_TAG_ALL_APPLICATIONS:
+                    this.mKeyAllowedForAllApplications = true;
+                    break;
+                case KM_TAG_ROOT_OF_TRUST:
+                    ASN1Sequence rootOfTrust = (ASN1Sequence) taggedEntry.getObject();
+                    this.mVerifiedBootKey =
+                            getOctetsFromAsn1(rootOfTrust.getObjectAt(VERIFIED_BOOT_KEY_INDEX));
+                    this.mVerifiedBootLocked =
+                            getBoolFromAsn1(rootOfTrust.getObjectAt(VERIFIED_BOOT_LOCKED_INDEX));
+                    this.mVerifiedBootState =
+                            getVerifiedBootStateEnum(
+                                    rootOfTrust.getObjectAt(VERIFIED_BOOT_STATE_INDEX));
+                    // The verified boot hash was added in structure version 3 (Keymaster 4.0).
+                    if (mAttestationVersion >= 3) {
+                        this.mVerifiedBootHash =
+                                getOctetsFromAsn1(
+                                        rootOfTrust.getObjectAt(VERIFIED_BOOT_HASH_INDEX));
+                    }
+                    break;
+                case KM_TAG_OS_VERSION:
+                    this.mKeyOsVersion = getIntegerFromAsn1(taggedEntry.getObject());
+                    break;
+                case KM_TAG_OS_PATCHLEVEL:
+                    this.mKeyOsPatchLevel = getIntegerFromAsn1(taggedEntry.getObject());
+                    break;
+                case KM_TAG_ATTESTATION_ID_BRAND:
+                    this.mDeviceBrand = getUtf8FromOctetsFromAsn1(taggedEntry.getObject());
+                    break;
+                case KM_TAG_ATTESTATION_ID_DEVICE:
+                    this.mDeviceName = getUtf8FromOctetsFromAsn1(taggedEntry.getObject());
+                    break;
+                case KM_TAG_ATTESTATION_ID_PRODUCT:
+                    this.mDeviceProductName = getUtf8FromOctetsFromAsn1(taggedEntry.getObject());
+                    break;
+                case KM_TAG_VENDOR_PATCHLEVEL:
+                    this.mKeyVendorPatchLevel = getIntegerFromAsn1(taggedEntry.getObject());
+                    break;
+                case KM_TAG_BOOT_PATCHLEVEL:
+                    this.mKeyBootPatchLevel = getIntegerFromAsn1(taggedEntry.getObject());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private void parseAttestationApplicationId(byte [] attestationApplicationId)
+            throws Exception {
+        ASN1Sequence outerSequence = ASN1Sequence.getInstance(
+                new ASN1InputStream(attestationApplicationId).readObject());
+        Map<String, Long> packageNameVersion = new HashMap<>();
+        ASN1Set packageInfoSet = (ASN1Set) outerSequence.getObjectAt(PACKAGE_INFO_SET_INDEX);
+        for (ASN1Encodable packageInfoEntry : packageInfoSet.toArray()) {
+            ASN1Sequence packageInfoSequence = (ASN1Sequence) packageInfoEntry;
+            packageNameVersion.put(
+                    getUtf8FromOctetsFromAsn1(
+                            packageInfoSequence.getObjectAt(PACKAGE_INFO_NAME_INDEX)),
+                    getLongFromAsn1(packageInfoSequence.getObjectAt(PACKAGE_INFO_VERSION_INDEX)));
+        }
+        List<ByteString> certificateDigests = new ArrayList<>();
+        ASN1Set certificateDigestSet =
+                (ASN1Set) outerSequence.getObjectAt(PACKAGE_SIGNATURE_SET_INDEX);
+        for (ASN1Encodable certificateDigestEntry : certificateDigestSet.toArray()) {
+            certificateDigests.add(getOctetsFromAsn1(certificateDigestEntry));
+        }
+        this.mApplicationPackageNameVersion = Collections.unmodifiableMap(packageNameVersion);
+        this.mApplicationCertificateDigests = Collections.unmodifiableList(certificateDigests);
+
+    }
+
+    private VerifiedBootState getVerifiedBootStateEnum(ASN1Encodable asn1) {
+        int verifiedBoot = getEnumFromAsn1(asn1);
+        switch (verifiedBoot) {
+            case KM_VERIFIED_BOOT_STATE_VERIFIED:
+                return VerifiedBootState.VERIFIED;
+            case KM_VERIFIED_BOOT_STATE_SELF_SIGNED:
+                return VerifiedBootState.SELF_SIGNED;
+            case KM_VERIFIED_BOOT_STATE_UNVERIFIED:
+                return VerifiedBootState.UNVERIFIED;
+            case KM_VERIFIED_BOOT_STATE_FAILED:
+                return VerifiedBootState.FAILED;
+            default:
+                throw new IllegalArgumentException("Invalid verified boot state.");
+        }
+    }
+
+    private SecurityLevel getSecurityLevelEnum(ASN1Encodable asn1) {
+        int securityLevel = getEnumFromAsn1(asn1);
+        switch (securityLevel) {
+            case KM_SECURITY_LEVEL_SOFTWARE:
+                return SecurityLevel.SOFTWARE;
+            case KM_SECURITY_LEVEL_TRUSTED_ENVIRONMENT:
+                return SecurityLevel.TRUSTED_ENVIRONMENT;
+            case KM_SECURITY_LEVEL_STRONG_BOX:
+                return SecurityLevel.STRONG_BOX;
+            default:
+                throw new IllegalArgumentException("Invalid security level.");
+        }
+    }
+
+    @NonNull
+    private ByteString getOctetsFromAsn1(ASN1Encodable asn1) {
+        return ByteString.copyFrom(((ASN1OctetString) asn1).getOctets());
+    }
+
+    @NonNull
+    private String getUtf8FromOctetsFromAsn1(ASN1Encodable asn1) {
+        return new String(((ASN1OctetString) asn1).getOctets(), StandardCharsets.UTF_8);
+    }
+
+    @NonNull
+    private int getIntegerFromAsn1(ASN1Encodable asn1) {
+        return ((ASN1Integer) asn1).getValue().intValueExact();
+    }
+
+    @NonNull
+    private long getLongFromAsn1(ASN1Encodable asn1) {
+        return ((ASN1Integer) asn1).getValue().longValueExact();
+    }
+
+    @NonNull
+    private int getEnumFromAsn1(ASN1Encodable asn1) {
+        return ((ASN1Enumerated) asn1).getValue().intValueExact();
+    }
+
+    @Nullable
+    private Boolean getBoolFromAsn1(ASN1Encodable asn1) {
+        if (asn1 instanceof ASN1Boolean) {
+            return ((ASN1Boolean) asn1).isTrue();
+        }
+        return null;
+    }
+}
diff --git a/services/core/java/com/android/server/security/AttestationVerificationManagerService.java b/services/core/java/com/android/server/security/AttestationVerificationManagerService.java
index 243efb5..863f2d1 100644
--- a/services/core/java/com/android/server/security/AttestationVerificationManagerService.java
+++ b/services/core/java/com/android/server/security/AttestationVerificationManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.security;
 
+import static android.security.attestationverification.AttestationVerificationManager.PROFILE_PEER_DEVICE;
 import static android.security.attestationverification.AttestationVerificationManager.PROFILE_SELF_TRUSTED;
 import static android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE;
 import static android.security.attestationverification.AttestationVerificationManager.RESULT_UNKNOWN;
@@ -44,9 +45,11 @@
 public class AttestationVerificationManagerService extends SystemService {
 
     private static final String TAG = "AVF";
+    private final AttestationVerificationPeerDeviceVerifier mPeerDeviceVerifier;
 
-    public AttestationVerificationManagerService(final Context context) {
+    public AttestationVerificationManagerService(final Context context) throws Exception {
         super(context);
+        mPeerDeviceVerifier = new AttestationVerificationPeerDeviceVerifier(context);
     }
 
     private final IBinder mService = new IAttestationVerificationManagerService.Stub() {
@@ -83,7 +86,7 @@
         result.token = null;
         switch (profile.getAttestationProfileId()) {
             case PROFILE_SELF_TRUSTED:
-                Slog.d(TAG, "Verifying Self trusted profile.");
+                Slog.d(TAG, "Verifying Self Trusted profile.");
                 try {
                     result.resultCode =
                             AttestationVerificationSelfTrustedVerifierForTesting.getInstance()
@@ -92,6 +95,11 @@
                     result.resultCode = RESULT_FAILURE;
                 }
                 break;
+            case PROFILE_PEER_DEVICE:
+                Slog.d(TAG, "Verifying Peer Device profile.");
+                result.resultCode = mPeerDeviceVerifier.verifyAttestation(
+                        localBindingType, requirements, attestation);
+                break;
             default:
                 Slog.d(TAG, "No profile found, defaulting.");
                 result.resultCode = RESULT_UNKNOWN;
diff --git a/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java b/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java
new file mode 100644
index 0000000..0f8be5a
--- /dev/null
+++ b/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java
@@ -0,0 +1,510 @@
+/*
+ * 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.security;
+
+import static android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE;
+import static android.security.attestationverification.AttestationVerificationManager.PARAM_PUBLIC_KEY;
+import static android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE;
+import static android.security.attestationverification.AttestationVerificationManager.RESULT_SUCCESS;
+import static android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE;
+import static android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY;
+
+import static com.android.server.security.AndroidKeystoreAttestationVerificationAttributes.VerifiedBootState.VERIFIED;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+import org.json.JSONObject;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.cert.CertPath;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.PKIXParameters;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Verifies Android key attestation according to the {@code PROFILE_PEER_DEVICE} profile.
+ *
+ * Trust anchors are vendor-defined via the vendor_required_attestation_certificates.xml resource.
+ * The profile is satisfied by checking all the following:
+ * * TrustAnchor match
+ * * Certificate validity
+ * * Android OS 10 or higher
+ * * Hardware backed key store
+ * * Verified boot locked
+ * * Remote Patch level must be within 1 year of local patch if local patch is less than 1 year old.
+ *
+ */
+class AttestationVerificationPeerDeviceVerifier {
+    private static final String TAG = "AVF";
+    private static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int MAX_PATCH_AGE_MONTHS = 12;
+
+    private final Context mContext;
+    private final Set<TrustAnchor> mTrustAnchors;
+    private final boolean mRevocationEnabled;
+    private final LocalDate mTestSystemDate;
+    private final LocalDate mTestLocalPatchDate;
+    private CertificateFactory mCertificateFactory;
+    private CertPathValidator mCertPathValidator;
+
+    private static void debugVerboseLog(String str, Throwable t) {
+        if (DEBUG) {
+            Slog.v(TAG, str, t);
+        }
+    }
+
+    private static void debugVerboseLog(String str) {
+        if (DEBUG) {
+            Slog.v(TAG, str);
+        }
+    }
+
+    AttestationVerificationPeerDeviceVerifier(@NonNull Context context) throws Exception {
+        mContext = Objects.requireNonNull(context);
+        mCertificateFactory = CertificateFactory.getInstance("X.509");
+        mCertPathValidator = CertPathValidator.getInstance("PKIX");
+        mTrustAnchors = getTrustAnchors();
+        mRevocationEnabled = true;
+        mTestSystemDate = null;
+        mTestLocalPatchDate = null;
+    }
+
+    // Use ONLY for hermetic unit testing.
+    @VisibleForTesting
+    AttestationVerificationPeerDeviceVerifier(@NonNull Context context,
+            Set<TrustAnchor> trustAnchors, boolean revocationEnabled,
+            LocalDate systemDate, LocalDate localPatchDate) throws Exception {
+        mContext = Objects.requireNonNull(context);
+        mCertificateFactory = CertificateFactory.getInstance("X.509");
+        mCertPathValidator = CertPathValidator.getInstance("PKIX");
+        mTrustAnchors = trustAnchors;
+        mRevocationEnabled = revocationEnabled;
+        mTestSystemDate = systemDate;
+        mTestLocalPatchDate = localPatchDate;
+    }
+
+    /**
+     * Verifies attestation for public key or challenge local binding.
+     *
+     * The attestations must be suitable for {@link java.security.cert.CertificateFactory}
+     * The certificates in the attestation provided must be DER-encoded and may be supplied in
+     * binary or printable (Base64) encoding. If the certificate is provided in Base64 encoding,
+     * it must be bounded at the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
+     * the end by -----END CERTIFICATE-----.
+     *
+     * @param localBindingType Only {@code TYPE_PUBLIC_KEY} and {@code TYPE_CHALLENGE} supported.
+     * @param requirements Only {@code PARAM_PUBLIC_KEY} and {@code PARAM_CHALLENGE} supported.
+     * @param attestation Certificates should be DER encoded with leaf certificate appended first.
+     */
+    int verifyAttestation(
+            int localBindingType, @NonNull Bundle requirements, @NonNull byte[] attestation) {
+        int status = RESULT_FAILURE;
+
+        if (mCertificateFactory == null) {
+            debugVerboseLog("Was unable to initialize CertificateFactory onCreate.");
+            return status;
+        }
+
+        if (mCertPathValidator == null) {
+            debugVerboseLog("Was unable to initialize CertPathValidator onCreate.");
+            return status;
+        }
+
+        List<X509Certificate> certificates;
+        try {
+            certificates = getCertificates(attestation);
+        } catch (CertificateException e) {
+            debugVerboseLog("Unable to parse attestation certificates.", e);
+            return status;
+        }
+
+        if (certificates.isEmpty()) {
+            debugVerboseLog("Attestation contains no certificates.");
+            return status;
+        }
+
+        X509Certificate leafNode = certificates.get(0);
+        if (validateRequirements(localBindingType, requirements)
+                && validateCertificateChain(certificates)
+                && checkCertificateAttributes(leafNode, localBindingType, requirements)) {
+            status = RESULT_SUCCESS;
+        } else {
+            status = RESULT_FAILURE;
+        }
+        return status;
+    }
+
+    @NonNull
+    private List<X509Certificate> getCertificates(byte[] attestation)
+            throws CertificateException {
+        List<X509Certificate> certificates = new ArrayList<>();
+        ByteArrayInputStream bis = new ByteArrayInputStream(attestation);
+        while (bis.available() > 0) {
+            certificates.add((X509Certificate) mCertificateFactory.generateCertificate(bis));
+        }
+
+        return certificates;
+    }
+
+    private boolean validateRequirements(int localBindingType, Bundle requirements) {
+        if (requirements.size() != 1) {
+            debugVerboseLog("Requirements does not contain exactly 1 key.");
+            return false;
+        }
+
+        if (localBindingType != TYPE_PUBLIC_KEY && localBindingType != TYPE_CHALLENGE) {
+            debugVerboseLog("Binding type is not supported: " + localBindingType);
+            return false;
+        }
+
+        if (localBindingType == TYPE_PUBLIC_KEY && !requirements.containsKey(PARAM_PUBLIC_KEY)) {
+            debugVerboseLog("Requirements does not contain key: " + PARAM_PUBLIC_KEY);
+            return false;
+        }
+
+        if (localBindingType == TYPE_CHALLENGE && !requirements.containsKey(PARAM_CHALLENGE)) {
+            debugVerboseLog("Requirements does not contain key: " + PARAM_CHALLENGE);
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean validateCertificateChain(List<X509Certificate> certificates) {
+        if (certificates.size() < 2) {
+            debugVerboseLog("Certificate chain less than 2 in size.");
+            return false;
+        }
+
+        try {
+            CertPath certificatePath = mCertificateFactory.generateCertPath(certificates);
+            PKIXParameters validationParams = new PKIXParameters(mTrustAnchors);
+            if (mRevocationEnabled) {
+                // Checks Revocation Status List based on
+                // https://developer.android.com/training/articles/security-key-attestation#certificate_status
+                PKIXCertPathChecker checker = new AndroidRevocationStatusListChecker();
+                validationParams.addCertPathChecker(checker);
+            }
+            // Do not use built-in revocation status checker.
+            validationParams.setRevocationEnabled(false);
+            mCertPathValidator.validate(certificatePath, validationParams);
+        } catch (Throwable t) {
+            debugVerboseLog("Invalid certificate chain.", t);
+            return false;
+        }
+        return true;
+    }
+
+    private Set<TrustAnchor> getTrustAnchors() throws CertPathValidatorException {
+        Set<TrustAnchor> modifiableSet = new HashSet<>();
+        try {
+            for (String certString: getTrustAnchorResources()) {
+                modifiableSet.add(
+                        new TrustAnchor((X509Certificate) mCertificateFactory.generateCertificate(
+                                new ByteArrayInputStream(getCertificateBytes(certString))), null));
+            }
+        } catch (CertificateException e) {
+            e.printStackTrace();
+            throw new CertPathValidatorException("Invalid trust anchor certificate.", e);
+        }
+        return Collections.unmodifiableSet(modifiableSet);
+    }
+
+    private byte[] getCertificateBytes(String certString) {
+        String formattedCertString = certString.replaceAll("\\s+", "\n");
+        formattedCertString = formattedCertString.replaceAll(
+                "-BEGIN\\nCERTIFICATE-", "-BEGIN CERTIFICATE-");
+        formattedCertString = formattedCertString.replaceAll(
+                "-END\\nCERTIFICATE-", "-END CERTIFICATE-");
+        return formattedCertString.getBytes(UTF_8);
+    }
+
+    private String[] getTrustAnchorResources() {
+        return mContext.getResources().getStringArray(
+                R.array.vendor_required_attestation_certificates);
+    }
+
+    private boolean checkCertificateAttributes(
+            X509Certificate leafCertificate, int localBindingType, Bundle requirements) {
+        AndroidKeystoreAttestationVerificationAttributes attestationAttributes;
+        try {
+            attestationAttributes =
+                    AndroidKeystoreAttestationVerificationAttributes.fromCertificate(
+                            leafCertificate);
+        } catch (Throwable t) {
+            debugVerboseLog("Could not get ParsedAttestationAttributes from Certificate.", t);
+            return false;
+        }
+
+        // Checks for support of Keymaster 4.
+        if (attestationAttributes.getAttestationVersion() < 3) {
+            debugVerboseLog("Attestation version is not at least 3 (Keymaster 4).");
+            return false;
+        }
+
+        // Checks for support of Keymaster 4.
+        if (attestationAttributes.getKeymasterVersion() < 4) {
+            debugVerboseLog("Keymaster version is not at least 4.");
+            return false;
+        }
+
+        // First two characters are Android OS version.
+        if (attestationAttributes.getKeyOsVersion() < 100000) {
+            debugVerboseLog("Android OS version is not 10+.");
+            return false;
+        }
+
+        if (!attestationAttributes.isAttestationHardwareBacked()) {
+            debugVerboseLog("Key is not HW backed.");
+            return false;
+        }
+
+        if (!attestationAttributes.isKeymasterHardwareBacked()) {
+            debugVerboseLog("Keymaster is not HW backed.");
+            return false;
+        }
+
+        if (attestationAttributes.getVerifiedBootState() != VERIFIED) {
+            debugVerboseLog("Boot state not Verified.");
+            return false;
+        }
+
+        try {
+            if (!attestationAttributes.isVerifiedBootLocked()) {
+                debugVerboseLog("Verified boot state is not locked.");
+                return false;
+            }
+        } catch (IllegalStateException e) {
+            debugVerboseLog("VerifiedBootLocked is not set.", e);
+            return false;
+        }
+
+        // Patch level integer YYYYMM is expected to be within 1 year of today.
+        if (!isValidPatchLevel(attestationAttributes.getKeyOsPatchLevel())) {
+            debugVerboseLog("OS patch level is not within valid range.");
+            return false;
+        }
+
+        // Patch level integer YYYYMMDD is expected to be within 1 year of today.
+        if (!isValidPatchLevel(attestationAttributes.getKeyBootPatchLevel())) {
+            debugVerboseLog("Boot patch level is not within valid range.");
+            return false;
+        }
+
+        if (!isValidPatchLevel(attestationAttributes.getKeyVendorPatchLevel())) {
+            debugVerboseLog("Vendor patch level is not within valid range.");
+            return false;
+        }
+
+        if (!isValidPatchLevel(attestationAttributes.getKeyBootPatchLevel())) {
+            debugVerboseLog("Boot patch level is not within valid range.");
+            return false;
+        }
+
+        // Verify leaf public key matches provided public key.
+        if (localBindingType == TYPE_PUBLIC_KEY
+                && !Arrays.equals(requirements.getByteArray(PARAM_PUBLIC_KEY),
+                                  leafCertificate.getPublicKey().getEncoded())) {
+            debugVerboseLog("Provided public key does not match leaf certificate public key.");
+            return false;
+        }
+
+        // Verify challenge matches provided challenge.
+        if (localBindingType == TYPE_CHALLENGE
+                && !Arrays.equals(requirements.getByteArray(PARAM_CHALLENGE),
+                                  attestationAttributes.getAttestationChallenge().toByteArray())) {
+            debugVerboseLog("Provided challenge does not match leaf certificate challenge.");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Validates patchLevel passed is within range of the local device patch date if local patch is
+     * not over one year old. Since the time can be changed on device, just checking the patch date
+     * is not enough. Therefore, we also confirm the patch level for the remote and local device are
+     * similar.
+     */
+    private boolean isValidPatchLevel(int patchLevel) {
+        LocalDate currentDate = mTestSystemDate != null
+                ? mTestSystemDate : LocalDate.now(ZoneId.systemDefault());
+
+        // Convert local patch date to LocalDate.
+        LocalDate localPatchDate;
+        try {
+            if (mTestLocalPatchDate != null) {
+                localPatchDate = mTestLocalPatchDate;
+            } else {
+                localPatchDate = LocalDate.parse(Build.VERSION.SECURITY_PATCH);
+            }
+        } catch (Throwable t) {
+            debugVerboseLog("Build.VERSION.SECURITY_PATCH: "
+                    + Build.VERSION.SECURITY_PATCH + " is not in format YYYY-MM-DD");
+            return false;
+        }
+
+        // Check local patch date is not in last year of system clock.
+        if (ChronoUnit.MONTHS.between(localPatchDate, currentDate) > MAX_PATCH_AGE_MONTHS) {
+            return true;
+        }
+
+        // Convert remote patch dates to LocalDate.
+        String remoteDeviceDateStr = String.valueOf(patchLevel);
+        if (remoteDeviceDateStr.length() != 6 && remoteDeviceDateStr.length() != 8) {
+            debugVerboseLog("Patch level is not in format YYYYMM or YYYYMMDD");
+            return false;
+        }
+
+        int patchYear = Integer.parseInt(remoteDeviceDateStr.substring(0, 4));
+        int patchMonth = Integer.parseInt(remoteDeviceDateStr.substring(4, 6));
+        LocalDate remotePatchDate = LocalDate.of(patchYear, patchMonth, 1);
+
+        // Check patch dates are within 1 year of each other
+        boolean IsRemotePatchWithinOneYearOfLocalPatch;
+        if (remotePatchDate.compareTo(localPatchDate) > 0) {
+            IsRemotePatchWithinOneYearOfLocalPatch = ChronoUnit.MONTHS.between(
+                    localPatchDate, remotePatchDate) <= MAX_PATCH_AGE_MONTHS;
+        } else if (remotePatchDate.compareTo(localPatchDate) < 0) {
+            IsRemotePatchWithinOneYearOfLocalPatch = ChronoUnit.MONTHS.between(
+                    remotePatchDate, localPatchDate) <= MAX_PATCH_AGE_MONTHS;
+        } else {
+            IsRemotePatchWithinOneYearOfLocalPatch = true;
+        }
+
+        return IsRemotePatchWithinOneYearOfLocalPatch;
+    }
+
+    /**
+     * Checks certificate revocation status.
+     *
+     * Queries status list from android.googleapis.com/attestation/status and checks for
+     * the existence of certificate's serial number. If serial number exists in map, then fail.
+     */
+    private final class AndroidRevocationStatusListChecker extends PKIXCertPathChecker {
+        private static final String TOP_LEVEL_JSON_PROPERTY_KEY = "entries";
+        private static final String STATUS_PROPERTY_KEY = "status";
+        private static final String REASON_PROPERTY_KEY = "reason";
+        private String mStatusUrl;
+        private JSONObject mJsonStatusMap;
+
+        @Override
+        public void init(boolean forward) throws CertPathValidatorException {
+            mStatusUrl = getRevocationListUrl();
+            if (mStatusUrl == null || mStatusUrl.isEmpty()) {
+                throw new CertPathValidatorException(
+                        "R.string.vendor_required_attestation_revocation_list_url is empty.");
+            }
+            // TODO(b/221067843): Update to only pull status map on non critical path and if
+            // out of date (24hrs).
+            mJsonStatusMap = getStatusMap(mStatusUrl);
+        }
+
+        @Override
+        public boolean isForwardCheckingSupported() {
+            return false;
+        }
+
+        @Override
+        public Set<String> getSupportedExtensions() {
+            return null;
+        }
+
+        @Override
+        public void check(Certificate cert, Collection<String> unresolvedCritExts)
+                throws CertPathValidatorException {
+            X509Certificate x509Certificate = (X509Certificate) cert;
+            // The json key is the certificate's serial number converted to lowercase hex.
+            String serialNumber = x509Certificate.getSerialNumber().toString(16);
+
+            if (serialNumber == null) {
+                throw new CertPathValidatorException("Certificate serial number can not be null.");
+            }
+
+            if (mJsonStatusMap.has(serialNumber)) {
+                JSONObject revocationStatus;
+                String status;
+                String reason;
+                try {
+                    revocationStatus = mJsonStatusMap.getJSONObject(serialNumber);
+                    status = revocationStatus.getString(STATUS_PROPERTY_KEY);
+                    reason = revocationStatus.getString(REASON_PROPERTY_KEY);
+                } catch (Throwable t) {
+                    throw new CertPathValidatorException("Unable get properties for certificate "
+                            + "with serial number " + serialNumber);
+                }
+                throw new CertPathValidatorException(
+                        "Invalid certificate with serial number " + serialNumber
+                                + " has status " + status
+                                + " because reason " + reason);
+            }
+        }
+
+        private JSONObject getStatusMap(String stringUrl) throws CertPathValidatorException {
+            URL url;
+            try {
+                url = new URL(stringUrl);
+            } catch (Throwable t) {
+                throw new CertPathValidatorException(
+                        "Unable to get revocation status from " + mStatusUrl, t);
+            }
+
+            try (InputStream inputStream = url.openStream()) {
+                JSONObject statusListJson = new JSONObject(
+                        new String(inputStream.readAllBytes(), UTF_8));
+                return statusListJson.getJSONObject(TOP_LEVEL_JSON_PROPERTY_KEY);
+            } catch (Throwable t) {
+                throw new CertPathValidatorException(
+                        "Unable to parse revocation status from " + mStatusUrl, t);
+            }
+        }
+
+        private String getRevocationListUrl() {
+            return mContext.getResources().getString(
+                    R.string.vendor_required_attestation_revocation_list_url);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
index a8e2d43..2f68f56 100644
--- a/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/sensorprivacy/SensorPrivacyService.java
@@ -918,7 +918,6 @@
          */
         @Override
         public void addToggleSensorPrivacyListener(ISensorPrivacyListener listener) {
-            Log.d("evan", "trying to add from " + Binder.getCallingUid());
             enforceObserveSensorPrivacyPermission();
             if (listener == null) {
                 throw new IllegalArgumentException("listener cannot be null");
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java
index c638201..9bbae4b 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Compat.java
@@ -29,7 +29,9 @@
 import android.os.IHwBinder;
 import android.os.RemoteException;
 import android.system.OsConstants;
+import android.util.Log;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
@@ -54,6 +56,8 @@
  * </ul>
  */
 final class SoundTriggerHw2Compat implements ISoundTriggerHal {
+    private static final String TAG = "SoundTriggerHw2Compat";
+
     private final @NonNull Runnable mRebootRunnable;
     private final @NonNull IHwBinder mBinder;
     private @NonNull android.hardware.soundtrigger.V2_0.ISoundTriggerHw mUnderlying_2_0;
@@ -226,6 +230,16 @@
             return handle.get();
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
+        } finally {
+            // TODO(b/219825762): We should be able to use the entire object in a try-with-resources
+            //   clause, instead of having to explicitly close internal fields.
+            if (hidlModel.data != null) {
+                try {
+                    hidlModel.data.close();
+                } catch (IOException e) {
+                    Log.e(TAG, "Failed to close file", e);
+                }
+            }
         }
     }
 
@@ -252,6 +266,16 @@
             return handle.get();
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
+        } finally {
+            // TODO(b/219825762): We should be able to use the entire object in a try-with-resources
+            //   clause, instead of having to explicitly close internal fields.
+            if (hidlModel.common.data != null) {
+                try {
+                    hidlModel.common.data.close();
+                } catch (IOException e) {
+                    Log.e(TAG, "Failed to close file", e);
+                }
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 1b15351..2e60f13 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -2668,6 +2668,7 @@
         StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
         StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
         StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
+        StatFs metadataFsSystem = new StatFs(Environment.getMetadataDirectory().getAbsolutePath());
 
         pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag,
                 FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA, statFsData.getAvailableBytes(),
@@ -2680,6 +2681,10 @@
         pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag,
                 FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM,
                 statFsSystem.getAvailableBytes(), statFsSystem.getTotalBytes()));
+
+        pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag,
+                FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__METADATA,
+                metadataFsSystem.getAvailableBytes(), metadataFsSystem.getTotalBytes()));
         return StatsManager.PULL_SUCCESS;
     }
 
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index 411f3dc..11fd99c 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -157,7 +157,7 @@
      * @see com.android.internal.statusbar.IStatusBar#requestWindowMagnificationConnection(boolean
      * request)
      */
-    void requestWindowMagnificationConnection(boolean request);
+    boolean requestWindowMagnificationConnection(boolean request);
 
     /**
      * Handles a logging command from the WM shell command.
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 66904b1..59b9daf 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -18,9 +18,9 @@
 
 import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS;
 import static android.app.StatusBarManager.DISABLE2_NOTIFICATION_SHADE;
-import static android.app.StatusBarManager.NAV_BAR_MODE_OVERRIDE_KIDS;
-import static android.app.StatusBarManager.NAV_BAR_MODE_OVERRIDE_NONE;
-import static android.app.StatusBarManager.NavBarModeOverride;
+import static android.app.StatusBarManager.NAV_BAR_MODE_DEFAULT;
+import static android.app.StatusBarManager.NAV_BAR_MODE_KIDS;
+import static android.app.StatusBarManager.NavBarMode;
 import static android.app.StatusBarManager.SessionFlags;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
@@ -637,12 +637,14 @@
         }
 
         @Override
-        public void requestWindowMagnificationConnection(boolean request) {
+        public boolean requestWindowMagnificationConnection(boolean request) {
             if (mBar != null) {
                 try {
                     mBar.requestWindowMagnificationConnection(request);
+                    return true;
                 } catch (RemoteException ex) { }
             }
+            return false;
         }
 
         @Override
@@ -856,11 +858,11 @@
     }
 
     @Override
-    public void onBiometricAuthenticated() {
+    public void onBiometricAuthenticated(@Modality int modality) {
         enforceBiometricDialog();
         if (mBar != null) {
             try {
-                mBar.onBiometricAuthenticated();
+                mBar.onBiometricAuthenticated(modality);
             } catch (RemoteException ex) {
             }
         }
@@ -1945,26 +1947,26 @@
     }
 
     /**
-     * Sets or removes the navigation bar mode override.
+     * Sets or removes the navigation bar mode.
      *
-     * @param navBarModeOverride the mode of the navigation bar override to be set.
+     * @param navBarMode the mode of the navigation bar to be set.
      */
-    public void setNavBarModeOverride(@NavBarModeOverride int navBarModeOverride) {
+    public void setNavBarMode(@NavBarMode int navBarMode) {
         enforceStatusBar();
-        if (navBarModeOverride != NAV_BAR_MODE_OVERRIDE_NONE
-                && navBarModeOverride != NAV_BAR_MODE_OVERRIDE_KIDS) {
-            throw new UnsupportedOperationException(
-                    "Supplied navBarModeOverride not supported: " + navBarModeOverride);
+        if (navBarMode != NAV_BAR_MODE_DEFAULT && navBarMode != NAV_BAR_MODE_KIDS) {
+            throw new IllegalArgumentException("Supplied navBarMode not supported: " + navBarMode);
         }
 
         final int userId = mCurrentUserId;
         final long userIdentity = Binder.clearCallingIdentity();
         try {
             Settings.Secure.putIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.NAV_BAR_KIDS_MODE, navBarModeOverride, userId);
+                    Settings.Secure.NAV_BAR_KIDS_MODE, navBarMode, userId);
+            Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.NAV_BAR_FORCE_VISIBLE, navBarMode, userId);
 
             IOverlayManager overlayManager = getOverlayManager();
-            if (overlayManager != null && navBarModeOverride == NAV_BAR_MODE_OVERRIDE_KIDS
+            if (overlayManager != null && navBarMode == NAV_BAR_MODE_KIDS
                     && isPackageSupported(NAV_BAR_MODE_3BUTTON_OVERLAY)) {
                 overlayManager.setEnabledExclusiveInCategory(NAV_BAR_MODE_3BUTTON_OVERLAY, userId);
             }
@@ -1976,14 +1978,14 @@
     }
 
     /**
-     * Gets the navigation bar mode override. Returns default value if no override is set.
+     * Gets the navigation bar mode. Returns default value if no mode is set.
      *
      * @hide
      */
-    public @NavBarModeOverride int getNavBarModeOverride() {
+    public @NavBarMode int getNavBarMode() {
         enforceStatusBar();
 
-        int navBarKidsMode = NAV_BAR_MODE_OVERRIDE_NONE;
+        int navBarKidsMode = NAV_BAR_MODE_DEFAULT;
         final int userId = mCurrentUserId;
         final long userIdentity = Binder.clearCallingIdentity();
         try {
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/timezonedetector/OWNERS b/services/core/java/com/android/server/timezonedetector/OWNERS
index 0293242..485a0dd 100644
--- a/services/core/java/com/android/server/timezonedetector/OWNERS
+++ b/services/core/java/com/android/server/timezonedetector/OWNERS
@@ -3,5 +3,6 @@
 # ultimately referenced by other OWNERS files for components maintained by the same team.
 nfuller@google.com
 jmorace@google.com
+kanyinsola@google.com
 mingaleev@google.com
 narayan@google.com
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/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 1dea3d7..20cd8f5 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -17,6 +17,7 @@
 package com.android.server.trust;
 
 import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_DISPLAY_MESSAGE;
+import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
 
 import android.annotation.TargetApi;
 import android.app.AlarmManager;
@@ -158,7 +159,7 @@
                     mMessage = (CharSequence) msg.obj;
                     int flags = msg.arg1;
                     mDisplayTrustGrantedMessage = (flags & FLAG_GRANT_TRUST_DISPLAY_MESSAGE) != 0;
-                    if ((flags & TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0) {
+                    if ((flags & FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0) {
                         mWaitingForTrustableDowngrade = true;
                     } else {
                         mWaitingForTrustableDowngrade = false;
@@ -638,6 +639,11 @@
         return mTrustable && mManagingTrust && !mTrustDisabledByDpm;
     }
 
+    /** Set the trustagent as not trustable */
+    public void setUntrustable() {
+        mTrustable = false;
+    }
+
     public boolean isManagingTrust() {
         return mManagingTrust && !mTrustDisabledByDpm;
     }
@@ -665,6 +671,7 @@
         mContext.unbindService(mConnection);
         mBound = false;
         mContext.unregisterReceiver(mBroadcastReceiver);
+        mContext.unregisterReceiver(mTrustableDowngradeReceiver);
         mTrustAgentService = null;
         mSetTrustAgentFeaturesToken = null;
         mHandler.sendEmptyMessage(MSG_REVOKE_TRUST);
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index b4c54f9..bd4b8d1 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.trust;
 
+import static android.service.trust.TrustAgentService.FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE;
+
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -127,13 +129,16 @@
     private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
     private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
     private static final int MSG_SCHEDULE_TRUST_TIMEOUT = 15;
-    public static final int MSG_USER_REQUESTED_UNLOCK = 16;
+    private static final int MSG_USER_REQUESTED_UNLOCK = 16;
+    private static final int MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH = 17;
 
     private static final String REFRESH_DEVICE_LOCKED_EXCEPT_USER = "except";
 
     private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
     private static final String TRUST_TIMEOUT_ALARM_TAG = "TrustManagerService.trustTimeoutForUser";
     private static final long TRUST_TIMEOUT_IN_MILLIS = 4 * 60 * 60 * 1000;
+    private static final long TRUSTABLE_IDLE_TIMEOUT_IN_MILLIS = 8 * 60 * 60 * 1000;
+    private static final long TRUSTABLE_TIMEOUT_IN_MILLIS = 24 * 60 * 60 * 1000;
 
     private static final String PRIV_NAMESPACE = "http://schemas.android.com/apk/prv/res/android";
 
@@ -203,9 +208,18 @@
     @GuardedBy("mUsersUnlockedByBiometric")
     private final SparseBooleanArray mUsersUnlockedByBiometric = new SparseBooleanArray();
 
-    private final ArrayMap<Integer, TrustTimeoutAlarmListener> mTrustTimeoutAlarmListenerForUser =
+    private enum TimeoutType {
+        TRUSTED,
+        TRUSTABLE
+    }
+    private final ArrayMap<Integer, TrustedTimeoutAlarmListener> mTrustTimeoutAlarmListenerForUser =
             new ArrayMap<>();
+    private final SparseArray<TrustableTimeoutAlarmListener> mTrustableTimeoutAlarmListenerForUser =
+            new SparseArray<>();
+    private final SparseArray<TrustableTimeoutAlarmListener>
+            mIdleTrustableTimeoutAlarmListenerForUser = new SparseArray<>();
     private AlarmManager mAlarmManager;
+    private final Object mAlarmLock = new Object();
     private final SettingsObserver mSettingsObserver;
 
     private final StrongAuthTracker mStrongAuthTracker;
@@ -258,7 +272,7 @@
 
         private final boolean mIsAutomotive;
         private final ContentResolver mContentResolver;
-        private boolean mTrustAgentsExtendUnlock;
+        private boolean mTrustAgentsNonrenewableTrust;
         private boolean mLockWhenTrustLost;
 
         /**
@@ -295,11 +309,11 @@
         @Override
         public void onChange(boolean selfChange, Uri uri) {
             if (TRUST_AGENTS_EXTEND_UNLOCK.equals(uri)) {
-                // Smart lock should only extend unlock. The only exception is for automotive,
-                // where it can actively unlock the head unit.
+                // Smart lock should only grant non-renewable trust. The only exception is for
+                // automotive, where it can actively unlock the head unit.
                 int defaultValue = mIsAutomotive ? 0 : 1;
 
-                mTrustAgentsExtendUnlock =
+                mTrustAgentsNonrenewableTrust =
                         Settings.Secure.getIntForUser(
                                 mContentResolver,
                                 Settings.Secure.TRUST_AGENTS_EXTEND_UNLOCK,
@@ -315,8 +329,8 @@
             }
         }
 
-        boolean getTrustAgentsExtendUnlock() {
-            return mTrustAgentsExtendUnlock;
+        boolean getTrustAgentsNonrenewableTrust() {
+            return mTrustAgentsNonrenewableTrust;
         }
 
         boolean getLockWhenTrustLost() {
@@ -339,36 +353,53 @@
 
             // If active unlocking is not allowed, cancel any pending trust timeouts because the
             // screen is already locked.
-            TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
-            if (alarm != null && mSettingsObserver.getTrustAgentsExtendUnlock()) {
+            TrustedTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
+            if (alarm != null && mSettingsObserver.getTrustAgentsNonrenewableTrust()) {
                 mAlarmManager.cancel(alarm);
                 alarm.setQueued(false /* isQueued */);
             }
         }
     }
 
-    private void scheduleTrustTimeout(int userId, boolean override) {
+    private void scheduleTrustTimeout(boolean override, boolean isTrustableTimeout) {
         int shouldOverride = override ? 1 : 0;
-        if (override) {
-            shouldOverride = 1;
-        }
-        mHandler.obtainMessage(MSG_SCHEDULE_TRUST_TIMEOUT, userId, shouldOverride).sendToTarget();
+        int trustableTimeout = isTrustableTimeout ? 1 : 0;
+        mHandler.obtainMessage(MSG_SCHEDULE_TRUST_TIMEOUT, shouldOverride,
+                trustableTimeout).sendToTarget();
     }
 
-    private void handleScheduleTrustTimeout(int userId, int shouldOverride) {
+    private void handleScheduleTrustTimeout(boolean shouldOverride, TimeoutType timeoutType) {
+        int userId = mCurrentUser;
+        if (timeoutType == TimeoutType.TRUSTABLE) {
+            // don't override the hard timeout unless biometric or knowledge factor authentication
+            // occurs which isn't where this is called from. Override the idle timeout what the
+            // calling function has determined.
+            handleScheduleTrustableTimeouts(userId, shouldOverride,
+                    false /* overrideHardTimeout */);
+        } else {
+            handleScheduleTrustedTimeout(userId, shouldOverride);
+        }
+    }
+
+    /* Override both the idle and hard trustable timeouts */
+    private void refreshTrustableTimers(int userId) {
+        handleScheduleTrustableTimeouts(userId, true /* overrideIdleTimeout */,
+                true /* overrideHardTimeout */);
+    }
+
+    private void handleScheduleTrustedTimeout(int userId, boolean shouldOverride) {
         long when = SystemClock.elapsedRealtime() + TRUST_TIMEOUT_IN_MILLIS;
-        userId = mCurrentUser;
-        TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
+        TrustedTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
 
         // Cancel existing trust timeouts for this user if needed.
         if (alarm != null) {
-            if (shouldOverride == 0 && alarm.isQueued()) {
+            if (!shouldOverride && alarm.isQueued()) {
                 if (DEBUG) Slog.d(TAG, "Found existing trust timeout alarm. Skipping.");
                 return;
             }
             mAlarmManager.cancel(alarm);
         } else {
-            alarm = new TrustTimeoutAlarmListener(userId);
+            alarm = new TrustedTimeoutAlarmListener(userId);
             mTrustTimeoutAlarmListenerForUser.put(userId, alarm);
         }
 
@@ -379,6 +410,59 @@
                 mHandler);
     }
 
+    private void handleScheduleTrustableTimeouts(int userId, boolean overrideIdleTimeout,
+            boolean overrideHardTimeout) {
+        setUpIdleTimeout(userId, overrideIdleTimeout);
+        setUpHardTimeout(userId, overrideHardTimeout);
+    }
+
+    private void setUpIdleTimeout(int userId, boolean overrideIdleTimeout) {
+        long when = SystemClock.elapsedRealtime() + TRUSTABLE_IDLE_TIMEOUT_IN_MILLIS;
+        TrustableTimeoutAlarmListener alarm = mIdleTrustableTimeoutAlarmListenerForUser.get(userId);
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.SCHEDULE_EXACT_ALARM, null);
+
+        // Cancel existing trustable timeouts for this user if needed.
+        if (alarm != null) {
+            if (!overrideIdleTimeout && alarm.isQueued()) {
+                if (DEBUG) Slog.d(TAG, "Found existing trustable timeout alarm. Skipping.");
+                return;
+            }
+            mAlarmManager.cancel(alarm);
+        } else {
+            alarm = new TrustableTimeoutAlarmListener(userId);
+            mIdleTrustableTimeoutAlarmListenerForUser.put(userId, alarm);
+        }
+
+        if (DEBUG) Slog.d(TAG, "\tSetting up trustable idle timeout alarm");
+        alarm.setQueued(true /* isQueued */);
+        mAlarmManager.setExact(
+                AlarmManager.ELAPSED_REALTIME_WAKEUP, when, TRUST_TIMEOUT_ALARM_TAG, alarm,
+                mHandler);
+    }
+
+    private void setUpHardTimeout(int userId, boolean overrideHardTimeout) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.SCHEDULE_EXACT_ALARM, null);
+        TrustableTimeoutAlarmListener alarm = mTrustableTimeoutAlarmListenerForUser.get(userId);
+
+        // if the alarm doesn't exist, or hasn't been queued, or needs to be overridden we need to
+        // set it
+        if (alarm == null || !alarm.isQueued() || overrideHardTimeout) {
+            // schedule hard limit on renewable trust use
+            long when = SystemClock.elapsedRealtime() + TRUSTABLE_TIMEOUT_IN_MILLIS;
+            if (alarm == null) {
+                alarm = new TrustableTimeoutAlarmListener(userId);
+                mTrustableTimeoutAlarmListenerForUser.put(userId, alarm);
+            } else if (overrideHardTimeout) {
+                mAlarmManager.cancel(alarm);
+            }
+            if (DEBUG) Slog.d(TAG, "\tSetting up trustable hard timeout alarm");
+            alarm.setQueued(true /* isQueued */);
+            mAlarmManager.setExact(
+                    AlarmManager.ELAPSED_REALTIME_WAKEUP, when, TRUST_TIMEOUT_ALARM_TAG, alarm,
+                    mHandler);
+        }
+    }
+
    // Agent management
 
     private static final class AgentInfo {
@@ -419,11 +503,11 @@
         if (ENABLE_ACTIVE_UNLOCK_FLAG) {
             updateTrustWithRenewableUnlock(userId, flags, isFromUnlock);
         } else {
-            updateTrustWithExtendUnlock(userId, flags, isFromUnlock);
+            updateTrustWithNonrenewableTrust(userId, flags, isFromUnlock);
         }
     }
 
-    private void updateTrustWithExtendUnlock(int userId, int flags, boolean isFromUnlock) {
+    private void updateTrustWithNonrenewableTrust(int userId, int flags, boolean isFromUnlock) {
         boolean managed = aggregateIsTrustManaged(userId);
         dispatchOnTrustManagedChanged(managed, userId);
         if (mStrongAuthTracker.isTrustAllowedForUser(userId)
@@ -441,8 +525,8 @@
 
         boolean changed;
         synchronized (mUserIsTrusted) {
-            if (mSettingsObserver.getTrustAgentsExtendUnlock()) {
-                // In extend unlock trust agents can only set the device to trusted if it already
+            if (mSettingsObserver.getTrustAgentsNonrenewableTrust()) {
+                // For non-renewable trust agents can only set the device to trusted if it already
                 // trusted or the device is unlocked. Attempting to set the device as trusted
                 // when the device is locked will be ignored.
                 changed = mUserIsTrusted.get(userId) != trusted;
@@ -464,7 +548,7 @@
             if (!trusted) {
                 maybeLockScreen(userId);
             } else {
-                scheduleTrustTimeout(userId, false /* override */);
+                scheduleTrustTimeout(false /* override */, false /* isTrustableTimeout*/);
             }
         }
     }
@@ -522,7 +606,12 @@
             if (!isNowTrusted) {
                 maybeLockScreen(userId);
             } else {
-                scheduleTrustTimeout(userId, false /* override */);
+                boolean isTrustableTimeout =
+                        (flags & FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) != 0;
+                // Every time we grant renewable trust we should override the idle trustable
+                // timeout. If this is for non-renewable trust, then we shouldn't override.
+                scheduleTrustTimeout(isTrustableTimeout /* override */,
+                        isTrustableTimeout /* isTrustableTimeout */);
             }
         }
     }
@@ -1102,8 +1191,9 @@
     private void dispatchUnlockAttempt(boolean successful, int userId) {
         if (successful) {
             mStrongAuthTracker.allowTrustFromUnlock(userId);
-            // Allow the presence of trust on a successful unlock attempt to extend unlock.
+            // Allow the presence of trust on a successful unlock attempt to extend unlock
             updateTrust(userId, 0 /* flags */, true);
+            mHandler.obtainMessage(MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH, userId).sendToTarget();
         }
 
         for (int i = 0; i < mActiveAgents.size(); i++) {
@@ -1520,11 +1610,12 @@
             synchronized(mUsersUnlockedByBiometric) {
                 mUsersUnlockedByBiometric.put(userId, true);
             }
-            // In extend unlock mode we need to refresh trust state here, which will call
+            // In non-renewable trust mode we need to refresh trust state here, which will call
             // refreshDeviceLockedForUser()
-            int updateTrustOnUnlock = mSettingsObserver.getTrustAgentsExtendUnlock() ? 1 : 0;
+            int updateTrustOnUnlock = mSettingsObserver.getTrustAgentsNonrenewableTrust() ? 1 : 0;
             mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
                     updateTrustOnUnlock).sendToTarget();
+            mHandler.obtainMessage(MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH, userId).sendToTarget();
         }
 
         @Override
@@ -1643,7 +1734,13 @@
                     refreshDeviceLockedForUser(msg.arg1, unlockedUser);
                     break;
                 case MSG_SCHEDULE_TRUST_TIMEOUT:
-                    handleScheduleTrustTimeout(msg.arg1, msg.arg2);
+                    boolean shouldOverride = msg.arg1 == 1 ? true : false;
+                    TimeoutType timeoutType =
+                            msg.arg2 == 1 ? TimeoutType.TRUSTABLE : TimeoutType.TRUSTED;
+                    handleScheduleTrustTimeout(shouldOverride, timeoutType);
+                    break;
+                case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH:
+                    refreshTrustableTimers(msg.arg1);
                     break;
             }
         }
@@ -1759,10 +1856,11 @@
             // Cancel pending alarms if we require some auth anyway.
             if (!isTrustAllowedForUser(userId)) {
                 TrustTimeoutAlarmListener alarm = mTrustTimeoutAlarmListenerForUser.get(userId);
-                if (alarm != null && alarm.isQueued()) {
-                    alarm.setQueued(false /* isQueued */);
-                    mAlarmManager.cancel(alarm);
-                }
+                cancelPendingAlarm(alarm);
+                alarm = mTrustableTimeoutAlarmListenerForUser.get(userId);
+                cancelPendingAlarm(alarm);
+                alarm = mIdleTrustableTimeoutAlarmListenerForUser.get(userId);
+                cancelPendingAlarm(alarm);
             }
 
             refreshAgentList(userId);
@@ -1772,6 +1870,13 @@
             updateTrust(userId, 0 /* flags */);
         }
 
+        private void cancelPendingAlarm(@Nullable TrustTimeoutAlarmListener alarm) {
+            if (alarm != null && alarm.isQueued()) {
+                alarm.setQueued(false /* isQueued */);
+                mAlarmManager.cancel(alarm);
+            }
+        }
+
         boolean canAgentsRunForUser(int userId) {
             return mStartFromSuccessfulUnlock.get(userId)
                     || super.isTrustAllowedForUser(userId);
@@ -1804,9 +1909,9 @@
         }
     }
 
-    private class TrustTimeoutAlarmListener implements OnAlarmListener {
-        private final int mUserId;
-        private boolean mIsQueued = false;
+    private abstract class TrustTimeoutAlarmListener implements OnAlarmListener {
+        protected final int mUserId;
+        protected boolean mIsQueued = false;
 
         TrustTimeoutAlarmListener(int userId) {
             mUserId = userId;
@@ -1815,8 +1920,7 @@
         @Override
         public void onAlarm() {
             mIsQueued = false;
-            int strongAuthState = mStrongAuthTracker.getStrongAuthForUser(mUserId);
-
+            handleAlarm();
             // Only fire if trust can unlock.
             if (mStrongAuthTracker.isTrustAllowedForUser(mUserId)) {
                 if (DEBUG) Slog.d(TAG, "Revoking all trust because of trust timeout");
@@ -1826,12 +1930,98 @@
             maybeLockScreen(mUserId);
         }
 
-        public void setQueued(boolean isQueued) {
-            mIsQueued = isQueued;
-        }
+        protected abstract void handleAlarm();
 
         public boolean isQueued() {
             return mIsQueued;
         }
+
+        public void setQueued(boolean isQueued) {
+            mIsQueued = isQueued;
+        }
+    }
+
+    private class TrustedTimeoutAlarmListener extends TrustTimeoutAlarmListener {
+
+        TrustedTimeoutAlarmListener(int userId) {
+            super(userId);
+        }
+
+        @Override
+        public void handleAlarm() {
+            TrustableTimeoutAlarmListener otherAlarm;
+            boolean otherAlarmPresent;
+            if (ENABLE_ACTIVE_UNLOCK_FLAG) {
+                otherAlarm = mTrustableTimeoutAlarmListenerForUser.get(mUserId);
+                otherAlarmPresent = (otherAlarm != null) && otherAlarm.isQueued();
+                if (otherAlarmPresent) {
+                    synchronized (mAlarmLock) {
+                        disableNonrenewableTrustWhileRenewableTrustIsPresent();
+                    }
+                    return;
+                }
+            }
+        }
+
+        private void disableNonrenewableTrustWhileRenewableTrustIsPresent() {
+            synchronized (mUserTrustState) {
+                if (mUserTrustState.get(mUserId) == TrustState.TRUSTED) {
+                    // if we're trusted and we have a trustable alarm, we need to
+                    // downgrade to trustable
+                    mUserTrustState.put(mUserId, TrustState.TRUSTABLE);
+                    updateTrust(mUserId, 0 /* flags */);
+                }
+            }
+        }
+    }
+
+    private class TrustableTimeoutAlarmListener extends TrustTimeoutAlarmListener {
+
+        TrustableTimeoutAlarmListener(int userId) {
+            super(userId);
+        }
+
+        @Override
+        public void handleAlarm() {
+            TrustedTimeoutAlarmListener otherAlarm;
+            boolean otherAlarmPresent;
+            if (ENABLE_ACTIVE_UNLOCK_FLAG) {
+                cancelBothTrustableAlarms();
+                otherAlarm = mTrustTimeoutAlarmListenerForUser.get(mUserId);
+                otherAlarmPresent = (otherAlarm != null) && otherAlarm.isQueued();
+                if (otherAlarmPresent) {
+                    synchronized (mAlarmLock) {
+                        disableRenewableTrustWhileNonrenewableTrustIsPresent();
+                    }
+                    return;
+                }
+            }
+        }
+
+        private void cancelBothTrustableAlarms() {
+            TrustableTimeoutAlarmListener idleTimeout =
+                    mIdleTrustableTimeoutAlarmListenerForUser.get(
+                            mUserId);
+            TrustableTimeoutAlarmListener trustableTimeout =
+                    mTrustableTimeoutAlarmListenerForUser.get(
+                            mUserId);
+            if (idleTimeout != null && idleTimeout.isQueued()) {
+                idleTimeout.setQueued(false);
+                mAlarmManager.cancel(idleTimeout);
+            }
+            if (trustableTimeout != null && trustableTimeout.isQueued()) {
+                trustableTimeout.setQueued(false);
+                mAlarmManager.cancel(trustableTimeout);
+            }
+        }
+
+        private void disableRenewableTrustWhileNonrenewableTrustIsPresent() {
+            // if non-renewable trust is running, we need to temporarily prevent
+            // renewable trust from being used
+            for (AgentInfo agentInfo : mActiveAgents) {
+                agentInfo.agent.setUntrustable();
+            }
+            updateTrust(mUserId, 0 /* flags */);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java b/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
index b8885e8..080a36c 100644
--- a/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
+++ b/services/core/java/com/android/server/vibrator/StartSequentialEffectStep.java
@@ -55,13 +55,15 @@
 
     private long mVibratorsOnMaxDuration;
 
+    /** Start a sequential effect at the beginning. */
     StartSequentialEffectStep(VibrationStepConductor conductor,
             CombinedVibration.Sequential effect) {
         this(conductor, SystemClock.uptimeMillis() + effect.getDelays().get(0), effect,
                 /* index= */ 0);
     }
 
-    StartSequentialEffectStep(VibrationStepConductor conductor, long startTime,
+    /** Continue a SequentialEffect from the specified index. */
+    private StartSequentialEffectStep(VibrationStepConductor conductor, long startTime,
             CombinedVibration.Sequential effect, int index) {
         super(conductor, startTime);
         sequentialEffect = effect;
@@ -123,8 +125,7 @@
 
     /**
      * Create the next {@link StartSequentialEffectStep} to play this sequential effect, starting at
-     * the
-     * time this method is called, or null if sequence is complete.
+     * the time this method is called, or null if sequence is complete.
      */
     @Nullable
     Step nextStep() {
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index 0c15ee7..f02f9f9 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -49,6 +49,8 @@
         FORWARDED_TO_INPUT_DEVICES,
         CANCELLED,
         IGNORED_ERROR_APP_OPS,
+        IGNORED_ERROR_CANCELLING,
+        IGNORED_ERROR_SCHEDULING,
         IGNORED_ERROR_TOKEN,
         IGNORED,
         IGNORED_APP_OPS,
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 6c5d952..77da751 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -34,6 +34,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManagerInternal;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.media.AudioManager;
@@ -42,6 +43,7 @@
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.VibrationAttributes;
@@ -106,6 +108,19 @@
      */
     private static final int VIBRATE_ON_DISABLED_USAGE_ALLOWED = USAGE_ACCESSIBILITY;
 
+    /**
+     * Set of usages allowed for vibrations from system packages when the screen goes off.
+     *
+     * <p>Some examples are touch and hardware feedback, and physical emulation. When the system is
+     * playing one of these usages during the screen off event then the vibration will not be
+     * cancelled by the service.
+     */
+    private static final Set<Integer> SYSTEM_VIBRATION_SCREEN_OFF_USAGE_ALLOWLIST = new HashSet<>(
+            Arrays.asList(
+                    USAGE_TOUCH,
+                    USAGE_PHYSICAL_EMULATION,
+                    USAGE_HARDWARE_FEEDBACK));
+
     /** Listener for changes on vibration settings. */
     interface OnVibratorSettingsChanged {
         /** Callback triggered when any of the vibrator settings change. */
@@ -114,6 +129,7 @@
 
     private final Object mLock = new Object();
     private final Context mContext;
+    private final String mSystemUiPackage;
     private final SettingsObserver mSettingObserver;
     @VisibleForTesting
     final UidObserver mUidObserver;
@@ -151,6 +167,9 @@
         mUidObserver = new UidObserver();
         mUserReceiver = new UserObserver();
 
+        mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
+                .getSystemUiServiceComponent().getPackageName();
+
         VibrationEffect clickEffect = createEffectFromResource(
                 com.android.internal.R.array.config_virtualKeyVibePattern);
         VibrationEffect doubleClickEffect = createEffectFromResource(
@@ -336,35 +355,52 @@
                 }
             }
 
-            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;
     }
 
     /**
+     * Check if given vibration should be cancelled by the service when the screen goes off.
+     *
+     * <p>When the system is entering a non-interactive state, we want to cancel vibrations in case
+     * a misbehaving app has abandoned them. However, it may happen that the system is currently
+     * playing haptic feedback as part of the transition. So we don't cancel system vibrations of
+     * usages like touch and hardware feedback, and physical emulation.
+     *
+     * @return true if the vibration should be cancelled when the screen goes off, false otherwise.
+     */
+    public boolean shouldCancelVibrationOnScreenOff(int uid, String opPkg,
+            @VibrationAttributes.Usage int usage) {
+        if (!SYSTEM_VIBRATION_SCREEN_OFF_USAGE_ALLOWLIST.contains(usage)) {
+            // Usages not allowed even for system vibrations should always be cancelled.
+            return true;
+        }
+        // Only allow vibrations from System packages to continue vibrating when the screen goes off
+        return uid != Process.SYSTEM_UID && uid != 0 && !mSystemUiPackage.equals(opPkg);
+    }
+
+    /**
      * Return {@code true} if the device should vibrate for current ringer mode.
      *
      * <p>This checks the current {@link AudioManager#getRingerModeInternal()} against user settings
-     * for touch and ringtone usages 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) && (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.
         int ringerMode = (mAudioManager == null)
                 ? AudioManager.RINGER_MODE_SILENT
                 : mAudioManager.getRingerModeInternal();
-
-        switch (usageHint) {
-            case USAGE_TOUCH:
-            case USAGE_RINGTONE:
-                // Touch feedback and ringtone disabled when phone is on silent mode.
-                return ringerMode != AudioManager.RINGER_MODE_SILENT;
-            default:
-                // All other usages ignore ringer mode settings.
-                return true;
-        }
+        return ringerMode != AudioManager.RINGER_MODE_SILENT;
     }
 
     /** Updates all vibration settings and triggers registered listeners. */
diff --git a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
index 51691fb..e12426b 100644
--- a/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
+++ b/services/core/java/com/android/server/vibrator/VibrationStepConductor.java
@@ -18,13 +18,15 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.os.Build;
 import android.os.CombinedVibration;
+import android.os.IBinder;
 import android.os.VibrationEffect;
-import android.os.WorkSource;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.PrimitiveSegment;
 import android.os.vibrator.RampSegment;
 import android.os.vibrator.VibrationEffectSegment;
+import android.util.IntArray;
 import android.util.Slog;
 import android.util.SparseArray;
 
@@ -40,8 +42,15 @@
 /**
  * Creates and manages a queue of steps for performing a VibrationEffect, as well as coordinating
  * dispatch of callbacks.
+ *
+ * <p>In general, methods in this class are intended to be called only by a single instance of
+ * VibrationThread. The only thread-safe methods for calling from other threads are the "notify"
+ * methods (which should never be used from the VibrationThread thread).
  */
-final class VibrationStepConductor {
+final class VibrationStepConductor implements IBinder.DeathRecipient {
+    private static final boolean DEBUG = VibrationThread.DEBUG;
+    private static final String TAG = VibrationThread.TAG;
+
     /**
      * Extra timeout added to the end of each vibration step to ensure it finishes even when
      * vibrator callbacks are lost.
@@ -51,32 +60,35 @@
     static final float RAMP_OFF_AMPLITUDE_MIN = 1e-3f;
     static final List<Step> EMPTY_STEP_LIST = new ArrayList<>();
 
-    final Object mLock = new Object();
-
     // Used within steps.
     public final VibrationSettings vibrationSettings;
     public final DeviceVibrationEffectAdapter deviceEffectAdapter;
     public final VibrationThread.VibratorManagerHooks vibratorManagerHooks;
 
-    private final WorkSource mWorkSource;
     private final Vibration mVibration;
     private final SparseArray<VibratorController> mVibrators = new SparseArray<>();
 
-    @GuardedBy("mLock")
     private final PriorityQueue<Step> mNextSteps = new PriorityQueue<>();
-    @GuardedBy("mLock")
     private final Queue<Step> mPendingOnVibratorCompleteSteps = new LinkedList<>();
-    @GuardedBy("mLock")
-    private final Queue<Integer> mCompletionNotifiedVibrators = 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")
+    private boolean mSignalCancel = false;
+    @GuardedBy("mLock")
+    private boolean mSignalCancelImmediate = false;
+
+    private boolean mCancelled = false;
+    private boolean mCancelledImmediately = false;  // hard stop
     private int mPendingVibrateSteps;
-    @GuardedBy("mLock")
-    private int mConsumedStartVibrateSteps;
-    @GuardedBy("mLock")
+    private int mRemainingStartSequentialEffectSteps;
     private int mSuccessfulVibratorOnSteps;
-    @GuardedBy("mLock")
-    private boolean mWaitToProcessVibratorCompleteCallbacks;
 
     VibrationStepConductor(Vibration vib, VibrationSettings vibrationSettings,
             DeviceVibrationEffectAdapter effectAdapter,
@@ -86,7 +98,6 @@
         this.vibrationSettings = vibrationSettings;
         this.deviceEffectAdapter = effectAdapter;
         this.vibratorManagerHooks = vibratorManagerHooks;
-        this.mWorkSource = new WorkSource(mVibration.uid);
 
         CombinedVibration effect = vib.getEffect();
         for (int i = 0; i < availableVibrators.size(); i++) {
@@ -94,12 +105,16 @@
                 mVibrators.put(availableVibrators.keyAt(i), availableVibrators.valueAt(i));
             }
         }
+        this.mSignalVibratorsComplete = new IntArray(mVibrators.size());
     }
 
     @Nullable
     AbstractVibratorStep nextVibrateStep(long startTime, VibratorController controller,
             VibrationEffect.Composed effect, int segmentIndex,
             long previousStepVibratorOffTimeout) {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
+        }
         if (segmentIndex >= effect.getSegments().size()) {
             segmentIndex = effect.getRepeatIndex();
         }
@@ -126,58 +141,126 @@
                 previousStepVibratorOffTimeout);
     }
 
-    public void initializeForEffect(@NonNull CombinedVibration.Sequential vibration) {
-        synchronized (mLock) {
-            mPendingVibrateSteps++;
-            mNextSteps.offer(new StartSequentialEffectStep(this, vibration));
+    /** Called when this conductor is going to be started running by the VibrationThread. */
+    public void prepareToStart() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
         }
+        CombinedVibration.Sequential sequentialEffect = toSequential(mVibration.getEffect());
+        mPendingVibrateSteps++;
+        // This count is decremented at the completion of the step, so we don't subtract one.
+        mRemainingStartSequentialEffectSteps = sequentialEffect.getEffects().size();
+        mNextSteps.offer(new StartSequentialEffectStep(this, sequentialEffect));
     }
 
     public Vibration getVibration() {
+        // No thread assertion: immutable
         return mVibration;
     }
 
-    public WorkSource getWorkSource() {
-        return mWorkSource;
-    }
-
     SparseArray<VibratorController> getVibrators() {
+        // No thread assertion: immutable
         return mVibrators;
     }
 
     public boolean isFinished() {
-        synchronized (mLock) {
-            return mPendingOnVibratorCompleteSteps.isEmpty() && mNextSteps.isEmpty();
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
         }
+        if (mCancelledImmediately) {
+            return true;  // Terminate.
+        }
+
+        // No need to check for vibration complete callbacks - if there were any, they would
+        // have no steps to notify anyway.
+        return mPendingOnVibratorCompleteSteps.isEmpty() && mNextSteps.isEmpty();
     }
 
     /**
      * Calculate the {@link Vibration.Status} based on the current queue state and the expected
      * number of {@link StartSequentialEffectStep} to be played.
      */
-    public Vibration.Status calculateVibrationStatus(int expectedStartVibrateSteps) {
+    public Vibration.Status calculateVibrationStatus() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
+        }
+
+        if (mCancelled) {
+            return Vibration.Status.CANCELLED;
+        }
+        if (mPendingVibrateSteps > 0
+                || mRemainingStartSequentialEffectSteps > 0) {
+            return Vibration.Status.RUNNING;
+        }
+        // No pending steps, and something happened.
+        if (mSuccessfulVibratorOnSteps > 0) {
+            return Vibration.Status.FINISHED;
+        }
+        // If no step was able to turn the vibrator ON successfully.
+        return Vibration.Status.IGNORED_UNSUPPORTED;
+    }
+
+    /**
+     * Blocks until the next step is due to run. The wait here may be interrupted by calling
+     * one of the "notify" methods.
+     *
+     * <p>This method returns true if the next step is ready to run now. If the method returns
+     * false, then some waiting was done, but may have been interrupted by a wakeUp, and the
+     * status and isFinished of the vibration should be re-checked before calling this method again.
+     *
+     * @return true if the next step can be run now or the vibration is finished, or false if this
+     *   method waited and the conductor state may have changed asynchronously, in which case this
+     *   method needs to be run again.
+     */
+    public boolean waitUntilNextStepIsDue() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
+        }
+
+        processAllNotifySignals();
+        if (mCancelledImmediately) {
+            // Don't try to run a step for immediate cancel, although there should be none left.
+            // Non-immediate cancellation may have cleanup steps, so it continues processing.
+            return false;
+        }
+        if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
+            return true;  // Resumed step ready.
+        }
+        Step nextStep = mNextSteps.peek();
+        if (nextStep == null) {
+            return true;  // Finished
+        }
+        long waitMillis = nextStep.calculateWaitTime();
+        if (waitMillis <= 0) {
+            return true;  // Regular step ready
+        }
         synchronized (mLock) {
-            if (mPendingVibrateSteps > 0
-                    || mConsumedStartVibrateSteps < expectedStartVibrateSteps) {
-                return Vibration.Status.RUNNING;
+            // Double check for signals before sleeping, as their notify wouldn't interrupt a fresh
+            // wait.
+            if (hasPendingNotifySignalLocked()) {
+                // Don't run the next step, it will loop back to this method and process them.
+                return false;
             }
-            if (mSuccessfulVibratorOnSteps > 0) {
-                return Vibration.Status.FINISHED;
+            try {
+                mLock.wait(waitMillis);
+            } catch (InterruptedException e) {
             }
-            // If no step was able to turn the vibrator ON successfully.
-            return Vibration.Status.IGNORED_UNSUPPORTED;
+            return false;  // Caller needs to check isFinished and maybe wait again.
         }
     }
 
-    /** Returns the time in millis to wait before calling {@link #runNextStep()}. */
-    @GuardedBy("mLock")
-    public long getWaitMillisBeforeNextStepLocked() {
-        if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
-            // Steps resumed by vibrator complete callback should be played right away.
-            return 0;
+    @Nullable
+    private Step pollNext() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
         }
-        Step nextStep = mNextSteps.peek();
-        return nextStep == null ? 0 : nextStep.calculateWaitTime();
+
+        // Prioritize the steps resumed by a vibrator complete callback, irrespective of their
+        // "next run time".
+        if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
+            return mPendingOnVibratorCompleteSteps.poll();
+        }
+        return mNextSteps.poll();
     }
 
     /**
@@ -185,103 +268,192 @@
      * to be played next.
      */
     public void runNextStep() {
-        // Vibrator callbacks should wait until the polled step is played and the next steps are
-        // added back to the queue, so they can handle the callback.
-        markWaitToProcessVibratorCallbacks();
-        try {
-            Step nextStep = pollNext();
-            if (nextStep != null) {
-                // This might turn on the vibrator and have a HAL latency. Execute this outside
-                // any lock to avoid blocking other interactions with the thread.
-                List<Step> nextSteps = nextStep.play();
-                synchronized (mLock) {
-                    if (nextStep.getVibratorOnDuration() > 0) {
-                        mSuccessfulVibratorOnSteps++;
-                    }
-                    if (nextStep instanceof StartSequentialEffectStep) {
-                        mConsumedStartVibrateSteps++;
-                    }
-                    if (!nextStep.isCleanUp()) {
-                        mPendingVibrateSteps--;
-                    }
-                    for (int i = 0; i < nextSteps.size(); i++) {
-                        mPendingVibrateSteps += nextSteps.get(i).isCleanUp() ? 0 : 1;
-                    }
-                    mNextSteps.addAll(nextSteps);
-                }
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
+        }
+        // In theory a completion callback could have come in between the wait finishing and
+        // this method starting, but that only means the step is due now anyway, so it's reasonable
+        // to run it before processing callbacks as the window is tiny.
+        Step nextStep = pollNext();
+        if (nextStep != null) {
+            List<Step> nextSteps = nextStep.play();
+            if (nextStep.getVibratorOnDuration() > 0) {
+                mSuccessfulVibratorOnSteps++;
             }
-        } finally {
-            synchronized (mLock) {
-                processVibratorCompleteCallbacksLocked();
+            if (nextStep instanceof StartSequentialEffectStep) {
+                mRemainingStartSequentialEffectSteps--;
             }
+            if (!nextStep.isCleanUp()) {
+                mPendingVibrateSteps--;
+            }
+            for (int i = 0; i < nextSteps.size(); i++) {
+                mPendingVibrateSteps += nextSteps.get(i).isCleanUp() ? 0 : 1;
+            }
+            mNextSteps.addAll(nextSteps);
         }
     }
 
     /**
-     * Notify the vibrator completion.
-     *
-     * <p>This is a lightweight method that do not trigger any operation from {@link
-     * VibratorController}, so it can be called directly from a native callback.
+     * Binder death notification. VibrationThread registers this when it's running a conductor.
+     * Note that cancellation could theoretically happen immediately, before the conductor has
+     * started, but in this case it will be processed in the first signals loop.
      */
-    @GuardedBy("mLock")
-    private void notifyVibratorCompleteLocked(int vibratorId) {
-        mCompletionNotifiedVibrators.offer(vibratorId);
-        if (!mWaitToProcessVibratorCompleteCallbacks) {
-            // No step is being played or cancelled now, process the callback right away.
-            processVibratorCompleteCallbacksLocked();
+    @Override
+    public void binderDied() {
+        if (DEBUG) {
+            Slog.d(TAG, "Binder died, cancelling vibration...");
+        }
+        notifyCancelled(/* immediate= */ false);
+    }
+
+    /**
+     * Notify the execution that cancellation is requested. This will be acted upon
+     * asynchronously in the VibrationThread.
+     *
+     * @param immediate indicates whether cancellation should abort urgently and skip cleanup steps.
+     */
+    public void notifyCancelled(boolean immediate) {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(false);
+        }
+        synchronized (mLock) {
+            if (immediate && mSignalCancelImmediate || mSignalCancel) {
+                // Nothing to update: already cancelled previously.
+                return;
+            }
+            mSignalCancelImmediate |= immediate;
+            mSignalCancel = true;
+            mLock.notify();
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "Vibration cancel requested, immediate=" + immediate);
         }
     }
 
+    /**
+     * Notify the conductor that a vibrator has completed its work.
+     *
+     * <p>This is a lightweight method intended to be called directly via native callbacks.
+     * The state update is recorded for processing on the main execution thread (VibrationThread).
+     */
     public void notifyVibratorComplete(int vibratorId) {
+        // 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);
+        }
+
         synchronized (mLock) {
-            if (VibrationThread.DEBUG) {
-                Slog.d(VibrationThread.TAG,
-                        "Vibration complete reported by vibrator " + vibratorId);
-            }
-            notifyVibratorCompleteLocked(vibratorId);
+            mSignalVibratorsComplete.add(vibratorId);
             mLock.notify();
         }
     }
 
+    /**
+     * Notify that a VibratorManager sync operation has completed.
+     *
+     * <p>This is a lightweight method intended to be called directly via native callbacks.
+     * The state update is recorded for processing on the main execution thread
+     * (VibrationThread).
+     */
     public void notifySyncedVibrationComplete() {
+        // 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");
+        }
+
         synchronized (mLock) {
-            if (VibrationThread.DEBUG) {
-                Slog.d(VibrationThread.TAG,
-                        "Synced vibration complete reported by vibrator manager");
-            }
             for (int i = 0; i < mVibrators.size(); i++) {
-                notifyVibratorCompleteLocked(mVibrators.keyAt(i));
+                mSignalVibratorsComplete.add(mVibrators.keyAt(i));
             }
             mLock.notify();
         }
     }
 
+    @GuardedBy("mLock")
+    private boolean hasPendingNotifySignalLocked() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);  // Reads VibrationThread variables as well as signals.
+        }
+        return (mSignalCancel && !mCancelled)
+            || (mSignalCancelImmediate && !mCancelledImmediately)
+            || (mSignalVibratorsComplete.size() > 0);
+    }
+
+    /**
+     * Process any notified cross-thread signals, applying the necessary VibrationThread state
+     * changes.
+     */
+    private void processAllNotifySignals() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
+        }
+
+        int[] vibratorsToProcess = null;
+        boolean doCancel = false;
+        boolean doCancelImmediate = false;
+        // Collect signals to process, but don't keep the lock while processing them.
+        synchronized (mLock) {
+            if (mSignalCancelImmediate) {
+                if (mCancelledImmediately) {
+                    Slog.wtf(TAG, "Immediate cancellation signal processed twice");
+                }
+                // This should only happen once.
+                doCancelImmediate = true;
+            }
+            if (mSignalCancel && !mCancelled) {
+                doCancel = true;
+            }
+            if (!doCancelImmediate && mSignalVibratorsComplete.size() > 0) {
+                // Swap out the queue of completions to process.
+                vibratorsToProcess = mSignalVibratorsComplete.toArray();  // makes a copy
+                mSignalVibratorsComplete.clear();
+            }
+        }
+
+        // Force cancellation means stop everything and clear all steps, so the execution loop
+        // shouldn't come back to this method. To observe explicitly: this drops vibrator
+        // completion signals that were collected in this call, but we won't process them
+        // anyway as all steps are cancelled.
+        if (doCancelImmediate) {
+            processCancelImmediately();
+            return;
+        }
+        if (doCancel) {
+            processCancel();
+        }
+        if (vibratorsToProcess != null) {
+            processVibratorsComplete(vibratorsToProcess);
+        }
+    }
+
     /**
      * Cancel the current queue, replacing all remaining steps with respective clean-up steps.
      *
-     * <p>This will remove all steps and replace them with respective
+     * <p>This will remove all steps and replace them with respective results of
      * {@link Step#cancel()}.
      */
-    public void cancel() {
+    public void processCancel() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
+        }
+
+        mCancelled = true;
         // Vibrator callbacks should wait until all steps from the queue are properly cancelled
         // and clean up steps are added back to the queue, so they can handle the callback.
-        markWaitToProcessVibratorCallbacks();
-        try {
-            List<Step> cleanUpSteps = new ArrayList<>();
-            Step step;
-            while ((step = pollNext()) != null) {
-                cleanUpSteps.addAll(step.cancel());
-            }
-            synchronized (mLock) {
-                // All steps generated by Step.cancel() should be clean-up steps.
-                mPendingVibrateSteps = 0;
-                mNextSteps.addAll(cleanUpSteps);
-            }
-        } finally {
-            synchronized (mLock) {
-                processVibratorCompleteCallbacksLocked();
-            }
+        List<Step> cleanUpSteps = new ArrayList<>();
+        Step step;
+        while ((step = pollNext()) != null) {
+            cleanUpSteps.addAll(step.cancel());
         }
+        // All steps generated by Step.cancel() should be clean-up steps.
+        mPendingVibrateSteps = 0;
+        mNextSteps.addAll(cleanUpSteps);
     }
 
     /**
@@ -289,58 +461,34 @@
      *
      * <p>This will remove and trigger {@link Step#cancelImmediately()} in all steps, in order.
      */
-    public void cancelImmediately() {
-        // Vibrator callbacks should wait until all steps from the queue are properly cancelled.
-        markWaitToProcessVibratorCallbacks();
-        try {
-            Step step;
-            while ((step = pollNext()) != null) {
-                // This might turn off the vibrator and have a HAL latency. Execute this outside
-                // any lock to avoid blocking other interactions with the thread.
-                step.cancelImmediately();
-            }
-            synchronized (mLock) {
-                mPendingVibrateSteps = 0;
-            }
-        } finally {
-            synchronized (mLock) {
-                processVibratorCompleteCallbacksLocked();
-            }
+    public void processCancelImmediately() {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
         }
-    }
 
-    @Nullable
-    private Step pollNext() {
-        synchronized (mLock) {
-            // Prioritize the steps resumed by a vibrator complete callback.
-            if (!mPendingOnVibratorCompleteSteps.isEmpty()) {
-                return mPendingOnVibratorCompleteSteps.poll();
-            }
-            return mNextSteps.poll();
+        mCancelledImmediately = true;
+        mCancelled = true;
+        Step step;
+        while ((step = pollNext()) != null) {
+            step.cancelImmediately();
         }
-    }
-
-    private void markWaitToProcessVibratorCallbacks() {
-        synchronized (mLock) {
-            mWaitToProcessVibratorCompleteCallbacks = true;
-        }
+        mPendingVibrateSteps = 0;
     }
 
     /**
-     * Notify the step in this queue that should be resumed by the vibrator completion
-     * callback and keep it separate to be consumed by {@link #runNextStep()}.
-     *
-     * <p>This is a lightweight method that do not trigger any operation from {@link
-     * VibratorController}, so it can be called directly from a native callback.
+     * Processes the vibrators that have sent their complete callbacks. A step is found that will
+     * accept the completion callback, and this step is brought forward for execution in the next
+     * run.
      *
      * <p>This assumes only one of the next steps is waiting on this given vibrator, so the
      * first step found will be resumed by this method, in no particular order.
      */
-    @GuardedBy("mLock")
-    private void processVibratorCompleteCallbacksLocked() {
-        mWaitToProcessVibratorCompleteCallbacks = false;
-        while (!mCompletionNotifiedVibrators.isEmpty()) {
-            int vibratorId = mCompletionNotifiedVibrators.poll();
+    private void processVibratorsComplete(@NonNull int[] vibratorsToProcess) {
+        if (Build.IS_DEBUGGABLE) {
+            expectIsVibrationThread(true);
+        }
+
+        for (int vibratorId : vibratorsToProcess) {
             Iterator<Step> it = mNextSteps.iterator();
             while (it.hasNext()) {
                 Step step = it.next();
@@ -352,4 +500,27 @@
             }
         }
     }
+
+    private static CombinedVibration.Sequential toSequential(CombinedVibration effect) {
+        if (effect instanceof CombinedVibration.Sequential) {
+            return (CombinedVibration.Sequential) effect;
+        }
+        return (CombinedVibration.Sequential) CombinedVibration.startSequential()
+                .addNext(effect)
+                .combine();
+    }
+
+    /**
+     * This check is used for debugging and documentation to indicate the thread that's expected
+     * to invoke a given public method on this class. Most methods are only invoked by
+     * VibrationThread, which is where all the steps and HAL calls should be made. Other threads
+     * should only signal to the execution flow being run by VibrationThread.
+     */
+    private static void expectIsVibrationThread(boolean isVibrationThread) {
+        if ((Thread.currentThread() instanceof VibrationThread) != isVibrationThread) {
+            Slog.wtfStack("VibrationStepConductor",
+                    "Thread caller assertion failed, expected isVibrationThread="
+                            + isVibrationThread);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/vibrator/VibrationThread.java b/services/core/java/com/android/server/vibrator/VibrationThread.java
index f2cd8c3..cecc5c0 100644
--- a/services/core/java/com/android/server/vibrator/VibrationThread.java
+++ b/services/core/java/com/android/server/vibrator/VibrationThread.java
@@ -16,21 +16,25 @@
 
 package com.android.server.vibrator;
 
-import android.os.CombinedVibration;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.IBinder;
 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;
-import android.util.SparseArray;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.NoSuchElementException;
+import java.util.Objects;
 
 /** Plays a {@link Vibration} in dedicated thread. */
-final class VibrationThread extends Thread implements IBinder.DeathRecipient {
+final class VibrationThread extends Thread {
     static final String TAG = "VibrationThread";
     static final boolean DEBUG = false;
 
@@ -78,70 +82,166 @@
          * Tells the manager that the VibrationThread is finished with the previous vibration and
          * all of its cleanup tasks, and the vibrators can now be used for another vibration.
          */
-        void onVibrationThreadReleased();
+        void onVibrationThreadReleased(long vibrationId);
     }
 
     private final PowerManager.WakeLock mWakeLock;
     private final VibrationThread.VibratorManagerHooks mVibratorManagerHooks;
 
-    private final VibrationStepConductor mStepConductor;
+    // mLock is used here to communicate that the thread's work status has changed. The
+    // VibrationThread is expected to wait until work arrives, and other threads may wait until
+    // work has finished. Therefore, any changes to the conductor must be followed by a notifyAll
+    // so that threads check if their desired state is achieved.
+    private final Object mLock = new Object();
 
-    private volatile boolean mStop;
-    private volatile boolean mForceStop;
-    // Variable only set and read in main thread.
+    /**
+     * The conductor that is intended to be active. Null value means that a new conductor can
+     * be set to run. Note that this field is only reset to null when mExecutingConductor has
+     * completed, so the two fields should be in sync.
+     */
+    @GuardedBy("mLock")
+    @Nullable
+    private VibrationStepConductor mRequestedActiveConductor;
+
+    /**
+     * The conductor being executed by this thread, should only be accessed within this thread's
+     * execution. i.e. not thread-safe. {@link #mRequestedActiveConductor} is for cross-thread
+     * signalling.
+     */
+    @Nullable
+    private VibrationStepConductor mExecutingConductor;
+
+    // Variable only set and read in main thread, no need to lock.
     private boolean mCalledVibrationCompleteCallback = false;
 
-    VibrationThread(Vibration vib, VibrationSettings vibrationSettings,
-            DeviceVibrationEffectAdapter effectAdapter,
-            SparseArray<VibratorController> availableVibrators, PowerManager.WakeLock wakeLock,
-            VibratorManagerHooks vibratorManagerHooks) {
-        mVibratorManagerHooks = vibratorManagerHooks;
+    VibrationThread(PowerManager.WakeLock wakeLock, VibratorManagerHooks vibratorManagerHooks) {
         mWakeLock = wakeLock;
-        mStepConductor = new VibrationStepConductor(vib, vibrationSettings, effectAdapter,
-                availableVibrators, vibratorManagerHooks);
+        mVibratorManagerHooks = vibratorManagerHooks;
     }
 
-    Vibration getVibration() {
-        return mStepConductor.getVibration();
-    }
-
-    @VisibleForTesting
-    SparseArray<VibratorController> getVibrators() {
-        return mStepConductor.getVibrators();
-    }
-
-    @Override
-    public void binderDied() {
-        if (DEBUG) {
-            Slog.d(TAG, "Binder died, cancelling vibration...");
+    /**
+     * Sets/activates the current vibration. Must only be called after receiving
+     * onVibratorsReleased from the previous vibration.
+     *
+     * @return false if VibrationThread couldn't accept it, which shouldn't happen unless called
+     *  before the release callback.
+     */
+    boolean runVibrationOnVibrationThread(VibrationStepConductor conductor) {
+        synchronized (mLock) {
+            if (mRequestedActiveConductor != null) {
+                Slog.wtf(TAG, "Attempt to start vibration when one already running");
+                return false;
+            }
+            mRequestedActiveConductor = conductor;
+            mLock.notifyAll();
         }
-        cancel();
+        return true;
     }
 
     @Override
     public void run() {
-        // Structured to guarantee the vibrators completed and released callbacks at the end of
-        // thread execution. Both of these callbacks are exclusively called from this thread.
-        try {
-            try {
-                Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
-                runWithWakeLock();
-            } finally {
-                clientVibrationCompleteIfNotAlready(Vibration.Status.FINISHED_UNEXPECTED);
+        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
+        while (true) {
+            // mExecutingConductor is only modified in this loop.
+            mExecutingConductor = Objects.requireNonNull(waitForVibrationRequest());
+
+            mCalledVibrationCompleteCallback = false;
+            runCurrentVibrationWithWakeLock();
+            if (!mExecutingConductor.isFinished()) {
+                Slog.wtf(TAG, "VibrationThread terminated with unfinished vibration");
             }
-        } finally {
-            mVibratorManagerHooks.onVibrationThreadReleased();
+            synchronized (mLock) {
+                // Allow another vibration to be requested.
+                mRequestedActiveConductor = null;
+            }
+            // The callback is run without holding the lock, as it may initiate another vibration.
+            // It's safe to notify even if mVibratorConductor has been re-written, as the "wait"
+            // methods all verify their waited state before returning. In reality though, if the
+            // manager is waiting for the thread to finish, then there is no pending vibration
+            // for this thread.
+            // No point doing this in finally, as if there's an exception, this thread will die
+            // and be unusable anyway.
+            mVibratorManagerHooks.onVibrationThreadReleased(mExecutingConductor.getVibration().id);
+            synchronized (mLock) {
+                mLock.notifyAll();
+            }
+            mExecutingConductor = null;
+        }
+    }
+
+    /**
+     * Waits until the VibrationThread has finished processing, timing out after the given
+     * number of milliseconds. In general, external locking will manage the ordering of this
+     * with calls to {@link #runVibrationOnVibrationThread}.
+     *
+     * @return true if the vibration completed, or false if waiting timed out.
+     */
+    public boolean waitForThreadIdle(long maxWaitMillis) {
+        long now = SystemClock.elapsedRealtime();
+        long deadline = now + maxWaitMillis;
+        synchronized (mLock) {
+            while (true) {
+                if (mRequestedActiveConductor == null) {
+                    return true;  // Done
+                }
+                if (now >= deadline) {  // Note that thread.wait(0) waits indefinitely.
+                    return false;  // Timed out.
+                }
+                try {
+                    mLock.wait(deadline - now);
+                } catch (InterruptedException e) {
+                    Slog.w(TAG, "VibrationThread interrupted waiting to stop, continuing");
+                }
+                now = SystemClock.elapsedRealtime();
+            }
+        }
+    }
+
+    /** Waits for a signal indicating a vibration is ready to run, then returns its conductor. */
+    @NonNull
+    private VibrationStepConductor waitForVibrationRequest() {
+        while (true) {
+            synchronized (mLock) {
+                if (mRequestedActiveConductor != null) {
+                    return mRequestedActiveConductor;
+                }
+                try {
+                    mLock.wait();
+                } catch (InterruptedException e) {
+                    Slog.w(TAG, "VibrationThread interrupted waiting to start, continuing");
+                }
+            }
+        }
+    }
+
+    /**
+     * Only for testing: this method relies on the requested-active conductor, rather than
+     * the executing conductor that's not intended for other threads.
+     *
+     * @return true if the vibration that's currently desired to be active has the given id.
+     */
+    @VisibleForTesting
+    boolean isRunningVibrationId(long id) {
+        synchronized (mLock) {
+            return (mRequestedActiveConductor != null
+                    && mRequestedActiveConductor.getVibration().id == id);
         }
     }
 
     /** Runs the VibrationThread ensuring that the wake lock is acquired and released. */
-    private void runWithWakeLock() {
-        mWakeLock.setWorkSource(mStepConductor.getWorkSource());
+    private void runCurrentVibrationWithWakeLock() {
+        WorkSource workSource = new WorkSource(mExecutingConductor.getVibration().uid);
+        mWakeLock.setWorkSource(workSource);
         mWakeLock.acquire();
         try {
-            runWithWakeLockAndDeathLink();
+            try {
+                runCurrentVibrationWithWakeLockAndDeathLink();
+            } finally {
+                clientVibrationCompleteIfNotAlready(Vibration.Status.FINISHED_UNEXPECTED);
+            }
         } finally {
             mWakeLock.release();
+            mWakeLock.setWorkSource(null);
         }
     }
 
@@ -149,10 +249,10 @@
      * Runs the VibrationThread with the binder death link, handling link/unlink failures.
      * Called from within runWithWakeLock.
      */
-    private void runWithWakeLockAndDeathLink() {
-        IBinder vibrationBinderToken = mStepConductor.getVibration().token;
+    private void runCurrentVibrationWithWakeLockAndDeathLink() {
+        IBinder vibrationBinderToken = mExecutingConductor.getVibration().token;
         try {
-            vibrationBinderToken.linkToDeath(this, 0);
+            vibrationBinderToken.linkToDeath(mExecutingConductor, 0);
         } catch (RemoteException e) {
             Slog.e(TAG, "Error linking vibration to token death", e);
             clientVibrationCompleteIfNotAlready(Vibration.Status.IGNORED_ERROR_TOKEN);
@@ -164,53 +264,13 @@
             playVibration();
         } finally {
             try {
-                vibrationBinderToken.unlinkToDeath(this, 0);
+                vibrationBinderToken.unlinkToDeath(mExecutingConductor, 0);
             } catch (NoSuchElementException e) {
                 Slog.wtf(TAG, "Failed to unlink token", e);
             }
         }
     }
 
-    /** Cancel current vibration and ramp down the vibrators gracefully. */
-    public void cancel() {
-        if (mStop) {
-            // Already cancelled, running clean-up steps.
-            return;
-        }
-        mStop = true;
-        synchronized (mStepConductor.mLock) {
-            if (DEBUG) {
-                Slog.d(TAG, "Vibration cancelled");
-            }
-            mStepConductor.mLock.notify();
-        }
-    }
-
-    /** Cancel current vibration and shuts off the vibrators immediately. */
-    public void cancelImmediately() {
-        if (mForceStop) {
-            // Already forced the thread to stop, wait for it to finish.
-            return;
-        }
-        mStop = mForceStop = true;
-        synchronized (mStepConductor.mLock) {
-            if (DEBUG) {
-                Slog.d(TAG, "Vibration cancelled immediately");
-            }
-            mStepConductor.mLock.notify();
-        }
-    }
-
-    /** Notify current vibration that a synced step has completed. */
-    public void syncedVibrationComplete() {
-        mStepConductor.notifySyncedVibrationComplete();
-    }
-
-    /** Notify current vibration that a step has completed on given vibrator. */
-    public void vibratorComplete(int vibratorId) {
-        mStepConductor.notifyVibratorComplete(vibratorId);
-    }
-
     // Indicate that the vibration is complete. This can be called multiple times only for
     // convenience of handling error conditions - an error after the client is complete won't
     // affect the status.
@@ -218,70 +278,36 @@
         if (!mCalledVibrationCompleteCallback) {
             mCalledVibrationCompleteCallback = true;
             mVibratorManagerHooks.onVibrationCompleted(
-                    mStepConductor.getVibration().id, completedStatus);
+                    mExecutingConductor.getVibration().id, completedStatus);
         }
     }
 
     private void playVibration() {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "playVibration");
         try {
-            CombinedVibration.Sequential sequentialEffect =
-                    toSequential(mStepConductor.getVibration().getEffect());
-            final int sequentialEffectSize = sequentialEffect.getEffects().size();
-            mStepConductor.initializeForEffect(sequentialEffect);
-
-            while (!mStepConductor.isFinished()) {
-                long waitMillisBeforeNextStep;
-                synchronized (mStepConductor.mLock) {
-                    waitMillisBeforeNextStep = mStepConductor.getWaitMillisBeforeNextStepLocked();
-                    if (waitMillisBeforeNextStep > 0) {
-                        try {
-                            mStepConductor.mLock.wait(waitMillisBeforeNextStep);
-                        } catch (InterruptedException e) {
-                        }
-                    }
-                }
-                // Only run the next vibration step if we didn't have to wait in this loop.
-                // If we waited then the queue may have changed or the wait could have been
-                // interrupted by a cancel call, so loop again to re-evaluate the scheduling of
-                // the queue top element.
-                if (waitMillisBeforeNextStep <= 0) {
+            mExecutingConductor.prepareToStart();
+            while (!mExecutingConductor.isFinished()) {
+                boolean readyToRun = mExecutingConductor.waitUntilNextStepIsDue();
+                // If we waited, don't run the next step, but instead re-evaluate status.
+                if (readyToRun) {
                     if (DEBUG) {
                         Slog.d(TAG, "Play vibration consuming next step...");
                     }
                     // Run the step without holding the main lock, to avoid HAL interactions from
                     // blocking the thread.
-                    mStepConductor.runNextStep();
+                    mExecutingConductor.runNextStep();
                 }
-                Vibration.Status status = mStop ? Vibration.Status.CANCELLED
-                        : mStepConductor.calculateVibrationStatus(sequentialEffectSize);
+
+                Vibration.Status status = mExecutingConductor.calculateVibrationStatus();
+                // This block can only run once due to mCalledVibrationCompleteCallback.
                 if (status != Vibration.Status.RUNNING && !mCalledVibrationCompleteCallback) {
                     // First time vibration stopped running, start clean-up tasks and notify
                     // callback immediately.
                     clientVibrationCompleteIfNotAlready(status);
-                    if (status == Vibration.Status.CANCELLED) {
-                        mStepConductor.cancel();
-                    }
-                }
-                if (mForceStop) {
-                    // Cancel every step and stop playing them right away, even clean-up steps.
-                    mStepConductor.cancelImmediately();
-                    clientVibrationCompleteIfNotAlready(Vibration.Status.CANCELLED);
-                    break;
                 }
             }
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
         }
     }
-
-    private static CombinedVibration.Sequential toSequential(CombinedVibration effect) {
-        if (effect instanceof CombinedVibration.Sequential) {
-            return (CombinedVibration.Sequential) effect;
-        }
-        return (CombinedVibration.Sequential) CombinedVibration.startSequential()
-                .addNext(effect)
-                .combine();
-    }
-
 }
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 01f9d0b9..1260e5d 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -28,10 +28,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.hardware.vibrator.IVibrator;
 import android.os.BatteryStats;
 import android.os.Binder;
+import android.os.Build;
 import android.os.CombinedVibration;
 import android.os.ExternalVibration;
 import android.os.Handler;
@@ -53,6 +53,7 @@
 import android.os.VibratorInfo;
 import android.os.vibrator.PrebakedSegment;
 import android.os.vibrator.VibrationEffectSegment;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
@@ -62,7 +63,6 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.LocalServices;
 import com.android.server.SystemService;
 
 import libcore.util.NativeAllocationRegistry;
@@ -93,6 +93,12 @@
     /** Fixed large duration used to note repeating vibrations to {@link IBatteryStats}. */
     private static final long BATTERY_STATS_REPEATING_VIBRATION_DURATION = 5_000;
 
+    /**
+     * Maximum millis to wait for a vibration thread cancellation to "clean up" and finish, when
+     * blocking for an external vibration. In practice, this should be plenty.
+     */
+    private static final long VIBRATION_CANCEL_WAIT_MILLIS = 5000;
+
     /** Lifecycle responsible for initializing this class at the right system server phases. */
     public static class Lifecycle extends SystemService {
         private VibratorManagerService mService;
@@ -120,10 +126,10 @@
 
     private final Object mLock = new Object();
     private final Context mContext;
-    private final String mSystemUiPackage;
     private final PowerManager.WakeLock mWakeLock;
     private final IBatteryStats mBatteryStatsService;
     private final Handler mHandler;
+    private final VibrationThread mVibrationThread;
     private final AppOpsManager mAppOps;
     private final NativeWrapper mNativeWrapper;
     private final VibratorManagerRecords mVibratorManagerRecords;
@@ -135,9 +141,9 @@
     @GuardedBy("mLock")
     private final SparseArray<AlwaysOnVibration> mAlwaysOnEffects = new SparseArray<>();
     @GuardedBy("mLock")
-    private VibrationThread mCurrentVibration;
+    private VibrationStepConductor mCurrentVibration;
     @GuardedBy("mLock")
-    private VibrationThread mNextVibration;
+    private VibrationStepConductor mNextVibration;
     @GuardedBy("mLock")
     private ExternalVibrationHolder mCurrentExternalVibration;
     @GuardedBy("mLock")
@@ -153,18 +159,13 @@
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                 synchronized (mLock) {
-                    // When the system is entering a non-interactive state, we want
-                    // to cancel vibrations in case a misbehaving app has abandoned
-                    // them.  However it may happen that the system is currently playing
-                    // haptic feedback as part of the transition.  So we don't cancel
-                    // system vibrations.
-                    if (mNextVibration != null
-                            && !isSystemHapticFeedback(mNextVibration.getVibration())) {
+                    // When the system is entering a non-interactive state, we want to cancel
+                    // vibrations in case a misbehaving app has abandoned them.
+                    if (shouldCancelOnScreenOffLocked(mNextVibration)) {
                         clearNextVibrationLocked(Vibration.Status.CANCELLED);
                     }
-                    if (mCurrentVibration != null
-                            && !isSystemHapticFeedback(mCurrentVibration.getVibration())) {
-                        mCurrentVibration.cancel();
+                    if (shouldCancelOnScreenOffLocked(mCurrentVibration)) {
+                        mCurrentVibration.notifyCancelled(/* immediate= */ false);
                     }
                 }
             }
@@ -203,9 +204,6 @@
                 com.android.internal.R.integer.config_previousVibrationsDumpLimit);
         mVibratorManagerRecords = new VibratorManagerRecords(dumpLimit);
 
-        mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
-                .getSystemUiServiceComponent().getPackageName();
-
         mBatteryStatsService = injector.getBatteryStatsService();
 
         mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -213,6 +211,8 @@
         PowerManager pm = context.getSystemService(PowerManager.class);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
         mWakeLock.setReferenceCounted(true);
+        mVibrationThread = new VibrationThread(mWakeLock, mVibrationThreadCallbacks);
+        mVibrationThread.start();
 
         // Load vibrator hardware info. The vibrator ids and manager capabilities are loaded only
         // once and assumed unchanged for the lifecycle of this service. Each individual vibrator
@@ -420,7 +420,7 @@
                 final long ident = Binder.clearCallingIdentity();
                 try {
                     if (mCurrentVibration != null) {
-                        mCurrentVibration.cancel();
+                        mCurrentVibration.notifyCancelled(/* immediate= */ false);
                     }
                     Vibration.Status status = startVibrationLocked(vib);
                     if (status != Vibration.Status.RUNNING) {
@@ -458,16 +458,15 @@
                     if (mCurrentVibration != null
                             && shouldCancelVibration(mCurrentVibration.getVibration(),
                             usageFilter, token)) {
-                        mCurrentVibration.cancel();
+                        mCurrentVibration.notifyCancelled(/* immediate= */false);
                     }
                     if (mCurrentExternalVibration != null
                             && 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);
@@ -595,7 +594,7 @@
                     Slog.d(TAG, "Canceling vibration because settings changed: "
                             + (inputDevicesChanged ? "input devices changed" : ignoreStatus));
                 }
-                mCurrentVibration.cancel();
+                mCurrentVibration.notifyCancelled(/* immediate= */ false);
             }
         }
     }
@@ -637,17 +636,15 @@
                 return Vibration.Status.FORWARDED_TO_INPUT_DEVICES;
             }
 
-            VibrationThread vibThread = new VibrationThread(vib, mVibrationSettings,
-                    mDeviceVibrationEffectAdapter, mVibrators, mWakeLock,
-                    mVibrationThreadCallbacks);
-
+            VibrationStepConductor conductor = new VibrationStepConductor(vib, mVibrationSettings,
+                    mDeviceVibrationEffectAdapter, mVibrators, mVibrationThreadCallbacks);
             if (mCurrentVibration == null) {
-                return startVibrationThreadLocked(vibThread);
+                return startVibrationOnThreadLocked(conductor);
             }
             // If there's already a vibration queued (waiting for the previous one to finish
             // cancelling), end it cleanly and replace it with the new one.
             clearNextVibrationLocked(Vibration.Status.IGNORED_SUPERSEDED);
-            mNextVibration = vibThread;
+            mNextVibration = conductor;
             return Vibration.Status.RUNNING;
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
@@ -655,16 +652,20 @@
     }
 
     @GuardedBy("mLock")
-    private Vibration.Status startVibrationThreadLocked(VibrationThread vibThread) {
+    private Vibration.Status startVibrationOnThreadLocked(VibrationStepConductor conductor) {
         Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "startVibrationThreadLocked");
         try {
-            Vibration vib = vibThread.getVibration();
+            Vibration vib = conductor.getVibration();
             int mode = startAppOpModeLocked(vib.uid, vib.opPkg, vib.attrs);
             switch (mode) {
                 case AppOpsManager.MODE_ALLOWED:
                     Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
-                    mCurrentVibration = vibThread;
-                    mCurrentVibration.start();
+                    mCurrentVibration = conductor;
+                    if (!mVibrationThread.runVibrationOnVibrationThread(mCurrentVibration)) {
+                        // Shouldn't happen. The method call already logs a wtf.
+                        mCurrentVibration = null;  // Aborted.
+                        return Vibration.Status.IGNORED_ERROR_SCHEDULING;
+                    }
                     return Vibration.Status.RUNNING;
                 case AppOpsManager.MODE_ERRORED:
                     Slog.w(TAG, "Start AppOpsManager operation errored for uid " + vib.uid);
@@ -752,7 +753,7 @@
                 if (DEBUG) {
                     Slog.d(TAG, "Synced vibration " + vibrationId + " complete, notifying thread");
                 }
-                mCurrentVibration.syncedVibrationComplete();
+                mCurrentVibration.notifySyncedVibrationComplete();
             }
         }
     }
@@ -764,7 +765,7 @@
                     Slog.d(TAG, "Vibration " + vibrationId + " on vibrator " + vibratorId
                             + " complete, notifying thread");
                 }
-                mCurrentVibration.vibratorComplete(vibratorId);
+                mCurrentVibration.notifyVibratorComplete(vibratorId);
             }
         }
     }
@@ -1074,11 +1075,14 @@
                 == PackageManager.PERMISSION_GRANTED;
     }
 
-    private boolean isSystemHapticFeedback(Vibration vib) {
-        if (vib.attrs.getUsage() != VibrationAttributes.USAGE_TOUCH) {
+    @GuardedBy("mLock")
+    private boolean shouldCancelOnScreenOffLocked(@Nullable VibrationStepConductor conductor) {
+        if (conductor == null) {
             return false;
         }
-        return vib.uid == Process.SYSTEM_UID || vib.uid == 0 || mSystemUiPackage.equals(vib.opPkg);
+        Vibration vib = conductor.getVibration();
+        return mVibrationSettings.shouldCancelVibrationOnScreenOff(
+                vib.uid, vib.opPkg, vib.attrs.getUsage());
     }
 
     @GuardedBy("mLock")
@@ -1193,21 +1197,27 @@
         }
 
         @Override
-        public void onVibrationThreadReleased() {
+        public void onVibrationThreadReleased(long vibrationId) {
             if (DEBUG) {
-                Slog.d(TAG, "Vibrators released after finished vibration");
+                Slog.d(TAG, "VibrationThread released after finished vibration");
             }
             synchronized (mLock) {
                 if (DEBUG) {
-                    Slog.d(TAG, "Processing vibrators released callback");
+                    Slog.d(TAG, "Processing VibrationThread released callback");
+                }
+                if (Build.IS_DEBUGGABLE && mCurrentVibration != null
+                        && mCurrentVibration.getVibration().id != vibrationId) {
+                    Slog.wtf(TAG, TextUtils.formatSimple(
+                            "VibrationId mismatch on release. expected=%d, released=%d",
+                            mCurrentVibration.getVibration().id, vibrationId));
                 }
                 mCurrentVibration = null;
                 if (mNextVibration != null) {
-                    VibrationThread vibThread = mNextVibration;
+                    VibrationStepConductor nextConductor = mNextVibration;
                     mNextVibration = null;
-                    Vibration.Status status = startVibrationThreadLocked(vibThread);
+                    Vibration.Status status = startVibrationOnThreadLocked(nextConductor);
                     if (status != Vibration.Status.RUNNING) {
-                        endVibrationLocked(vibThread.getVibration(), status);
+                        endVibrationLocked(nextConductor.getVibration(), status);
                     }
                 }
             }
@@ -1272,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;
@@ -1297,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,
@@ -1439,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) {
@@ -1458,8 +1506,8 @@
                 return IExternalVibratorService.SCALE_MUTE;
             }
 
-            ExternalVibrationHolder cancelingExternalVibration = null;
-            VibrationThread cancelingVibration = null;
+            boolean alreadyUnderExternalControl = false;
+            boolean waitForCompletion = false;
             int scale;
             synchronized (mLock) {
                 Vibration.Status ignoreStatus = shouldIgnoreVibrationLocked(
@@ -1481,8 +1529,8 @@
                     // vibration that may be playing and ready the vibrator for external control.
                     if (mCurrentVibration != null) {
                         clearNextVibrationLocked(Vibration.Status.IGNORED_FOR_EXTERNAL);
-                        mCurrentVibration.cancelImmediately();
-                        cancelingVibration = mCurrentVibration;
+                        mCurrentVibration.notifyCancelled(/* immediate= */ true);
+                        waitForCompletion = true;
                     }
                 } else {
                     // At this point we have an externally controlled vibration playing already.
@@ -1493,29 +1541,29 @@
                     //
                     // 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;
             }
 
-            if (cancelingVibration != null) {
-                try {
-                    cancelingVibration.join();
-                } catch (InterruptedException e) {
-                    Slog.w("Interrupted while waiting for vibration to finish before starting "
-                            + "external control", e);
+            if (waitForCompletion) {
+                if (!mVibrationThread.waitForThreadIdle(VIBRATION_CANCEL_WAIT_MILLIS)) {
+                    Slog.e(TAG, "Timed out waiting for vibration to cancel");
+                    synchronized (mLock) {
+                        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.");
                 }
@@ -1535,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)) {
@@ -1566,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/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 87c8a79..2da2987 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -62,8 +62,8 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
 import android.graphics.Color;
+import android.graphics.ImageDecoder;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.hardware.display.DisplayManager;
@@ -199,6 +199,8 @@
     static final String WALLPAPER_LOCK_ORIG = "wallpaper_lock_orig";
     static final String WALLPAPER_LOCK_CROP = "wallpaper_lock";
     static final String WALLPAPER_INFO = "wallpaper_info.xml";
+    private static final String RECORD_FILE = "decode_record";
+    private static final String RECORD_LOCK_FILE = "decode_lock_record";
 
     // All the various per-user state files we need to be aware of
     private static final String[] sPerUserFiles = new String[] {
@@ -689,8 +691,7 @@
                 }
 
                 if (DEBUG) {
-                    // This is just a quick estimation, may be smaller than it is.
-                    long estimateSize = options.outWidth * options.outHeight * 4;
+                    long estimateSize = (long) options.outWidth * options.outHeight * 4;
                     Slog.v(TAG, "Null crop of new wallpaper, estimate size="
                             + estimateSize + ", success=" + success);
                 }
@@ -699,9 +700,6 @@
                 FileOutputStream f = null;
                 BufferedOutputStream bos = null;
                 try {
-                    BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(
-                            wallpaper.wallpaperFile.getAbsolutePath(), false);
-
                     // This actually downsamples only by powers of two, but that's okay; we do
                     // a proper scaling blit later.  This is to minimize transient RAM use.
                     // We calculate the largest power-of-two under the actual ratio rather than
@@ -755,8 +753,24 @@
                         Slog.v(TAG, "  maxTextureSize=" + GLHelper.getMaxTextureSize());
                     }
 
-                    Bitmap cropped = decoder.decodeRegion(cropHint, options);
-                    decoder.recycle();
+                    //Create a record file and will delete if ImageDecoder work well.
+                    final String recordName =
+                            (wallpaper.wallpaperFile.getName().equals(WALLPAPER)
+                                    ? RECORD_FILE : RECORD_LOCK_FILE);
+                    final File record = new File(getWallpaperDir(wallpaper.userId), recordName);
+                    record.createNewFile();
+                    Slog.v(TAG, "record path =" + record.getPath()
+                            + ", record name =" + record.getName());
+
+                    final ImageDecoder.Source srcData =
+                            ImageDecoder.createSource(wallpaper.wallpaperFile);
+                    final int sampleSize = scale;
+                    Bitmap cropped = ImageDecoder.decodeBitmap(srcData, (decoder, info, src) -> {
+                        decoder.setTargetSampleSize(sampleSize);
+                        decoder.setCrop(estimateCrop);
+                    });
+
+                    record.delete();
 
                     if (cropped == null) {
                         Slog.e(TAG, "Could not decode new wallpaper");
@@ -1819,6 +1833,7 @@
                     new UserSwitchObserver() {
                         @Override
                         public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+                            errorCheck(newUserId);
                             switchUser(newUserId, reply);
                         }
                     }, TAG);
@@ -1856,6 +1871,14 @@
 
     @Override
     public void onBootPhase(int phase) {
+        // If someone set too large jpg file as wallpaper, system_server may be killed by lmk in
+        // generateCrop(), so we create a file in generateCrop() before ImageDecoder starts working
+        // and delete this file after ImageDecoder finishing. If the specific file exists, that
+        // means ImageDecoder can't handle the original wallpaper file, in order to avoid
+        // system_server restart again and again and rescue party will trigger factory reset,
+        // so we reset default wallpaper in case system_server is trapped into a restart loop.
+        errorCheck(UserHandle.USER_SYSTEM);
+
         if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
             systemReady();
         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
@@ -1863,6 +1886,38 @@
         }
     }
 
+    private static final HashMap<Integer, String> sWallpaperType = new HashMap<Integer, String>() {
+        {
+            put(FLAG_SYSTEM, RECORD_FILE);
+            put(FLAG_LOCK, RECORD_LOCK_FILE);
+        }
+    };
+
+    private void errorCheck(int userID) {
+        sWallpaperType.forEach((type, filename) -> {
+            final File record = new File(getWallpaperDir(userID), filename);
+            if (record.exists()) {
+                Slog.w(TAG, "User:" + userID + ", wallpaper tyep = " + type
+                        + ", wallpaper fail detect!! reset to default wallpaper");
+                clearWallpaperData(userID, type);
+                record.delete();
+            }
+        });
+    }
+
+    private void clearWallpaperData(int userID, int wallpaperType) {
+        final WallpaperData wallpaper = new WallpaperData(userID, getWallpaperDir(userID),
+                (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_ORIG : WALLPAPER,
+                (wallpaperType == FLAG_LOCK) ? WALLPAPER_LOCK_CROP : WALLPAPER_CROP);
+        if (wallpaper.sourceExists()) {
+            wallpaper.wallpaperFile.delete();
+        }
+        if (wallpaper.cropExists()) {
+            wallpaper.cropFile.delete();
+        }
+
+    }
+
     @Override
     public void onUnlockUser(final int userId) {
         synchronized (mLock) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 0396a11..e37b08f4 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -45,7 +45,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowTracing.WINSCOPE_EXT;
-import static com.android.server.wm.utils.RegionUtils.forEachRect;
 
 import android.accessibilityservice.AccessibilityTrace;
 import android.animation.ObjectAnimator;
@@ -80,6 +79,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
 import android.util.TypedValue;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
@@ -101,6 +101,7 @@
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.AccessibilityWindowsPopulator.AccessibilityWindow;
 import com.android.server.wm.WindowManagerInternal.AccessibilityControllerInternal;
 import com.android.server.wm.WindowManagerInternal.MagnificationCallbacks;
 import com.android.server.wm.WindowManagerInternal.WindowsForAccessibilityCallback;
@@ -133,19 +134,22 @@
     private static final Rect EMPTY_RECT = new Rect();
     private static final float[] sTempFloats = new float[9];
 
-    private SparseArray<DisplayMagnifier> mDisplayMagnifiers = new SparseArray<>();
-    private SparseArray<WindowsForAccessibilityObserver> mWindowsForAccessibilityObserver =
+    private final SparseArray<DisplayMagnifier> mDisplayMagnifiers = new SparseArray<>();
+    private final SparseArray<WindowsForAccessibilityObserver> mWindowsForAccessibilityObserver =
             new SparseArray<>();
     private SparseArray<IBinder> mFocusedWindow = new SparseArray<>();
     private int mFocusedDisplay = -1;
-    private boolean mIsImeVisible = false;
+    private final SparseBooleanArray mIsImeVisibleArray = new SparseBooleanArray();
     // Set to true if initializing window population complete.
     private boolean mAllObserversInitialized = true;
+    private final AccessibilityWindowsPopulator mAccessibilityWindowsPopulator;
 
     AccessibilityController(WindowManagerService service) {
         mService = service;
         mAccessibilityTracing =
                 AccessibilityController.getAccessibilityControllerInternal(service);
+
+        mAccessibilityWindowsPopulator = new AccessibilityWindowsPopulator(mService, this);
     }
 
     boolean setMagnificationCallbacks(int displayId, MagnificationCallbacks callbacks) {
@@ -164,8 +168,11 @@
             if (dc != null) {
                 final Display display = dc.getDisplay();
                 if (display != null && display.getType() != Display.TYPE_OVERLAY) {
-                    mDisplayMagnifiers.put(displayId, new DisplayMagnifier(
-                            mService, dc, display, callbacks));
+                    final DisplayMagnifier magnifier = new DisplayMagnifier(
+                            mService, dc, display, callbacks);
+                    magnifier.notifyImeWindowVisibilityChanged(
+                            mIsImeVisibleArray.get(displayId, false));
+                    mDisplayMagnifiers.put(displayId, magnifier);
                     result = true;
                 }
             }
@@ -209,7 +216,9 @@
                 }
                 mWindowsForAccessibilityObserver.remove(displayId);
             }
-            observer = new WindowsForAccessibilityObserver(mService, displayId, callback);
+            mAccessibilityWindowsPopulator.setWindowsNotification(true);
+            observer = new WindowsForAccessibilityObserver(mService, displayId, callback,
+                    mAccessibilityWindowsPopulator);
             mWindowsForAccessibilityObserver.put(displayId, observer);
             mAllObserversInitialized &= observer.mInitialized;
         } else {
@@ -224,6 +233,10 @@
                 }
             }
             mWindowsForAccessibilityObserver.remove(displayId);
+
+            if (mWindowsForAccessibilityObserver.size() <= 0) {
+                mAccessibilityWindowsPopulator.setWindowsNotification(false);
+            }
         }
     }
 
@@ -254,6 +267,8 @@
                     FLAGS_MAGNIFICATION_CALLBACK | FLAGS_WINDOWS_FOR_ACCESSIBILITY_CALLBACK,
                     "displayId=" + displayId + "; spec={" + spec + "}");
         }
+        mAccessibilityWindowsPopulator.setMagnificationSpec(displayId, spec);
+
         final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
         if (displayMagnifier != null) {
             displayMagnifier.setMagnificationSpec(spec);
@@ -309,11 +324,6 @@
         if (displayMagnifier != null) {
             displayMagnifier.onDisplaySizeChanged(displayContent);
         }
-        final WindowsForAccessibilityObserver windowsForA11yObserver =
-                mWindowsForAccessibilityObserver.get(displayId);
-        if (windowsForA11yObserver != null) {
-            windowsForA11yObserver.scheduleComputeChangedWindows();
-        }
     }
 
     void onAppWindowTransition(int displayId, int transition) {
@@ -341,11 +351,6 @@
         if (displayMagnifier != null) {
             displayMagnifier.onWindowTransition(windowState, transition);
         }
-        final WindowsForAccessibilityObserver windowsForA11yObserver =
-                mWindowsForAccessibilityObserver.get(displayId);
-        if (windowsForA11yObserver != null) {
-            windowsForA11yObserver.scheduleComputeChangedWindows();
-        }
     }
 
     void onWindowFocusChangedNot(int displayId) {
@@ -482,11 +487,13 @@
             mAccessibilityTracing.logTrace(TAG + ".updateImeVisibilityIfNeeded",
                     FLAGS_MAGNIFICATION_CALLBACK, "displayId=" + displayId + ";shown=" + shown);
         }
-        if (mIsImeVisible == shown) {
+
+        final boolean isDisplayImeVisible = mIsImeVisibleArray.get(displayId, false);
+        if (isDisplayImeVisible == shown) {
             return;
         }
 
-        mIsImeVisible = shown;
+        mIsImeVisibleArray.put(displayId, shown);
         final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
         if (displayMagnifier != null) {
             displayMagnifier.notifyImeWindowVisibilityChanged(shown);
@@ -522,6 +529,7 @@
     }
 
     public void onDisplayRemoved(int displayId) {
+        mIsImeVisibleArray.delete(displayId);
         mFocusedWindow.remove(displayId);
     }
 
@@ -1403,20 +1411,18 @@
 
         private static final boolean DEBUG = false;
 
-        private final SparseArray<WindowState> mTempWindowStates = new SparseArray<>();
+        private final List<AccessibilityWindow> mTempA11yWindows = new ArrayList<>();
 
         private final Set<IBinder> mTempBinderSet = new ArraySet<>();
 
-        private final RectF mTempRectF = new RectF();
-
-        private final Matrix mTempMatrix = new Matrix();
-
         private final Point mTempPoint = new Point();
 
         private final Region mTempRegion = new Region();
 
         private final Region mTempRegion1 = new Region();
 
+        private final Region mTempRegion2 = new Region();
+
         private final WindowManagerService mService;
 
         private final Handler mHandler;
@@ -1431,10 +1437,11 @@
 
         // Set to true if initializing window population complete.
         private boolean mInitialized;
+        private final AccessibilityWindowsPopulator mA11yWindowsPopulator;
 
         WindowsForAccessibilityObserver(WindowManagerService windowManagerService,
-                int displayId,
-                WindowsForAccessibilityCallback callback) {
+                int displayId, WindowsForAccessibilityCallback callback,
+                AccessibilityWindowsPopulator accessibilityWindowsPopulator) {
             mService = windowManagerService;
             mCallback = callback;
             mDisplayId = displayId;
@@ -1443,6 +1450,7 @@
                     AccessibilityController.getAccessibilityControllerInternal(mService);
             mRecurringAccessibilityEventsIntervalMillis = ViewConfiguration
                     .getSendRecurringAccessibilityEventsInterval();
+            mA11yWindowsPopulator = accessibilityWindowsPopulator;
             computeChangedWindows(true);
         }
 
@@ -1466,52 +1474,6 @@
             }
         }
 
-        boolean shellRootIsAbove(WindowState windowState, ShellRoot shellRoot) {
-            int wsLayer = mService.mPolicy.getWindowLayerLw(windowState);
-            int shellLayer = mService.mPolicy.getWindowLayerFromTypeLw(shellRoot.getWindowType(),
-                    true);
-            return shellLayer >= wsLayer;
-        }
-
-        int addShellRootsIfAbove(WindowState windowState, ArrayList<ShellRoot> shellRoots,
-                int shellRootIndex, List<WindowInfo> windows, Set<IBinder> addedWindows,
-                Region unaccountedSpace, boolean focusedWindowAdded) {
-            while (shellRootIndex < shellRoots.size()
-                    && shellRootIsAbove(windowState, shellRoots.get(shellRootIndex))) {
-                ShellRoot shellRoot = shellRoots.get(shellRootIndex);
-                shellRootIndex++;
-                final WindowInfo info = shellRoot.getWindowInfo();
-                if (info == null) {
-                    continue;
-                }
-
-                info.layer = addedWindows.size();
-                windows.add(info);
-                addedWindows.add(info.token);
-                unaccountedSpace.op(info.regionInScreen, unaccountedSpace,
-                        Region.Op.REVERSE_DIFFERENCE);
-                if (unaccountedSpace.isEmpty() && focusedWindowAdded) {
-                    break;
-                }
-            }
-            return shellRootIndex;
-        }
-
-        private ArrayList<ShellRoot> getSortedShellRoots(
-                SparseArray<ShellRoot> originalShellRoots) {
-            ArrayList<ShellRoot> sortedShellRoots = new ArrayList<>(originalShellRoots.size());
-            for (int i = originalShellRoots.size() - 1; i >= 0; --i) {
-                sortedShellRoots.add(originalShellRoots.valueAt(i));
-            }
-
-            sortedShellRoots.sort((left, right) ->
-                    mService.mPolicy.getWindowLayerFromTypeLw(right.getWindowType(), true)
-                            - mService.mPolicy.getWindowLayerFromTypeLw(left.getWindowType(),
-                            true));
-
-            return sortedShellRoots;
-        }
-
         /**
          * Check if windows have changed, and send them to the accessibility subsystem if they have.
          *
@@ -1561,44 +1523,29 @@
                 Region unaccountedSpace = mTempRegion;
                 unaccountedSpace.set(0, 0, screenWidth, screenHeight);
 
-                final SparseArray<WindowState> visibleWindows = mTempWindowStates;
-                populateVisibleWindowsOnScreen(visibleWindows);
+                final List<AccessibilityWindow> visibleWindows = mTempA11yWindows;
+                mA11yWindowsPopulator.populateVisibleWindowsOnScreenLocked(
+                        mDisplayId, visibleWindows);
                 Set<IBinder> addedWindows = mTempBinderSet;
                 addedWindows.clear();
 
                 boolean focusedWindowAdded = false;
 
                 final int visibleWindowCount = visibleWindows.size();
-                ArrayList<TaskFragment> skipRemainingWindowsForTaskFragments = new ArrayList<>();
-
-                ArrayList<ShellRoot> shellRoots = getSortedShellRoots(dc.mShellRoots);
 
                 // Iterate until we figure out what is touchable for the entire screen.
-                int shellRootIndex = 0;
-                for (int i = visibleWindowCount - 1; i >= 0; i--) {
-                    final WindowState windowState = visibleWindows.valueAt(i);
-                    int prevShellRootIndex = shellRootIndex;
-                    shellRootIndex = addShellRootsIfAbove(windowState, shellRoots, shellRootIndex,
-                            windows, addedWindows, unaccountedSpace, focusedWindowAdded);
-
-                    // If a Shell Root was added, it could have accounted for all the space already.
-                    if (shellRootIndex > prevShellRootIndex && unaccountedSpace.isEmpty()
-                            && focusedWindowAdded) {
-                        break;
-                    }
-
-                    final Region regionInScreen = new Region();
-                    computeWindowRegionInScreen(windowState, regionInScreen);
-                    if (windowMattersToAccessibility(windowState,
-                            regionInScreen, unaccountedSpace,
-                            skipRemainingWindowsForTaskFragments)) {
-                        addPopulatedWindowInfo(windowState, regionInScreen, windows, addedWindows);
-                        if (windowMattersToUnaccountedSpaceComputation(windowState)) {
-                            updateUnaccountedSpace(windowState, regionInScreen, unaccountedSpace,
-                                    skipRemainingWindowsForTaskFragments);
+                for (int i = 0; i < visibleWindowCount; i++) {
+                    final AccessibilityWindow a11yWindow = visibleWindows.get(i);
+                    final Region regionInWindow = new Region();
+                    a11yWindow.getTouchableRegionInWindow(regionInWindow);
+                    if (windowMattersToAccessibility(a11yWindow, regionInWindow,
+                            unaccountedSpace)) {
+                        addPopulatedWindowInfo(a11yWindow, regionInWindow, windows, addedWindows);
+                        if (windowMattersToUnaccountedSpaceComputation(a11yWindow)) {
+                            updateUnaccountedSpace(a11yWindow, unaccountedSpace);
                         }
-                        focusedWindowAdded |= windowState.isFocused();
-                    } else if (isUntouchableNavigationBar(windowState, mTempRegion1)) {
+                        focusedWindowAdded |= a11yWindow.isFocused();
+                    } else if (a11yWindow.isUntouchableNavigationBar()) {
                         // If this widow is navigation bar without touchable region, accounting the
                         // region of navigation bar inset because all touch events from this region
                         // would be received by launcher, i.e. this region is a un-touchable one
@@ -1647,47 +1594,39 @@
 
         // Some windows should be excluded from unaccounted space computation, though they still
         // should be reported
-        private boolean windowMattersToUnaccountedSpaceComputation(WindowState windowState) {
+        private boolean windowMattersToUnaccountedSpaceComputation(AccessibilityWindow a11yWindow) {
             // Do not account space of trusted non-touchable windows, except the split-screen
             // divider.
             // If it's not trusted, touch events are not sent to the windows behind it.
-            if (((windowState.mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
-                    && (windowState.mAttrs.type != TYPE_DOCK_DIVIDER)
-                    && windowState.isTrustedOverlay()) {
+            if (((a11yWindow.getFlags() & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
+                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER)
+                    && a11yWindow.isTrustedOverlay()) {
                 return false;
             }
 
-            if (windowState.mAttrs.type
-                    == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
+            if (a11yWindow.getType() == WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
                 return false;
             }
             return true;
         }
 
-        private boolean windowMattersToAccessibility(WindowState windowState,
-                Region regionInScreen, Region unaccountedSpace,
-                ArrayList<TaskFragment> skipRemainingWindowsForTaskFragments) {
-            final RecentsAnimationController controller = mService.getRecentsAnimationController();
-            if (controller != null && controller.shouldIgnoreForAccessibility(windowState)) {
+        private boolean windowMattersToAccessibility(AccessibilityWindow a11yWindow,
+                Region regionInScreen, Region unaccountedSpace) {
+            if (a11yWindow.ignoreRecentsAnimationForAccessibility()) {
                 return false;
             }
 
-            if (windowState.isFocused()) {
+            if (a11yWindow.isFocused()) {
                 return true;
             }
 
-            // If the window is part of a task that we're finished with - ignore.
-            final TaskFragment taskFragment = windowState.getTaskFragment();
-            if (taskFragment != null
-                    && skipRemainingWindowsForTaskFragments.contains(taskFragment)) {
-                return false;
-            }
-
             // Ignore non-touchable windows, except the split-screen divider, which is
             // occasionally non-touchable but still useful for identifying split-screen
-            // mode.
-            if (((windowState.mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
-                    && (windowState.mAttrs.type != TYPE_DOCK_DIVIDER)) {
+            // mode and the PIP menu.
+            if (((a11yWindow.getFlags()
+                    & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
+                    && (a11yWindow.getType() != TYPE_DOCK_DIVIDER
+                    && !a11yWindow.isPIPMenu())) {
                 return false;
             }
 
@@ -1697,88 +1636,36 @@
             }
 
             // Add windows of certain types not covered by modal windows.
-            if (isReportedWindowType(windowState.mAttrs.type)) {
+            if (isReportedWindowType(a11yWindow.getType())) {
                 return true;
             }
 
             return false;
         }
 
-        private void updateUnaccountedSpace(WindowState windowState, Region regionInScreen,
-                Region unaccountedSpace,
-                ArrayList<TaskFragment> skipRemainingWindowsForTaskFragments) {
-            // Account for the space this window takes if the window
-            // is not an accessibility overlay which does not change
-            // the reported windows.
-            unaccountedSpace.op(regionInScreen, unaccountedSpace,
-                    Region.Op.REVERSE_DIFFERENCE);
-
-            // If a window is modal it prevents other windows from being touched
-            if ((windowState.mAttrs.flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)) == 0) {
-                if (!windowState.hasTapExcludeRegion()) {
-                    // Account for all space in the task, whether the windows in it are
-                    // touchable or not. The modal window blocks all touches from the task's
-                    // area.
-                    unaccountedSpace.op(windowState.getDisplayFrame(), unaccountedSpace,
-                            Region.Op.REVERSE_DIFFERENCE);
-                } else {
-                    // If a window has tap exclude region, we need to account it.
-                    final Region displayRegion = new Region(windowState.getDisplayFrame());
-                    final Region tapExcludeRegion = new Region();
-                    windowState.getTapExcludeRegion(tapExcludeRegion);
-                    displayRegion.op(tapExcludeRegion, displayRegion,
-                            Region.Op.REVERSE_DIFFERENCE);
-                    unaccountedSpace.op(displayRegion, unaccountedSpace,
-                            Region.Op.REVERSE_DIFFERENCE);
-                }
-
-                final TaskFragment taskFragment = windowState.getTaskFragment();
-                if (taskFragment != null) {
-                    // If the window is associated with a particular task, we can skip the
-                    // rest of the windows for that task.
-                    skipRemainingWindowsForTaskFragments.add(taskFragment);
-                } else if (!windowState.hasTapExcludeRegion()) {
-                    // If the window is not associated with a particular task, then it is
-                    // globally modal. In this case we can skip all remaining windows when
-                    // it doesn't has tap exclude region.
-                    unaccountedSpace.setEmpty();
-                }
-            }
-
-            // Account for the space of letterbox.
-            if (windowState.areAppWindowBoundsLetterboxed()) {
-                unaccountedSpace.op(getLetterboxBounds(windowState), unaccountedSpace,
+        private void updateUnaccountedSpace(AccessibilityWindow a11yWindow,
+                Region unaccountedSpace) {
+            if (a11yWindow.getType()
+                    != WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY) {
+                // Account for the space this window takes if the window
+                // is not an accessibility overlay which does not change
+                // the reported windows.
+                final Region touchableRegion = mTempRegion2;
+                a11yWindow.getTouchableRegionInScreen(touchableRegion);
+                unaccountedSpace.op(touchableRegion, unaccountedSpace,
                         Region.Op.REVERSE_DIFFERENCE);
+                // Account for the space of letterbox.
+                final Region letterboxBounds = mTempRegion1;
+                if (a11yWindow.setLetterBoxBoundsIfNeeded(letterboxBounds)) {
+                    unaccountedSpace.op(letterboxBounds,
+                            unaccountedSpace, Region.Op.REVERSE_DIFFERENCE);
+                }
             }
         }
 
-        private void computeWindowRegionInScreen(WindowState windowState, Region outRegion) {
-            // Get the touchable frame.
-            Region touchableRegion = mTempRegion1;
-            windowState.getTouchableRegion(touchableRegion);
-
-            // Map the frame to get what appears on the screen.
-            Matrix matrix = mTempMatrix;
-            populateTransformationMatrix(windowState, matrix);
-
-            forEachRect(touchableRegion, rect -> {
-                // Move to origin as all transforms are captured by the matrix.
-                RectF windowFrame = mTempRectF;
-                windowFrame.set(rect);
-                windowFrame.offset(-windowState.getFrame().left, -windowState.getFrame().top);
-
-                matrix.mapRect(windowFrame);
-
-                // Union all rects.
-                outRegion.union(new Rect((int) windowFrame.left, (int) windowFrame.top,
-                        (int) windowFrame.right, (int) windowFrame.bottom));
-            });
-        }
-
-        private static void addPopulatedWindowInfo(WindowState windowState, Region regionInScreen,
-                List<WindowInfo> out, Set<IBinder> tokenOut) {
-            final WindowInfo window = windowState.getWindowInfo();
+        private static void addPopulatedWindowInfo(AccessibilityWindow a11yWindow,
+                Region regionInScreen, List<WindowInfo> out, Set<IBinder> tokenOut) {
+            final WindowInfo window = a11yWindow.getWindowInfo();
             window.regionInScreen.set(regionInScreen);
             window.layer = tokenOut.size();
             out.add(window);
@@ -1805,23 +1692,6 @@
                     && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
         }
 
-        private void populateVisibleWindowsOnScreen(SparseArray<WindowState> outWindows) {
-            final List<WindowState> tempWindowStatesList = new ArrayList<>();
-            final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
-            if (dc == null) {
-                return;
-            }
-
-            dc.forAllWindows(w -> {
-                if (w.isVisible()) {
-                    tempWindowStatesList.add(w);
-                }
-            }, false /* traverseTopToBottom */);
-            for (int i = 0; i < tempWindowStatesList.size(); i++) {
-                outWindows.put(i, tempWindowStatesList.get(i));
-            }
-        }
-
         private WindowState getTopFocusWindow() {
             return mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus;
         }
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
new file mode 100644
index 0000000..d4648a4
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -0,0 +1,870 @@
+/*
+ * 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.wm;
+
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+
+import static com.android.server.wm.utils.RegionUtils.forEachRect;
+
+import android.annotation.NonNull;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+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;
+import android.util.SparseArray;
+import android.view.IWindow;
+import android.view.InputWindowHandle;
+import android.view.MagnificationSpec;
+import android.view.WindowInfo;
+import android.view.WindowManager;
+import android.window.WindowInfosListener;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is the accessibility windows population adapter.
+ */
+public final class AccessibilityWindowsPopulator extends WindowInfosListener {
+
+    private static final String TAG = AccessibilityWindowsPopulator.class.getSimpleName();
+    // If the surface flinger callback is not coming within in 2 frames time, i.e. about
+    // 35ms, then assuming the windows become stable.
+    private static final int SURFACE_FLINGER_CALLBACK_WINDOWS_STABLE_TIMES_MS = 35;
+    // To avoid the surface flinger callbacks always comes within in 2 frames, then no windows
+    // are reported to the A11y framework, and the animation duration time is 500ms, so setting
+    // this value as the max timeout value to force computing changed windows.
+    private static final int WINDOWS_CHANGED_NOTIFICATION_MAX_DURATION_TIMES_MS = 500;
+
+    private static final float[] sTempFloats = new float[9];
+
+    private final WindowManagerService mService;
+    private final AccessibilityController mAccessibilityController;
+    @GuardedBy("mLock")
+    private final SparseArray<List<InputWindowHandle>> mInputWindowHandlesOnDisplays =
+            new SparseArray<>();
+    @GuardedBy("mLock")
+    private final SparseArray<Matrix> mMagnificationSpecInverseMatrix = new SparseArray<>();
+    @GuardedBy("mLock")
+    private final SparseArray<DisplayInfo> mDisplayInfos = new SparseArray<>();
+    private final SparseArray<MagnificationSpec> mCurrentMagnificationSpec = new SparseArray<>();
+    @GuardedBy("mLock")
+    private final SparseArray<MagnificationSpec> mPreviousMagnificationSpec = new SparseArray<>();
+    @GuardedBy("mLock")
+    private final List<InputWindowHandle> mVisibleWindows = new ArrayList<>();
+    @GuardedBy("mLock")
+    private boolean mWindowsNotificationEnabled = false;
+    @GuardedBy("mLock")
+    private final Map<IBinder, Matrix> mWindowsTransformMatrixMap = new HashMap<>();
+    private final Object mLock = new Object();
+    private final Handler mHandler;
+
+    private final Matrix mTempMatrix1 = new Matrix();
+    private final Matrix mTempMatrix2 = new Matrix();
+    private final float[] mTempFloat1 = new float[9];
+    private final float[] mTempFloat2 = new float[9];
+    private final float[] mTempFloat3 = new float[9];
+
+    AccessibilityWindowsPopulator(WindowManagerService service,
+            AccessibilityController accessibilityController) {
+        mService = service;
+        mAccessibilityController = accessibilityController;
+        mHandler = new MyHandler(mService.mH.getLooper());
+
+        register();
+    }
+
+    /**
+     * Gets the visible windows list with the window layer on the specified display.
+     *
+     * @param displayId The display.
+     * @param outWindows The visible windows list. The z-order of each window in the list
+     *                   is from the top to bottom.
+     */
+    public void populateVisibleWindowsOnScreenLocked(int displayId,
+            List<AccessibilityWindow> outWindows) {
+        List<InputWindowHandle> inputWindowHandles;
+        final Matrix inverseMatrix = new Matrix();
+        final Matrix displayMatrix = new Matrix();
+
+        synchronized (mLock) {
+            inputWindowHandles = mInputWindowHandlesOnDisplays.get(displayId);
+            if (inputWindowHandles == null) {
+                outWindows.clear();
+
+                return;
+            }
+            inverseMatrix.set(mMagnificationSpecInverseMatrix.get(displayId));
+
+            final DisplayInfo displayInfo = mDisplayInfos.get(displayId);
+            if (displayInfo != null) {
+                displayMatrix.set(displayInfo.mTransform);
+            } else {
+                Slog.w(TAG, "The displayInfo of this displayId (" + displayId + ") called "
+                        + "back from the surface fligner is null");
+            }
+        }
+
+        final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
+        final ShellRoot shellroot = dc.mShellRoots.get(WindowManager.SHELL_ROOT_LAYER_PIP);
+        final IBinder pipMenuIBinder =
+                shellroot != null ? shellroot.getAccessibilityWindowToken() : null;
+
+        for (final InputWindowHandle windowHandle : inputWindowHandles) {
+            final AccessibilityWindow accessibilityWindow =
+                    AccessibilityWindow.initializeData(mService, windowHandle, inverseMatrix,
+                            pipMenuIBinder, displayMatrix);
+
+            outWindows.add(accessibilityWindow);
+        }
+    }
+
+    @Override
+    public void onWindowInfosChanged(InputWindowHandle[] windowHandles,
+            DisplayInfo[] displayInfos) {
+        mHandler.post(() -> onWindowInfosChangedInternal(windowHandles, displayInfos));
+    }
+
+    private void onWindowInfosChangedInternal(InputWindowHandle[] windowHandles,
+            DisplayInfo[] displayInfos) {
+        final List<InputWindowHandle> tempVisibleWindows = new ArrayList<>();
+
+        for (InputWindowHandle window : windowHandles) {
+            final boolean visible = (window.inputConfig & InputConfig.NOT_VISIBLE) == 0;
+            if (visible && window.getWindow() != null) {
+                tempVisibleWindows.add(window);
+            }
+        }
+        final HashMap<IBinder, Matrix> windowsTransformMatrixMap =
+                getWindowsTransformMatrix(tempVisibleWindows);
+
+        synchronized (mLock) {
+            mWindowsTransformMatrixMap.clear();
+            mWindowsTransformMatrixMap.putAll(windowsTransformMatrixMap);
+
+            mVisibleWindows.clear();
+            mVisibleWindows.addAll(tempVisibleWindows);
+
+            mDisplayInfos.clear();
+            for (final DisplayInfo displayInfo : displayInfos) {
+                mDisplayInfos.put(displayInfo.mDisplayId, displayInfo);
+            }
+
+            if (mWindowsNotificationEnabled) {
+                if (!mHandler.hasMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT)) {
+                    mHandler.sendEmptyMessageDelayed(
+                            MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT,
+                            WINDOWS_CHANGED_NOTIFICATION_MAX_DURATION_TIMES_MS);
+                }
+                populateVisibleWindowHandlesAndNotifyWindowsChangeIfNeeded();
+            }
+        }
+    }
+
+    private HashMap<IBinder, Matrix> getWindowsTransformMatrix(List<InputWindowHandle> windows) {
+        synchronized (mService.mGlobalLock) {
+            final HashMap<IBinder, Matrix> windowsTransformMatrixMap = new HashMap<>();
+
+            for (InputWindowHandle inputWindowHandle : windows) {
+                final IWindow iWindow = inputWindowHandle.getWindow();
+                final WindowState windowState = iWindow != null ? mService.mWindowMap.get(
+                        iWindow.asBinder()) : null;
+
+                if (windowState != null && windowState.shouldMagnify()) {
+                    final Matrix transformMatrix = new Matrix();
+                    windowState.getTransformationMatrix(sTempFloats, transformMatrix);
+                    windowsTransformMatrixMap.put(iWindow.asBinder(), transformMatrix);
+                }
+            }
+
+            return windowsTransformMatrixMap;
+        }
+    }
+
+    /**
+     * Sets to notify the accessibilityController to compute changed windows on
+     * the display after populating the visible windows if the windows reported
+     * from the surface flinger changes.
+     *
+     * @param register {@code true} means starting windows population.
+     */
+    public void setWindowsNotification(boolean register) {
+        synchronized (mLock) {
+            if (mWindowsNotificationEnabled == register) {
+                return;
+            }
+            mWindowsNotificationEnabled = register;
+            if (mWindowsNotificationEnabled) {
+                populateVisibleWindowHandlesAndNotifyWindowsChangeIfNeeded();
+            } else {
+                releaseResources();
+            }
+        }
+    }
+
+    /**
+     * Sets the magnification spec for calculating the window bounds of all windows
+     * reported from the surface flinger in the magnifying.
+     *
+     * @param displayId The display Id.
+     * @param spec THe magnification spec.
+     */
+    public void setMagnificationSpec(int displayId, MagnificationSpec spec) {
+        synchronized (mLock) {
+            MagnificationSpec currentMagnificationSpec = mCurrentMagnificationSpec.get(displayId);
+            if (currentMagnificationSpec == null) {
+                currentMagnificationSpec = new MagnificationSpec();
+                currentMagnificationSpec.setTo(spec);
+                mCurrentMagnificationSpec.put(displayId, currentMagnificationSpec);
+
+                return;
+            }
+
+            MagnificationSpec previousMagnificationSpec = mPreviousMagnificationSpec.get(displayId);
+            if (previousMagnificationSpec == null) {
+                previousMagnificationSpec = new MagnificationSpec();
+                mPreviousMagnificationSpec.put(displayId, previousMagnificationSpec);
+            }
+            previousMagnificationSpec.setTo(currentMagnificationSpec);
+            currentMagnificationSpec.setTo(spec);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void populateVisibleWindowHandlesAndNotifyWindowsChangeIfNeeded() {
+        final SparseArray<List<InputWindowHandle>> tempWindowHandleList = new SparseArray<>();
+
+        for (final InputWindowHandle windowHandle : mVisibleWindows) {
+            List<InputWindowHandle> inputWindowHandles = tempWindowHandleList.get(
+                    windowHandle.displayId);
+
+            if (inputWindowHandles == null) {
+                inputWindowHandles = new ArrayList<>();
+                tempWindowHandleList.put(windowHandle.displayId, inputWindowHandles);
+            }
+            inputWindowHandles.add(windowHandle);
+        }
+        findMagnificationSpecInverseMatrixIfNeeded(tempWindowHandleList);
+
+        final List<Integer> displayIdsForWindowsChanged = new ArrayList<>();
+        getDisplaysForWindowsChanged(displayIdsForWindowsChanged, tempWindowHandleList,
+                mInputWindowHandlesOnDisplays);
+
+        // Clones all windows from the callback of the surface flinger.
+        mInputWindowHandlesOnDisplays.clear();
+        for (int i = 0; i < tempWindowHandleList.size(); i++) {
+            final int displayId = tempWindowHandleList.keyAt(i);
+            mInputWindowHandlesOnDisplays.put(displayId, tempWindowHandleList.get(displayId));
+        }
+
+        if (!displayIdsForWindowsChanged.isEmpty()) {
+            if (!mHandler.hasMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED)) {
+                mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED,
+                        displayIdsForWindowsChanged).sendToTarget();
+            }
+
+            return;
+        }
+        mHandler.removeMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE);
+        mHandler.sendEmptyMessageDelayed(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE,
+                SURFACE_FLINGER_CALLBACK_WINDOWS_STABLE_TIMES_MS);
+    }
+
+    @GuardedBy("mLock")
+    private static void getDisplaysForWindowsChanged(List<Integer> outDisplayIdsForWindowsChanged,
+            SparseArray<List<InputWindowHandle>> newWindowsList,
+            SparseArray<List<InputWindowHandle>> oldWindowsList) {
+        for (int i = 0; i < newWindowsList.size(); i++) {
+            final int displayId = newWindowsList.keyAt(i);
+            final List<InputWindowHandle> newWindows = newWindowsList.get(displayId);
+            final List<InputWindowHandle> oldWindows = oldWindowsList.get(displayId);
+
+            if (hasWindowsChanged(newWindows, oldWindows)) {
+                outDisplayIdsForWindowsChanged.add(displayId);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private static boolean hasWindowsChanged(List<InputWindowHandle> newWindows,
+            List<InputWindowHandle> oldWindows) {
+        if (oldWindows == null || oldWindows.size() != newWindows.size()) {
+            return true;
+        }
+
+        final int windowsCount = newWindows.size();
+        // Since we always traverse windows from high to low layer,
+        // the old and new windows at the same index should be the
+        // same, otherwise something changed.
+        for (int i = 0; i < windowsCount; i++) {
+            final InputWindowHandle newWindow = newWindows.get(i);
+            final InputWindowHandle oldWindow = oldWindows.get(i);
+
+            if (!newWindow.getWindow().asBinder().equals(oldWindow.getWindow().asBinder())) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @GuardedBy("mLock")
+    private void findMagnificationSpecInverseMatrixIfNeeded(SparseArray<List<InputWindowHandle>>
+            windowHandleList) {
+        MagnificationSpec currentMagnificationSpec;
+        MagnificationSpec previousMagnificationSpec;
+        for (int i = 0; i < windowHandleList.size(); i++) {
+            final int displayId = windowHandleList.keyAt(i);
+            List<InputWindowHandle> inputWindowHandles = windowHandleList.get(displayId);
+
+            final MagnificationSpec currentSpec = mCurrentMagnificationSpec.get(displayId);
+            if (currentSpec == null) {
+                continue;
+            }
+            currentMagnificationSpec = new MagnificationSpec();
+            currentMagnificationSpec.setTo(currentSpec);
+
+            final MagnificationSpec previousSpec = mPreviousMagnificationSpec.get(displayId);
+
+            if (previousSpec == null) {
+                final Matrix inverseMatrixForCurrentSpec = new Matrix();
+                generateInverseMatrix(currentMagnificationSpec, inverseMatrixForCurrentSpec);
+                mMagnificationSpecInverseMatrix.put(displayId, inverseMatrixForCurrentSpec);
+                continue;
+            }
+            previousMagnificationSpec = new MagnificationSpec();
+            previousMagnificationSpec.setTo(previousSpec);
+
+            generateInverseMatrixBasedOnProperMagnificationSpecForDisplay(inputWindowHandles,
+                    currentMagnificationSpec, previousMagnificationSpec);
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void generateInverseMatrixBasedOnProperMagnificationSpecForDisplay(
+            List<InputWindowHandle> inputWindowHandles, MagnificationSpec currentMagnificationSpec,
+            MagnificationSpec previousMagnificationSpec) {
+        // To decrease the counts of holding the WindowManagerService#mGlogalLock in
+        // the method, getWindowTransformMatrix(), this for loop begins from the bottom
+        // to top of the z-order windows.
+        for (int index = inputWindowHandles.size() - 1; index >= 0; index--) {
+            final Matrix windowTransformMatrix = mTempMatrix2;
+            final InputWindowHandle windowHandle = inputWindowHandles.get(index);
+            final IBinder iBinder = windowHandle.getWindow().asBinder();
+
+            if (getWindowTransformMatrix(iBinder, windowTransformMatrix)) {
+                generateMagnificationSpecInverseMatrix(windowHandle, currentMagnificationSpec,
+                        previousMagnificationSpec, windowTransformMatrix);
+
+                break;
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private boolean getWindowTransformMatrix(IBinder iBinder, Matrix outTransform) {
+        final Matrix windowMatrix = iBinder != null
+                ? mWindowsTransformMatrixMap.get(iBinder) : null;
+
+        if (windowMatrix == null) {
+            return false;
+        }
+        outTransform.set(windowMatrix);
+
+        return true;
+    }
+
+    /**
+     * Generates the inverse matrix based on the proper magnification spec.
+     * The magnification spec associated with the InputWindowHandle might not the current
+     * spec set by WM, which might be the previous one. To find the appropriate spec,
+     * we store two consecutive magnification specs, and found out which one is the proper
+     * one closing the identity matrix for generating the inverse matrix.
+     *
+     * @param inputWindowHandle The window from the surface flinger.
+     * @param currentMagnificationSpec The current magnification spec.
+     * @param previousMagnificationSpec The previous magnification spec.
+     * @param transformMatrix The transform matrix of the window doesn't consider the
+     *                        magnifying effect.
+     */
+    @GuardedBy("mLock")
+    private void generateMagnificationSpecInverseMatrix(InputWindowHandle inputWindowHandle,
+            @NonNull MagnificationSpec currentMagnificationSpec,
+            @NonNull MagnificationSpec previousMagnificationSpec, Matrix transformMatrix) {
+
+        final float[] identityMatrixFloatsForCurrentSpec = mTempFloat1;
+        computeIdentityMatrix(inputWindowHandle, currentMagnificationSpec,
+                transformMatrix, identityMatrixFloatsForCurrentSpec);
+        final float[] identityMatrixFloatsForPreviousSpec = mTempFloat2;
+        computeIdentityMatrix(inputWindowHandle, previousMagnificationSpec,
+                transformMatrix, identityMatrixFloatsForPreviousSpec);
+
+        Matrix inverseMatrixForMagnificationSpec = new Matrix();
+        if (selectProperMagnificationSpecByComparingIdentityDegree(
+                identityMatrixFloatsForCurrentSpec, identityMatrixFloatsForPreviousSpec)) {
+            generateInverseMatrix(currentMagnificationSpec,
+                    inverseMatrixForMagnificationSpec);
+
+            // Choosing the current spec means the previous spec is out of date,
+            // so removing it. And if the current spec is no magnifying, meaning
+            // the magnifying is done so removing the inverse matrix of this display.
+            mPreviousMagnificationSpec.remove(inputWindowHandle.displayId);
+            if (currentMagnificationSpec.isNop()) {
+                mCurrentMagnificationSpec.remove(inputWindowHandle.displayId);
+                mMagnificationSpecInverseMatrix.remove(inputWindowHandle.displayId);
+                return;
+            }
+        } else {
+            generateInverseMatrix(previousMagnificationSpec,
+                    inverseMatrixForMagnificationSpec);
+        }
+
+        mMagnificationSpecInverseMatrix.put(inputWindowHandle.displayId,
+                inverseMatrixForMagnificationSpec);
+    }
+
+    /**
+     * Computes the identity matrix for generating the
+     * inverse matrix based on below formula under window is at the stable state:
+     * inputWindowHandle#transform * MagnificationSpecMatrix * WindowState#transform
+     * = IdentityMatrix
+     */
+    @GuardedBy("mLock")
+    private void computeIdentityMatrix(InputWindowHandle inputWindowHandle,
+            @NonNull MagnificationSpec magnificationSpec,
+            Matrix transformMatrix, float[] magnifyMatrixFloats) {
+        final Matrix specMatrix = mTempMatrix1;
+        transformMagnificationSpecToMatrix(magnificationSpec, specMatrix);
+
+        final Matrix resultMatrix = new Matrix(inputWindowHandle.transform);
+        resultMatrix.preConcat(specMatrix);
+        resultMatrix.preConcat(transformMatrix);
+
+        resultMatrix.getValues(magnifyMatrixFloats);
+    }
+
+    /**
+     * @return true if selecting the magnification spec one, otherwise selecting the
+     * magnification spec two.
+     */
+    @GuardedBy("mLock")
+    private boolean selectProperMagnificationSpecByComparingIdentityDegree(
+            float[] magnifyMatrixFloatsForSpecOne,
+            float[] magnifyMatrixFloatsForSpecTwo) {
+        final float[] IdentityMatrixValues = mTempFloat3;
+        Matrix.IDENTITY_MATRIX.getValues(IdentityMatrixValues);
+
+        final float scaleDiffForSpecOne = Math.abs(IdentityMatrixValues[Matrix.MSCALE_X]
+                - magnifyMatrixFloatsForSpecOne[Matrix.MSCALE_X]);
+        final float scaleDiffForSpecTwo = Math.abs(IdentityMatrixValues[Matrix.MSCALE_X]
+                - magnifyMatrixFloatsForSpecTwo[Matrix.MSCALE_X]);
+        final float offsetXDiffForSpecOne = Math.abs(IdentityMatrixValues[Matrix.MTRANS_X]
+                - magnifyMatrixFloatsForSpecOne[Matrix.MTRANS_X]);
+        final float offsetXDiffForSpecTwo = Math.abs(IdentityMatrixValues[Matrix.MTRANS_X]
+                - magnifyMatrixFloatsForSpecTwo[Matrix.MTRANS_X]);
+        final float offsetYDiffForSpecOne = Math.abs(IdentityMatrixValues[Matrix.MTRANS_Y]
+                - magnifyMatrixFloatsForSpecOne[Matrix.MTRANS_Y]);
+        final float offsetYDiffForSpecTwo = Math.abs(IdentityMatrixValues[Matrix.MTRANS_Y]
+                - magnifyMatrixFloatsForSpecTwo[Matrix.MTRANS_Y]);
+        final float offsetDiffForSpecOne = offsetXDiffForSpecOne
+                + offsetYDiffForSpecOne;
+        final float offsetDiffForSpecTwo = offsetXDiffForSpecTwo
+                + offsetYDiffForSpecTwo;
+
+        return Float.compare(scaleDiffForSpecTwo, scaleDiffForSpecOne) > 0
+                || (Float.compare(scaleDiffForSpecTwo, scaleDiffForSpecOne) == 0
+                && Float.compare(offsetDiffForSpecTwo, offsetDiffForSpecOne) > 0);
+    }
+
+    @GuardedBy("mLock")
+    private static void generateInverseMatrix(MagnificationSpec spec, Matrix outMatrix) {
+        outMatrix.reset();
+
+        final Matrix tempMatrix = new Matrix();
+        transformMagnificationSpecToMatrix(spec, tempMatrix);
+
+        final boolean result = tempMatrix.invert(outMatrix);
+        if (!result) {
+            Slog.e(TAG, "Can't inverse the magnification spec matrix with the "
+                    + "magnification spec = " + spec);
+            outMatrix.reset();
+        }
+    }
+
+    @GuardedBy("mLock")
+    private static void transformMagnificationSpecToMatrix(MagnificationSpec spec,
+            Matrix outMatrix) {
+        outMatrix.reset();
+        outMatrix.postScale(spec.scale, spec.scale);
+        outMatrix.postTranslate(spec.offsetX, spec.offsetY);
+    }
+
+    private void notifyWindowsChanged(@NonNull List<Integer> displayIdsForWindowsChanged) {
+        mHandler.removeMessages(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT);
+
+        for (int i = 0; i < displayIdsForWindowsChanged.size(); i++) {
+            mAccessibilityController.performComputeChangedWindowsNot(
+                    displayIdsForWindowsChanged.get(i), false);
+        }
+    }
+
+    private void forceUpdateWindows() {
+        final List<Integer> displayIdsForWindowsChanged = new ArrayList<>();
+
+        synchronized (mLock) {
+            for (int i = 0; i < mInputWindowHandlesOnDisplays.size(); i++) {
+                final int displayId = mInputWindowHandlesOnDisplays.keyAt(i);
+                displayIdsForWindowsChanged.add(displayId);
+            }
+        }
+        notifyWindowsChanged(displayIdsForWindowsChanged);
+    }
+
+    @GuardedBy("mLock")
+    private void releaseResources() {
+        mInputWindowHandlesOnDisplays.clear();
+        mMagnificationSpecInverseMatrix.clear();
+        mVisibleWindows.clear();
+        mDisplayInfos.clear();
+        mCurrentMagnificationSpec.clear();
+        mPreviousMagnificationSpec.clear();
+        mWindowsTransformMatrixMap.clear();
+        mWindowsNotificationEnabled = false;
+        mHandler.removeCallbacksAndMessages(null);
+    }
+
+    private class MyHandler extends Handler {
+        public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED = 1;
+        public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE = 2;
+        public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT = 3;
+
+        MyHandler(Looper looper) {
+            super(looper, null, false);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MESSAGE_NOTIFY_WINDOWS_CHANGED: {
+                    final List<Integer> displayIdsForWindowsChanged = (List<Integer>) message.obj;
+                    notifyWindowsChanged(displayIdsForWindowsChanged);
+                } break;
+
+                case MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE: {
+                    forceUpdateWindows();
+                } break;
+
+                case MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_TIMEOUT: {
+                    Slog.w(TAG, "Windows change within in 2 frames continuously over 500 ms "
+                            + "and notify windows changed immediately");
+                    mHandler.removeMessages(
+                            MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED_BY_UI_STABLE);
+
+                    forceUpdateWindows();
+                } break;
+            }
+        }
+    }
+
+    /**
+     * This class represents information about a window from the
+     * surface flinger to the accessibility framework.
+     */
+    public static class AccessibilityWindow {
+        private static final Region TEMP_REGION = new Region();
+        private static final RectF TEMP_RECTF = new RectF();
+        // Data
+        private IWindow mWindow;
+        private int mDisplayId;
+        private int mFlags;
+        private int mType;
+        private int mPrivateFlags;
+        private boolean mIsPIPMenu;
+        private boolean mIsFocused;
+        private boolean mShouldMagnify;
+        private boolean mIgnoreDuetoRecentsAnimation;
+        private boolean mIsTrustedOverlay;
+        private final Region mTouchableRegionInScreen = new Region();
+        private final Region mTouchableRegionInWindow = new Region();
+        private final Region mLetterBoxBounds = new Region();
+        private WindowInfo mWindowInfo;
+
+        /**
+         * Returns the instance after initializing the internal data.
+         * @param service The window manager service.
+         * @param inputWindowHandle The window from the surface flinger.
+         * @param inverseMatrix The magnification spec inverse matrix.
+         */
+        public static AccessibilityWindow initializeData(WindowManagerService service,
+                InputWindowHandle inputWindowHandle, Matrix inverseMatrix, IBinder pipIBinder,
+                Matrix displayMatrix) {
+            final IWindow window = inputWindowHandle.getWindow();
+            final WindowState windowState = window != null ? service.mWindowMap.get(
+                    window.asBinder()) : null;
+
+            final AccessibilityWindow instance = new AccessibilityWindow();
+
+            instance.mWindow = inputWindowHandle.getWindow();
+            instance.mDisplayId = inputWindowHandle.displayId;
+            instance.mFlags = inputWindowHandle.layoutParamsFlags;
+            instance.mType = inputWindowHandle.layoutParamsType;
+            instance.mIsPIPMenu = inputWindowHandle.getWindow().asBinder().equals(pipIBinder);
+
+            // TODO (b/199357848): gets the private flag of the window from other way.
+            instance.mPrivateFlags = windowState != null ? windowState.mAttrs.privateFlags : 0;
+            // TODO (b/199358208) : using new way to implement the focused window.
+            instance.mIsFocused = windowState != null && windowState.isFocused();
+            instance.mShouldMagnify = windowState == null || windowState.shouldMagnify();
+
+            final RecentsAnimationController controller = service.getRecentsAnimationController();
+            instance.mIgnoreDuetoRecentsAnimation = windowState != null && controller != null
+                    && controller.shouldIgnoreForAccessibility(windowState);
+            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()) {
+                getLetterBoxBounds(windowState, instance.mLetterBoxBounds);
+            }
+
+            final Rect windowFrame = new Rect(inputWindowHandle.frameLeft,
+                    inputWindowHandle.frameTop, inputWindowHandle.frameRight,
+                    inputWindowHandle.frameBottom);
+            getTouchableRegionInWindow(instance.mShouldMagnify, inputWindowHandle.touchableRegion,
+                    instance.mTouchableRegionInWindow, windowFrame, inverseMatrix, displayMatrix);
+            getUnMagnifiedTouchableRegion(instance.mShouldMagnify,
+                    inputWindowHandle.touchableRegion, instance.mTouchableRegionInScreen,
+                    inverseMatrix, displayMatrix);
+            instance.mWindowInfo = windowState != null
+                    ? windowState.getWindowInfo() : getWindowInfoForWindowlessWindows(instance);
+
+            return instance;
+        }
+
+        /**
+         * Returns the touchable region in the screen.
+         * @param outRegion The touchable region.
+         */
+        public void getTouchableRegionInScreen(Region outRegion) {
+            outRegion.set(mTouchableRegionInScreen);
+        }
+
+        /**
+         * Returns the touchable region in the window.
+         * @param outRegion The touchable region.
+         */
+        public void getTouchableRegionInWindow(Region outRegion) {
+            outRegion.set(mTouchableRegionInWindow);
+        }
+
+        /**
+         * @return the layout parameter flag {@link android.view.WindowManager.LayoutParams#flags}.
+         */
+        public int getFlags() {
+            return mFlags;
+        }
+
+        /**
+         * @return the layout parameter type {@link android.view.WindowManager.LayoutParams#type}.
+         */
+        public int getType() {
+            return mType;
+        }
+
+        /**
+         * @return the layout parameter private flag
+         * {@link android.view.WindowManager.LayoutParams#privateFlags}.
+         */
+        public int getPrivateFlag() {
+            return mPrivateFlags;
+        }
+
+        /**
+         * @return the windowInfo {@link WindowInfo}.
+         */
+        public WindowInfo getWindowInfo() {
+            return mWindowInfo;
+        }
+
+        /**
+         * Gets the letter box bounds if activity bounds are letterboxed
+         * or letterboxed for display cutout.
+         *
+         * @return {@code true} there's a letter box bounds.
+         */
+        public Boolean setLetterBoxBoundsIfNeeded(Region outBounds) {
+            if (mLetterBoxBounds.isEmpty()) {
+                return false;
+            }
+
+            outBounds.set(mLetterBoxBounds);
+            return true;
+        }
+
+        /**
+         * @return true if this window should be magnified.
+         */
+        public boolean shouldMagnify() {
+            return mShouldMagnify;
+        }
+
+        /**
+         * @return true if this window is focused.
+         */
+        public boolean isFocused() {
+            return mIsFocused;
+        }
+
+        /**
+         * @return true if it's running the recent animation but not the target app.
+         */
+        public boolean ignoreRecentsAnimationForAccessibility() {
+            return mIgnoreDuetoRecentsAnimation;
+        }
+
+        /**
+         * @return true if this window is the trusted overlay.
+         */
+        public boolean isTrustedOverlay() {
+            return mIsTrustedOverlay;
+        }
+
+        /**
+         * @return true if this window is the navigation bar with the gesture mode.
+         */
+        public boolean isUntouchableNavigationBar() {
+            if (mType != WindowManager.LayoutParams.TYPE_NAVIGATION_BAR) {
+                return false;
+            }
+
+            return mTouchableRegionInScreen.isEmpty();
+        }
+
+        /**
+         * @return true if this window is PIP menu.
+         */
+        public boolean isPIPMenu() {
+            return mIsPIPMenu;
+        }
+
+        private static void getTouchableRegionInWindow(boolean shouldMagnify, Region inRegion,
+                Region outRegion, Rect frame, Matrix inverseMatrix, Matrix displayMatrix) {
+            // Some modal windows, like the activity with Theme.dialog, has the full screen
+            // as its touchable region, but its window frame is smaller than the touchable
+            // region. The region we report should be the touchable area in the window frame
+            // for the consistency and match developers expectation.
+            // So we need to make the intersection between the frame and touchable region to
+            // obtain the real touch region in the screen.
+            Region touchRegion = TEMP_REGION;
+            touchRegion.set(inRegion);
+            touchRegion.op(frame, Region.Op.INTERSECT);
+
+            getUnMagnifiedTouchableRegion(shouldMagnify, touchRegion, outRegion, inverseMatrix,
+                    displayMatrix);
+        }
+
+        /**
+         * Gets the un-magnified touchable region. If this window can be magnified and magnifying,
+         * we will transform the input touchable region by applying the inverse matrix of the
+         * magnification spec to get the un-magnified touchable region.
+         * @param shouldMagnify The window can be magnified.
+         * @param inRegion The touchable region of this window.
+         * @param outRegion The un-magnified touchable region of this window.
+         * @param inverseMatrix The inverse matrix of the magnification spec.
+         * @param displayMatrix The display transform matrix which takes display coordinates to
+         *                      logical display coordinates.
+         */
+        private static void getUnMagnifiedTouchableRegion(boolean shouldMagnify, Region inRegion,
+                Region outRegion, Matrix inverseMatrix, Matrix displayMatrix) {
+            if ((!shouldMagnify || inverseMatrix.isIdentity()) && displayMatrix.isIdentity()) {
+                outRegion.set(inRegion);
+                return;
+            }
+
+            forEachRect(inRegion, rect -> {
+                // Move to origin as all transforms are captured by the matrix.
+                RectF windowFrame = TEMP_RECTF;
+                windowFrame.set(rect);
+
+                inverseMatrix.mapRect(windowFrame);
+                displayMatrix.mapRect(windowFrame);
+                // Union all rects.
+                outRegion.union(new Rect((int) windowFrame.left, (int) windowFrame.top,
+                        (int) windowFrame.right, (int) windowFrame.bottom));
+            });
+        }
+
+        private static WindowInfo getWindowInfoForWindowlessWindows(AccessibilityWindow window) {
+            WindowInfo windowInfo = WindowInfo.obtain();
+            windowInfo.displayId = window.mDisplayId;
+            windowInfo.type = window.mType;
+            windowInfo.token = window.mWindow.asBinder();
+            windowInfo.hasFlagWatchOutsideTouch = (window.mFlags
+                    & WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH) != 0;
+            windowInfo.inPictureInPicture = false;
+
+            // There only are two windowless windows now, one is split window, and the other
+            // one is PIP.
+            if (windowInfo.type == TYPE_DOCK_DIVIDER) {
+                windowInfo.title = "Splitscreen Divider";
+            } else if (window.mIsPIPMenu) {
+                windowInfo.title = "Picture-in-Picture menu";
+            }
+            return windowInfo;
+        }
+
+        private static void getLetterBoxBounds(WindowState windowState, Region outRegion) {
+            final Rect letterboxInsets = windowState.mActivityRecord.getLetterboxInsets();
+            final Rect nonLetterboxRect = windowState.getBounds();
+
+            nonLetterboxRect.inset(letterboxInsets);
+            outRegion.set(windowState.getBounds());
+            outRegion.op(nonLetterboxRect, Region.Op.DIFFERENCE);
+        }
+
+        @Override
+        public String toString() {
+            String builder = "A11yWindow=[" + mWindow.asBinder()
+                    + ", displayId=" + mDisplayId
+                    + ", flag=0x" + Integer.toHexString(mFlags)
+                    + ", type=" + mType
+                    + ", privateFlag=0x" + Integer.toHexString(mPrivateFlags)
+                    + ", focused=" + mIsFocused
+                    + ", shouldMagnify=" + mShouldMagnify
+                    + ", ignoreDuetoRecentsAnimation=" + mIgnoreDuetoRecentsAnimation
+                    + ", isTrustedOverlay=" + mIsTrustedOverlay
+                    + ", regionInScreen=" + mTouchableRegionInScreen
+                    + ", touchableRegion=" + mTouchableRegionInWindow
+                    + ", letterBoxBounds=" + mLetterBoxBounds
+                    + ", isPIPMenu=" + mIsPIPMenu
+                    + ", windowInfo=" + mWindowInfo
+                    + "]";
+
+            return builder;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
index 4df2e17..1d65cbb 100644
--- a/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
+++ b/services/core/java/com/android/server/wm/ActivityInterceptorCallback.java
@@ -43,9 +43,13 @@
     public abstract @Nullable ActivityInterceptResult intercept(ActivityInterceptorInfo info);
 
     /**
-     * Called when an activity is successfully launched.
+     * Called when an activity is successfully launched. The intent included in the
+     * ActivityInterceptorInfo may have changed from the one sent in
+     * {@link #intercept(ActivityInterceptorInfo)}, due to the return from
+     * {@link #intercept(ActivityInterceptorInfo)}.
      */
-    public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo) {
+    public void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo,
+            ActivityInterceptorInfo info) {
     }
 
     /**
@@ -54,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
     })
@@ -71,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/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index b0efa5b..1c93abd 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -44,8 +44,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.activityTypeToString;
-import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
 import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION;
 import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE;
 import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON;
@@ -148,6 +148,7 @@
 import static com.android.server.wm.ActivityRecordProto.APP_STOPPED;
 import static com.android.server.wm.ActivityRecordProto.CLIENT_VISIBLE;
 import static com.android.server.wm.ActivityRecordProto.DEFER_HIDING_CLIENT;
+import static com.android.server.wm.ActivityRecordProto.ENABLE_RECENTS_SCREENSHOT;
 import static com.android.server.wm.ActivityRecordProto.FILLS_PARENT;
 import static com.android.server.wm.ActivityRecordProto.FRONT_OF_TASK;
 import static com.android.server.wm.ActivityRecordProto.IN_SIZE_COMPAT_MODE;
@@ -277,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;
@@ -542,7 +544,7 @@
     final RootWindowContainer mRootWindowContainer;
 
     // Tracking splash screen status from previous activity
-    boolean mSplashScreenStyleEmpty = false;
+    boolean mSplashScreenStyleSolidColor = false;
 
     Drawable mEnterpriseThumbnailDrawable;
 
@@ -771,7 +773,7 @@
     // Last visibility state we reported to the app token.
     boolean reportedVisible;
 
-    boolean mEnablePreviewScreenshots = true;
+    boolean mEnableRecentsScreenshot = true;
 
     // Information about an application starting window if displayed.
     // Note: these are de-referenced before the starting window animates away.
@@ -781,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.
@@ -825,7 +831,7 @@
      */
     private static final int SPLASH_SCREEN_BEHAVIOR_DEFAULT = 0;
     /**
-     * The icon is shown unless the launching app specified SPLASH_SCREEN_STYLE_EMPTY.
+     * The icon is shown unless the launching app specified SPLASH_SCREEN_STYLE_SOLID_COLOR.
      *
      * @see android.R.attr#windowSplashScreenBehavior
      */
@@ -1547,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() {
@@ -2181,7 +2241,7 @@
     @VisibleForTesting
     boolean addStartingWindow(String pkg, int resolvedTheme, ActivityRecord from, boolean newTask,
             boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot,
-            boolean activityCreated, boolean useEmpty,
+            boolean activityCreated, boolean isSimple,
             boolean activityAllDrawn) {
         // If the display is frozen, we won't do anything until the actual window is
         // displayed so there is no reason to put in the starting window.
@@ -2217,7 +2277,7 @@
 
         final int typeParameter = StartingSurfaceController
                 .makeStartingWindowTypeParameter(newTask, taskSwitch, processRunning,
-                        allowTaskSnapshot, activityCreated, useEmpty, useLegacy, activityAllDrawn,
+                        allowTaskSnapshot, activityCreated, isSimple, useLegacy, activityAllDrawn,
                         type, packageName, mUserId);
 
         if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
@@ -2451,7 +2511,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();
             }
@@ -3246,7 +3307,8 @@
                 // the best capture timing (e.g. IME window capture),
                 // No need additional task capture while task is controlled by RecentsAnimation.
                 if (mAtmService.mWindowManager.mTaskSnapshotController != null
-                        && !task.isAnimatingByRecents()) {
+                        && !(task.isAnimatingByRecents()
+                                || mTransitionController.inRecentsTransition(task))) {
                     final ArraySet<Task> tasks = Sets.newArraySet(task);
                     mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks);
                     mAtmService.mWindowManager.mTaskSnapshotController
@@ -3640,6 +3702,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();
@@ -5083,10 +5159,9 @@
         }
 
         if (!visible) {
-            final InsetsControlTarget imeInputTarget = mDisplayContent.getImeTarget(
-                    DisplayContent.IME_TARGET_INPUT);
-            mLastImeShown = imeInputTarget != null && imeInputTarget.getWindow() != null
-                    && imeInputTarget.getWindow().mActivityRecord == this
+            final InputTarget imeInputTarget = mDisplayContent.getImeInputTarget();
+            mLastImeShown = imeInputTarget != null && imeInputTarget.getWindowState() != null
+                    && imeInputTarget.getWindowState().mActivityRecord == this
                     && mDisplayContent.mInputMethodWindow != null
                     && mDisplayContent.mInputMethodWindow.isVisible();
             mImeInsetsFrozenUntilStartInput = true;
@@ -5151,7 +5226,7 @@
      * See {@link Activity#setRecentsScreenshotEnabled}.
      */
     void setRecentsScreenshotEnabled(boolean enabled) {
-        mEnablePreviewScreenshots = enabled;
+        mEnableRecentsScreenshot = enabled;
     }
 
     /**
@@ -5163,7 +5238,7 @@
      *         screenshot.
      */
     boolean shouldUseAppThemeSnapshot() {
-        return !mEnablePreviewScreenshots || forAllWindows(WindowState::isSecureLocked,
+        return !mEnableRecentsScreenshot || forAllWindows(WindowState::isSecureLocked,
                 true /* topToBottom */);
     }
 
@@ -5427,6 +5502,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()) {
@@ -5436,6 +5516,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();
@@ -6136,7 +6235,7 @@
     void onFirstWindowDrawn(WindowState win) {
         firstWindowDrawn = true;
         // stop tracking
-        mSplashScreenStyleEmpty = true;
+        mSplashScreenStyleSolidColor = true;
 
         // We now have a good window to show, remove dead placeholders
         removeDeadWindows();
@@ -6171,7 +6270,7 @@
     void onStartingWindowDrawn() {
         boolean wasTaskVisible = false;
         if (task != null) {
-            mSplashScreenStyleEmpty = true;
+            mSplashScreenStyleSolidColor = true;
             wasTaskVisible = task.getHasBeenVisible();
             task.setHasBeenVisible(true);
         }
@@ -6186,6 +6285,10 @@
             // The pending transition state will be cleared after the transition is started, so
             // save the state for launching the client later (used by LaunchActivityItem).
             mStartingData.mIsTransitionForward = true;
+            // Ensure that the transition can run with the latest orientation.
+            if (this != mDisplayContent.getLastOrientationSource()) {
+                mDisplayContent.updateOrientation();
+            }
             mDisplayContent.executeAppTransition();
         }
     }
@@ -6641,10 +6744,10 @@
         }
         return false;
     }
-    private boolean shouldUseEmptySplashScreen(ActivityRecord sourceRecord, boolean startActivity,
-            ActivityOptions options, int resolvedTheme) {
+    private boolean shouldUseSolidColorSplashScreen(ActivityRecord sourceRecord,
+            boolean startActivity, ActivityOptions options, int resolvedTheme) {
         if (sourceRecord == null && !startActivity) {
-            // Use empty style if this activity is not top activity. This could happen when adding
+            // Use simple style if this activity is not top activity. This could happen when adding
             // a splash screen window to the warm start activity which is re-create because top is
             // finishing.
             final ActivityRecord above = task.getActivityAbove(this);
@@ -6656,7 +6759,7 @@
         // setSplashScreenStyle decide in priority of windowSplashScreenBehavior.
         if (options != null) {
             final int optionsStyle = options.getSplashScreenStyle();
-            if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_EMPTY) {
+            if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR) {
                 return true;
             } else if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_ICON
                     || isIconStylePreferred(resolvedTheme)) {
@@ -6677,11 +6780,11 @@
         }
 
         if (sourceRecord != null && !sourceRecord.isActivityTypeHome()) {
-            return sourceRecord.mSplashScreenStyleEmpty;
+            return sourceRecord.mSplashScreenStyleSolidColor;
         }
 
-        // If this activity was launched from Launcher or System for first start, never use an
-        // empty splash screen.
+        // If this activity was launched from Launcher or System for first start, never use a
+        // 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);
@@ -6747,7 +6850,7 @@
         final int resolvedTheme = evaluateStartingWindowTheme(prev, packageName, theme,
                 splashScreenTheme);
 
-        mSplashScreenStyleEmpty = shouldUseEmptySplashScreen(sourceRecord, startActivity,
+        mSplashScreenStyleSolidColor = shouldUseSolidColorSplashScreen(sourceRecord, startActivity,
                 startOptions, resolvedTheme);
 
         final boolean activityCreated =
@@ -6759,7 +6862,7 @@
 
         final boolean scheduled = addStartingWindow(packageName, resolvedTheme,
                 prev, newTask || newSingleActivity, taskSwitch, processRunning,
-                allowTaskSnapshot(), activityCreated, mSplashScreenStyleEmpty, allDrawn);
+                allowTaskSnapshot(), activityCreated, mSplashScreenStyleSolidColor, allDrawn);
         if (DEBUG_STARTING_WINDOW_VERBOSE && scheduled) {
             Slog.d(TAG, "Scheduled starting window for " + this);
         }
@@ -7509,8 +7612,7 @@
         final int parentWindowingMode =
                 newParentConfiguration.windowConfiguration.getWindowingMode();
         final boolean isFixedOrientationLetterboxAllowed =
-                isSplitScreenWindowingMode(parentWindowingMode)
-                        || parentWindowingMode == WINDOWING_MODE_MULTI_WINDOW
+                parentWindowingMode == WINDOWING_MODE_MULTI_WINDOW
                         || parentWindowingMode == WINDOWING_MODE_FULLSCREEN;
         // TODO(b/181207944): Consider removing the if condition and always run
         // resolveFixedOrientationConfiguration() since this should be applied for all cases.
@@ -8207,6 +8309,20 @@
 
     @Override
     public void onConfigurationChanged(Configuration newParentConfig) {
+        // We want to collect the ActivityRecord if the windowing mode is changed, so that it will
+        // dispatch app transition finished event correctly at the end.
+        // Check #isVisible() because we don't want to animate for activity that stays invisible.
+        // Activity with #isVisibleRequested() changed should be collected when that is requested.
+        if (mTransitionController.isShellTransitionsEnabled() && isVisible()
+                && isVisibleRequested()) {
+            final int projectedWindowingMode =
+                    getRequestedOverrideWindowingMode() == WINDOWING_MODE_UNDEFINED
+                            ? newParentConfig.windowConfiguration.getWindowingMode()
+                            : getRequestedOverrideWindowingMode();
+            if (getWindowingMode() != projectedWindowingMode) {
+                mTransitionController.collect(this);
+            }
+        }
         if (mCompatDisplayInsets != null) {
             Configuration overrideConfig = getRequestedOverrideConfiguration();
             // Adapt to changes in orientation locking. The app is still non-resizable, but
@@ -9184,6 +9300,7 @@
         // Only record if max bounds sandboxing is applied, if the caller has the necessary
         // permission to access the device configs.
         proto.write(PROVIDES_MAX_BOUNDS, providesMaxBounds());
+        proto.write(ENABLE_RECENTS_SCREENSHOT, mEnableRecentsScreenshot);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
index 316bf20..8622bd3 100644
--- a/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
+++ b/services/core/java/com/android/server/wm/ActivityRecordInputSink.java
@@ -16,13 +16,10 @@
 
 package com.android.server.wm;
 
-import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_APP_TRANSITION;
-import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
-import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
-
 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;
@@ -101,8 +98,7 @@
             mToken = inputChannel.getToken();
             mInputEventReceiver = createInputEventReceiver(inputChannel);
         }
-        if (mDisabled || !mIsCompatEnabled || mActivityRecord.isAnimating(TRANSITION | PARENTS,
-                ANIMATION_TYPE_APP_TRANSITION)) {
+        if (mDisabled || !mIsCompatEnabled || mActivityRecord.isInTransition()) {
             // TODO(b/208662670): Investigate if we can have feature active during animations.
             mInputWindowHandleWrapper.setToken(null);
         } else {
@@ -116,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;
     }
 
@@ -174,5 +169,4 @@
             finishInputEvent(event, true);
         }
     }
-
 }
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 2a26050..c9b8501 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -523,8 +523,8 @@
     }
 
     void registerRemoteAnimationForNextActivityStart(String packageName,
-            RemoteAnimationAdapter adapter) {
-        mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter);
+            RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
+        mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter, launchCookie);
     }
 
     PendingRemoteAnimationRegistry getPendingRemoteAnimationRegistry() {
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 658a17b..cdeb86c 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -188,10 +188,7 @@
         final SparseArray<ActivityInterceptorCallback> callbacks =
                 mService.getActivityInterceptorCallbacks();
         final ActivityInterceptorCallback.ActivityInterceptorInfo interceptorInfo =
-                new ActivityInterceptorCallback.ActivityInterceptorInfo(mRealCallingUid,
-                        mRealCallingPid, mUserId, mCallingPackage, mCallingFeatureId, mIntent,
-                        mRInfo, mAInfo, mResolvedType, mCallingPid, mCallingUid,
-                        mActivityOptions);
+                getInterceptorInfo();
 
         for (int i = 0; i < callbacks.size(); i++) {
             final ActivityInterceptorCallback callback = callbacks.valueAt(i);
@@ -358,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
@@ -412,9 +409,17 @@
     void onActivityLaunched(TaskInfo taskInfo, ActivityInfo activityInfo) {
         final SparseArray<ActivityInterceptorCallback> callbacks =
                 mService.getActivityInterceptorCallbacks();
+        ActivityInterceptorCallback.ActivityInterceptorInfo info = getInterceptorInfo();
         for (int i = 0; i < callbacks.size(); i++) {
             final ActivityInterceptorCallback callback = callbacks.valueAt(i);
-            callback.onActivityLaunched(taskInfo, activityInfo);
+            callback.onActivityLaunched(taskInfo, activityInfo, info);
         }
     }
+
+    private ActivityInterceptorCallback.ActivityInterceptorInfo getInterceptorInfo() {
+        return new ActivityInterceptorCallback.ActivityInterceptorInfo(mRealCallingUid,
+                mRealCallingPid, mUserId, mCallingPackage, mCallingFeatureId, mIntent,
+                mRInfo, mAInfo, mResolvedType, mCallingPid, mCallingUid,
+                mActivityOptions);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index ef0ee12..ac121a1 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -208,6 +208,9 @@
     private boolean mAvoidMoveToFront;
     private boolean mFrozeTaskList;
     private boolean mTransientLaunch;
+    // The task which was above the targetTask before starting this activity. null if the targetTask
+    // was already on top or if the activity is in a new task.
+    private Task mPriorAboveTask;
 
     // We must track when we deliver the new intent since multiple code paths invoke
     // {@link #deliverNewIntent}. This is due to early returns in the code path. This flag is used
@@ -1666,7 +1669,8 @@
                 if (isTransient) {
                     // `r` isn't guaranteed to be the actual relevant activity, so we must wait
                     // until after we launched to identify the relevant activity.
-                    transitionController.setTransientLaunch(mLastStartActivityRecord);
+                    transitionController.setTransientLaunch(mLastStartActivityRecord,
+                            mPriorAboveTask);
                 }
                 if (newTransition != null) {
                     transitionController.requestStartTransition(newTransition,
@@ -1785,6 +1789,10 @@
             return startResult;
         }
 
+        if (targetTask != null) {
+            mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask());
+        }
+
         final ActivityRecord targetTaskTop = newTask
                 ? null : targetTask.getTopNonFinishingActivity();
         if (targetTaskTop != null) {
@@ -1808,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)
@@ -1917,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) {
@@ -2196,8 +2205,9 @@
             // removed from calling performClearTaskLocked (For example, if it is being brought out
             // of history or if it is finished immediately), thus disassociating the task. Also note
             // that mReuseTask is reset as a result of {@link Task#performClearTaskLocked}
-            // launching another activity.
-            targetTask.performClearTaskLocked();
+            // launching another activity. Keep the task-overlay activity because the targetTask
+            // will be reused to launch new activity.
+            targetTask.performClearTaskForReuse(true /* excludingTaskOverlay*/);
             targetTask.setIntent(mStartActivity);
             mAddingToTask = true;
         } else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
@@ -2207,8 +2217,7 @@
             // In this situation we want to remove all activities from the task up to the one
             // being started. In most cases this means we are resetting the task to its initial
             // state.
-            final ActivityRecord top = targetTask.performClearTaskForReuseLocked(mStartActivity,
-                    mLaunchFlags);
+            final ActivityRecord top = targetTask.performClearTop(mStartActivity, mLaunchFlags);
 
             if (top != null) {
                 if (top.isRootOfTask()) {
@@ -2225,7 +2234,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);
@@ -2687,10 +2696,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();
             }
         }
 
@@ -2921,7 +2931,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) {
@@ -2930,7 +2940,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 25c4d20..01dfb91 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -471,7 +471,7 @@
     /** Dump the current activities state. */
     public abstract boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
             String[] args, int opti, boolean dumpAll, boolean dumpVisibleRootTasksOnly,
-            boolean dumpFocusedRootTaskOnly);
+            boolean dumpFocusedRootTaskOnly, @UserIdInt int userId);
 
     /** Dump the current state for inclusion in oom dump. */
     public abstract void dumpForOom(PrintWriter pw);
@@ -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 0497477..6d8b3b1d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2232,18 +2232,8 @@
      * Return true if callingUid is system, or packageName belongs to that callingUid.
      */
     private boolean isSameApp(int callingUid, @Nullable String packageName) {
-        try {
-            if (callingUid != 0 && callingUid != SYSTEM_UID) {
-                if (packageName == null) {
-                    return false;
-                }
-                final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
-                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
-                        UserHandle.getUserId(callingUid));
-                return UserHandle.isSameApp(callingUid, uid);
-            }
-        } catch (RemoteException e) {
-            // Should not happen
+        if (callingUid != 0 && callingUid != SYSTEM_UID) {
+            return mPmInternal.isSameApp(packageName, callingUid, UserHandle.getUserId(callingUid));
         }
         return true;
     }
@@ -3714,7 +3704,7 @@
 
     @Override
     public void registerRemoteAnimationForNextActivityStart(String packageName,
-            RemoteAnimationAdapter adapter) {
+            RemoteAnimationAdapter adapter, IBinder launchCookie) {
         mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
                 "registerRemoteAnimationForNextActivityStart");
         adapter.setCallingPidUid(Binder.getCallingPid(), Binder.getCallingUid());
@@ -3722,7 +3712,7 @@
             final long origId = Binder.clearCallingIdentity();
             try {
                 getActivityStartController().registerRemoteAnimationForNextActivityStart(
-                        packageName, adapter);
+                        packageName, adapter, launchCookie);
             } finally {
                 Binder.restoreCallingIdentity(origId);
             }
@@ -4062,12 +4052,12 @@
      */
     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
             int opti, boolean dumpAll, boolean dumpVisibleRootTasksOnly,
-            boolean dumpFocusedRootTaskOnly) {
+            boolean dumpFocusedRootTaskOnly, @UserIdInt int userId) {
         ArrayList<ActivityRecord> activities;
 
         synchronized (mGlobalLock) {
             activities = mRootWindowContainer.getDumpActivities(name, dumpVisibleRootTasksOnly,
-                    dumpFocusedRootTaskOnly);
+                    dumpFocusedRootTaskOnly, userId);
         }
 
         if (activities.size() <= 0) {
@@ -6410,9 +6400,9 @@
         @Override
         public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
                 String[] args, int opti, boolean dumpAll, boolean dumpVisibleRootTasksOnly,
-                boolean dumpFocusedRootTaskOnly) {
+                boolean dumpFocusedRootTaskOnly, @UserIdInt int userId) {
             return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti, dumpAll,
-                    dumpVisibleRootTasksOnly, dumpFocusedRootTaskOnly);
+                    dumpVisibleRootTasksOnly, dumpFocusedRootTaskOnly, userId);
         }
 
         @Override
@@ -6764,5 +6754,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 3d7dead..64f4261 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -954,7 +954,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 +1046,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 +1439,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
@@ -1605,7 +1608,7 @@
         task.mTransitionController.requestCloseTransitionIfNeeded(task);
         task.mInRemoveTask = true;
         try {
-            task.performClearTask(reason);
+            task.removeActivities(reason, false /* excludingTaskOverlay */);
             cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents);
             mService.getLockTaskController().clearLockedTask(task);
             mService.getTaskChangeNotificationController().notifyTaskStackChanged();
@@ -1693,7 +1696,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/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index 3d54b27..6befefd 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -21,6 +21,7 @@
 import static com.android.server.wm.ActivityRecord.INVALID_PID;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.annotation.NonNull;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.Process;
@@ -35,6 +36,7 @@
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.OptionalInt;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -75,7 +77,33 @@
         activity.inputDispatchingTimedOut(reason, INVALID_PID);
     }
 
-    void notifyWindowUnresponsive(IBinder inputToken, String reason) {
+
+    /**
+     * Notify a window was unresponsive.
+     *
+     * @param token - the input token of the window
+     * @param pid - the pid of the window, if known
+     * @param reason - the reason for the window being unresponsive
+     */
+    void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
+            @NonNull String reason) {
+        if (notifyWindowUnresponsive(token, reason)) {
+            return;
+        }
+        if (!pid.isPresent()) {
+            Slog.w(TAG_WM, "Failed to notify that window token=" + token + " was unresponsive.");
+            return;
+        }
+        notifyWindowUnresponsive(pid.getAsInt(), reason);
+    }
+
+    /**
+     * Notify a window identified by its input token was unresponsive.
+     *
+     * @return true if the window was identified by the given input token and the request was
+     *         handled, false otherwise.
+     */
+    private boolean notifyWindowUnresponsive(@NonNull IBinder inputToken, String reason) {
         preDumpIfLockTooSlow();
         final int pid;
         final boolean aboveSystem;
@@ -83,10 +111,8 @@
         synchronized (mService.mGlobalLock) {
             InputTarget target = mService.getInputTargetFromToken(inputToken);
             if (target == null) {
-                Slog.e(TAG_WM, "Unknown token, dropping notifyConnectionUnresponsive request");
-                return;
+                return false;
             }
-
             WindowState windowState = target.getWindowState();
             pid = target.getPid();
             // Blame the activity if the input token belongs to the window. If the target is
@@ -102,34 +128,63 @@
         } else {
             mService.mAmInternal.inputDispatchingTimedOut(pid, aboveSystem, reason);
         }
+        return true;
     }
 
-    void notifyWindowResponsive(IBinder inputToken) {
+    /**
+     * Notify a window owned by the provided pid was unresponsive.
+     */
+    private void notifyWindowUnresponsive(int pid, String reason) {
+        Slog.i(TAG_WM, "ANR in input window owned by pid=" + pid + ". Reason: " + reason);
+        dumpAnrStateLocked(null /* activity */, null /* windowState */, reason);
+
+        // We cannot determine the z-order of the window, so place the anr dialog as high
+        // as possible.
+        mService.mAmInternal.inputDispatchingTimedOut(pid, true /*aboveSystem*/, reason);
+    }
+
+    /**
+     * Notify a window was responsive after previously being unresponsive.
+     *
+     * @param token - the input token of the window
+     * @param pid - the pid of the window, if known
+     */
+    void notifyWindowResponsive(@NonNull IBinder token, @NonNull OptionalInt pid) {
+        if (notifyWindowResponsive(token)) {
+            return;
+        }
+        if (!pid.isPresent()) {
+            Slog.w(TAG_WM, "Failed to notify that window token=" + token + " was responsive.");
+            return;
+        }
+        notifyWindowResponsive(pid.getAsInt());
+    }
+
+    /**
+     * Notify a window identified by its input token was responsive after previously being
+     * unresponsive.
+     *
+     * @return true if the window was identified by the given input token and the request was
+     *         handled, false otherwise.
+     */
+    private boolean notifyWindowResponsive(@NonNull IBinder inputToken) {
         final int pid;
         synchronized (mService.mGlobalLock) {
             InputTarget target = mService.getInputTargetFromToken(inputToken);
             if (target == null) {
-                Slog.e(TAG_WM, "Unknown token, dropping notifyWindowConnectionResponsive request");
-                return;
+                return false;
             }
             pid = target.getPid();
         }
         mService.mAmInternal.inputDispatchingResumed(pid);
+        return true;
     }
 
-    void notifyGestureMonitorUnresponsive(int gestureMonitorPid, String reason) {
-        preDumpIfLockTooSlow();
-        synchronized (mService.mGlobalLock) {
-            Slog.i(TAG_WM, "ANR in gesture monitor owned by pid:" + gestureMonitorPid
-                    + ".  Reason: " + reason);
-            dumpAnrStateLocked(null /* activity */, null /* windowState */, reason);
-        }
-        mService.mAmInternal.inputDispatchingTimedOut(gestureMonitorPid, /* aboveSystem */ true,
-                reason);
-    }
-
-    void notifyGestureMonitorResponsive(int gestureMonitorPid) {
-        mService.mAmInternal.inputDispatchingResumed(gestureMonitorPid);
+    /**
+     * Notify a window owned by the provided pid was responsive after previously being unresponsive.
+     */
+    private void notifyWindowResponsive(int pid) {
+        mService.mAmInternal.inputDispatchingResumed(pid);
     }
 
     /**
@@ -228,12 +283,7 @@
         mService.mAtmService.saveANRState(reason);
     }
 
-    private boolean isWindowAboveSystem(WindowState windowState) {
-        if (windowState == null) {
-            // If the window state is not available we cannot easily determine its z order. Try to
-            // place the anr dialog as high as possible.
-            return true;
-        }
+    private boolean isWindowAboveSystem(@NonNull WindowState windowState) {
         int systemAlertLayer = mService.mPolicy.getWindowLayerFromTypeLw(
                 TYPE_APPLICATION_OVERLAY, windowState.mOwnerCanAddInternalSystemWindow);
         return windowState.mBaseLayer > systemAlertLayer;
diff --git a/services/core/java/com/android/server/wm/AsyncRotationController.java b/services/core/java/com/android/server/wm/AsyncRotationController.java
index 5c13e81..220d9ec 100644
--- a/services/core/java/com/android/server/wm/AsyncRotationController.java
+++ b/services/core/java/com/android/server/wm/AsyncRotationController.java
@@ -94,6 +94,9 @@
     /** Whether the start transaction of the transition is committed (by shell). */
     private boolean mIsStartTransactionCommitted;
 
+    /** Whether the target windows have been requested to sync their draw transactions. */
+    private boolean mIsSyncDrawRequested;
+
     private SeamlessRotator mRotator;
 
     private final int mOriginalRotation;
@@ -139,22 +142,10 @@
         displayContent.forAllWindows(this, true /* traverseTopToBottom */);
 
         // Legacy animation doesn't need to wait for the start transaction.
-        mIsStartTransactionCommitted = mTransitionOp == OP_LEGACY;
-        if (mIsStartTransactionCommitted) return;
-        // The transition sync group may be finished earlier because it doesn't wait for these
-        // target windows. But the windows still need to use sync transaction to keep the appearance
-        // in previous rotation, so request a no-op sync to keep the state.
-        for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
-            if (mHasScreenRotationAnimation
-                    && mTargetWindowTokens.valueAt(i).mAction == Operation.ACTION_FADE) {
-                // The windows are hidden (leash is alpha 0) before finishing drawing so it is
-                // unnecessary to request sync.
-                continue;
-            }
-            final WindowToken token = mTargetWindowTokens.keyAt(i);
-            for (int j = token.getChildCount() - 1; j >= 0; j--) {
-                token.getChildAt(j).applyWithNextDraw(t -> {});
-            }
+        if (mTransitionOp == OP_LEGACY) {
+            mIsStartTransactionCommitted = true;
+        } else if (displayContent.mTransitionController.useShellTransitionsRotation()) {
+            keepAppearanceInPreviousRotation();
         }
     }
 
@@ -194,6 +185,30 @@
         mTargetWindowTokens.put(w.mToken, new Operation(action));
     }
 
+    /**
+     * Enables {@link #handleFinishDrawing(WindowState, SurfaceControl.Transaction)} to capture the
+     * draw transactions of the target windows if needed.
+     */
+    void keepAppearanceInPreviousRotation() {
+        // The transition sync group may be finished earlier because it doesn't wait for these
+        // target windows. But the windows still need to use sync transaction to keep the appearance
+        // in previous rotation, so request a no-op sync to keep the state.
+        for (int i = mTargetWindowTokens.size() - 1; i >= 0; i--) {
+            if (mHasScreenRotationAnimation
+                    && mTargetWindowTokens.valueAt(i).mAction == Operation.ACTION_FADE) {
+                // The windows are hidden (leash is alpha 0) before finishing drawing so it is
+                // unnecessary to request sync.
+                continue;
+            }
+            final WindowToken token = mTargetWindowTokens.keyAt(i);
+            for (int j = token.getChildCount() - 1; j >= 0; j--) {
+                token.getChildAt(j).applyWithNextDraw(t -> {});
+            }
+        }
+        mIsSyncDrawRequested = true;
+        if (DEBUG) Slog.d(TAG, "Requested to sync draw transaction");
+    }
+
     /** Lets the window fit in new rotation naturally. */
     private void finishOp(WindowToken windowToken) {
         final Operation op = mTargetWindowTokens.remove(windowToken);
@@ -314,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. */
@@ -433,7 +452,7 @@
      */
     boolean handleFinishDrawing(WindowState w, SurfaceControl.Transaction postDrawTransaction) {
         if (mTransitionOp == OP_LEGACY || postDrawTransaction == null
-                || !w.mTransitionController.inTransition()) {
+                || !mIsSyncDrawRequested || !w.mTransitionController.inTransition()) {
             return false;
         }
         final Operation op = mTargetWindowTokens.get(w.mToken);
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 9893f68..23f14a7 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -53,7 +53,7 @@
      * Returns true if the back predictability feature is enabled
      */
     static boolean isEnabled() {
-        return SystemProperties.getInt(BACK_PREDICTABILITY_PROP, 1) > 0;
+        return SystemProperties.getInt(BACK_PREDICTABILITY_PROP, 0) > 0;
     }
 
     static boolean isScreenshotEnabled() {
@@ -98,20 +98,33 @@
         HardwareBuffer screenshotBuffer = null;
         int prevTaskId;
         int prevUserId;
-        IOnBackInvokedCallback applicationCallback = null;
-        IOnBackInvokedCallback systemCallback = null;
         RemoteAnimationTarget topAppTarget;
         SurfaceControl animLeash;
+        IOnBackInvokedCallback callback = null;
 
         synchronized (task.mWmService.mGlobalLock) {
-            activityRecord = task.topRunningActivity();
 
-            removedWindowContainer = activityRecord;
-            taskWindowConfiguration = task.getTaskInfo().configuration.windowConfiguration;
-            WindowState window = task.getWindow(WindowState::isFocused);
+            // TODO Temp workaround for Sysui until b/221071505 is fixed
+            WindowState window = task.mWmService.getFocusedWindowLocked();
+            if (window == null) {
+                activityRecord = task.topRunningActivity();
+                removedWindowContainer = activityRecord;
+                taskWindowConfiguration = task.getTaskInfo().configuration.windowConfiguration;
+                window = task.getWindow(WindowState::isFocused);
+            } else {
+                activityRecord = window.mActivityRecord;
+                removedWindowContainer = activityRecord;
+                taskWindowConfiguration = window.getWindowConfiguration();
+            }
+            IOnBackInvokedCallback applicationCallback = null;
+            IOnBackInvokedCallback systemCallback = null;
             if (window != null) {
                 applicationCallback = window.getApplicationOnBackInvokedCallback();
-                systemCallback = window.getSystemOnBackInvokedCallback();
+                callback = applicationCallback;
+                if (callback == null) {
+                    systemCallback = window.getSystemOnBackInvokedCallback();
+                    callback = systemCallback;
+                }
             }
 
             ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "startBackNavigation task=%s, "
@@ -119,16 +132,25 @@
                             + "systemBackCallback=%s",
                     task, activityRecord, applicationCallback, systemCallback);
 
+            // TODO Temp workaround for Sysui until b/221071505 is fixed
+            if (activityRecord == null && callback != null) {
+                return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
+                        null /* topWindowLeash */, null /* screenshotSurface */,
+                        null /* screenshotBuffer */, null /* taskWindowConfiguration */,
+                        null /* onBackNavigationDone */,
+                        callback /* 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 (task.getDisplayContent().getImeContainer().isVisible()
+            if (activityRecord == null || task.getDisplayContent().getImeContainer().isVisible()
                     || activityRecord.isActivityTypeHome()) {
-                if (applicationCallback != null) {
+                if (callback != null) {
                     return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
                             null /* topWindowLeash */, null /* screenshotSurface */,
                             null /* screenshotBuffer */, null /* taskWindowConfiguration */,
                             null /* onBackNavigationDone */,
-                            applicationCallback /* onBackInvokedCallback */);
+                            callback /* onBackInvokedCallback */);
                 } else {
                     return null;
                 }
@@ -137,12 +159,12 @@
             prev = task.getActivity(
                     (r) -> !r.finishing && r.getTask() == task && !r.isTopRunningActivity());
 
-            if (applicationCallback != null) {
+            if (callback != null) {
                 return new BackNavigationInfo(BackNavigationInfo.TYPE_CALLBACK,
                         null /* topWindowLeash */, null /* screenshotSurface */,
                         null /* screenshotBuffer */, null /* taskWindowConfiguration */,
                         null /* onBackNavigationDone */,
-                        applicationCallback /* onBackInvokedCallback */);
+                        callback /* onBackInvokedCallback */);
             } else if (prev != null) {
                 backType = BackNavigationInfo.TYPE_CROSS_ACTIVITY;
             } else if (task.returnsToHomeRootTask()) {
@@ -239,8 +261,6 @@
             return null;
         }
 
-        final IOnBackInvokedCallback callback =
-                applicationCallback != null ? applicationCallback : systemCallback;
         RemoteCallback onBackNavigationDone = new RemoteCallback(
                 result -> resetSurfaces(finalRemovedWindowContainer
                 ));
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index afa4f19..08a9da4 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -24,8 +24,6 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.activityTypeToString;
 import static android.app.WindowConfiguration.windowingModeToString;
 import static android.app.WindowConfigurationProto.WINDOWING_MODE;
@@ -475,33 +473,9 @@
         return WindowConfiguration.inMultiWindowMode(windowingMode);
     }
 
-    /** Returns true if this container is currently in split-screen windowing mode. */
-    public boolean inSplitScreenWindowingMode() {
-        /*@WindowConfiguration.WindowingMode*/ int windowingMode =
-                mFullConfiguration.windowConfiguration.getWindowingMode();
-
-        return windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-    }
-
-    /** Returns true if this container is currently in split-screen secondary windowing mode. */
-    public boolean inSplitScreenSecondaryWindowingMode() {
-        /*@WindowConfiguration.WindowingMode*/ int windowingMode =
-                mFullConfiguration.windowConfiguration.getWindowingMode();
-
-        return windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
-    }
-
-    public boolean inSplitScreenPrimaryWindowingMode() {
-        return mFullConfiguration.windowConfiguration.getWindowingMode()
-                == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-    }
-
     /**
-     * Returns true if this container can be put in either
-     * {@link WindowConfiguration#WINDOWING_MODE_SPLIT_SCREEN_PRIMARY} or
-     * {@link WindowConfiguration##WINDOWING_MODE_SPLIT_SCREEN_SECONDARY} windowing modes based on
-     * its current state.
+     * Returns true if this container supports split-screen multi-window and can be put in
+     * split-screen based on its current state.
      */
     public boolean supportsSplitScreenWindowingMode() {
         return mFullConfiguration.windowConfiguration.supportSplitScreenWindowingMode();
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
new file mode 100644
index 0000000..07a0c37
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -0,0 +1,368 @@
+/*
+ * 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 static android.view.ContentRecordingSession.RECORD_CONTENT_DISPLAY;
+
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONTENT_RECORDING;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.Configuration;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.view.ContentRecordingSession;
+import android.view.Display;
+import android.view.SurfaceControl;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
+
+/**
+ * Manages content recording for a particular {@link DisplayContent}.
+ */
+final class ContentRecorder {
+
+    /**
+     * The display content this class is handling recording for.
+     */
+    @NonNull
+    private final DisplayContent mDisplayContent;
+
+    /**
+     * The session for content recording, or null if this DisplayContent is not being used for
+     * recording.
+     */
+    @VisibleForTesting private ContentRecordingSession mContentRecordingSession = null;
+
+    /**
+     * The WindowContainer for the level of the hierarchy to record.
+     */
+    @Nullable private WindowContainer mRecordedWindowContainer = null;
+
+    /**
+     * The surface for recording the contents of this hierarchy, or null if content recording is
+     * temporarily disabled.
+     */
+    @Nullable private SurfaceControl mRecordedSurface = null;
+
+    /**
+     * The last bounds of the region to record.
+     */
+    @Nullable private Rect mLastRecordedBounds = null;
+
+    ContentRecorder(@NonNull DisplayContent displayContent) {
+        mDisplayContent = displayContent;
+    }
+
+    /**
+     * Sets the incoming recording session. Should only be used when starting to record on
+     * this display; stopping recording is handled separately when the display is destroyed.
+     *
+     * @param session the new session indicating recording will begin on this display.
+     */
+    void setContentRecordingSession(@Nullable ContentRecordingSession session) {
+        mContentRecordingSession = session;
+    }
+
+    /**
+     * Returns {@code true} if this DisplayContent is currently recording.
+     */
+    boolean isCurrentlyRecording() {
+        return mContentRecordingSession != null && mRecordedSurface != null;
+    }
+
+    /**
+     * Start recording if this DisplayContent no longer has content. Stop recording if it now
+     * has content or the display is not on.
+     */
+    @VisibleForTesting void updateRecording() {
+        if (isCurrentlyRecording() && (mDisplayContent.getLastHasContent()
+                || mDisplayContent.getDisplay().getState() == Display.STATE_OFF)) {
+            pauseRecording();
+        } else {
+            // Display no longer has content, or now has a surface to write to, so try to start
+            // recording.
+            startRecordingIfNeeded();
+        }
+    }
+
+    /**
+     * Handle a configuration change on the display content, and resize recording if needed.
+     * @param lastOrientation the prior orientation of the configuration
+     */
+    void onConfigurationChanged(@Configuration.Orientation int lastOrientation) {
+        // Update surface for MediaProjection, if this DisplayContent is being used for recording.
+        if (isCurrentlyRecording() && mLastRecordedBounds != null) {
+            // Recording has already begun, but update recording since the display is now on.
+            if (mRecordedWindowContainer == null) {
+                ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                        "Unexpectedly null window container; unable to update recording for "
+                                + "display %d",
+                        mDisplayContent.getDisplayId());
+                return;
+            }
+
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Display %d was already recording, so apply transformations if necessary",
+                    mDisplayContent.getDisplayId());
+            // Retrieve the size of the region to record, and continue with the update
+            // if the bounds or orientation has changed.
+            final Rect recordedContentBounds = mRecordedWindowContainer.getBounds();
+            int recordedContentOrientation = mRecordedWindowContainer.getOrientation();
+            if (!mLastRecordedBounds.equals(recordedContentBounds)
+                    || lastOrientation != recordedContentOrientation) {
+                Point surfaceSize = fetchSurfaceSizeIfPresent();
+                if (surfaceSize != null) {
+                    ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                            "Going ahead with updating recording for display %d to new "
+                                    + "bounds %s and/or orientation %d.",
+                            mDisplayContent.getDisplayId(), recordedContentBounds,
+                            recordedContentOrientation);
+                    updateMirroredSurface(mDisplayContent.mWmService.mTransactionFactory.get(),
+                            recordedContentBounds, surfaceSize);
+                } else {
+                    // If the surface removed, do nothing. We will handle this via onDisplayChanged
+                    // (the display will be off if the surface is removed).
+                    ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                            "Unable to update recording for display %d to new bounds %s"
+                                    + " and/or orientation %d, since the surface is not available.",
+                            mDisplayContent.getDisplayId(), recordedContentBounds,
+                            recordedContentOrientation);
+                }
+            }
+        }
+    }
+
+    /**
+     * Pauses recording on this display content. Note the session does not need to be updated,
+     * since recording can be resumed still.
+     */
+    void pauseRecording() {
+        if (mRecordedSurface == null) {
+            return;
+        }
+        ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                "Display %d has content (%b) so pause recording", mDisplayContent.getDisplayId(),
+                mDisplayContent.getLastHasContent());
+        // If the display is not on and it is a virtual display, then it no longer has an
+        // associated surface to write output to.
+        // If the display now has content, stop mirroring to it.
+        mDisplayContent.mWmService.mTransactionFactory.get()
+                // Remove the reference to mMirroredSurface, to clean up associated memory.
+                .remove(mRecordedSurface)
+                // Reparent the SurfaceControl of this DisplayContent back to mSurfaceControl,
+                // to allow content to be added to it. This allows this DisplayContent to stop
+                // mirroring and show content normally.
+                .reparent(mDisplayContent.getWindowingLayer(), mDisplayContent.getSurfaceControl())
+                .reparent(mDisplayContent.getOverlayLayer(), mDisplayContent.getSurfaceControl())
+                .apply();
+        // Pause mirroring by destroying the reference to the mirrored layer.
+        mRecordedSurface = null;
+        // Do not un-set the token, in case content is removed and recording should begin again.
+    }
+
+    /**
+     * Stops recording on this DisplayContent, and updates the session details.
+     */
+    void remove() {
+        if (mRecordedSurface != null) {
+            // Do not wait for the mirrored surface to be garbage collected, but clean up
+            // immediately.
+            mDisplayContent.mWmService.mTransactionFactory.get().remove(mRecordedSurface).apply();
+            mRecordedSurface = null;
+            clearContentRecordingSession();
+        }
+    }
+
+    /**
+     * Removes both the local cache and WM Service view of the current session, to stop the session
+     * on this display.
+     */
+    private void clearContentRecordingSession() {
+        // Update the cached session state first, since updating the service will result in always
+        // returning to this instance to update recording state.
+        mContentRecordingSession = null;
+        mDisplayContent.mWmService.setContentRecordingSession(null);
+    }
+
+    /**
+     * Start recording to this DisplayContent if it does not have its own content. Captures the
+     * content of a WindowContainer indicated by a WindowToken. If unable to start recording, falls
+     * back to original MediaProjection approach.
+     */
+    private void startRecordingIfNeeded() {
+        // Only record if this display does not have its own content, is not recording already,
+        // and if this display is on (it has a surface to write output to).
+        if (mDisplayContent.getLastHasContent() || isCurrentlyRecording()
+                || mDisplayContent.getDisplay().getState() == Display.STATE_OFF
+                || mContentRecordingSession == null) {
+            return;
+        }
+
+        final int contentToRecord = mContentRecordingSession.getContentToRecord();
+        if (contentToRecord != RECORD_CONTENT_DISPLAY) {
+            // TODO(b/216625226) handle task-based recording
+            // Not a valid region, or recording is disabled, so fall back to prior MediaProjection
+            // approach.
+            clearContentRecordingSession();
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Unable to start recording due to invalid region for display %d",
+                    mDisplayContent.getDisplayId());
+            return;
+        }
+        // Given the WindowToken of the DisplayArea to record, retrieve the associated
+        // SurfaceControl.
+        IBinder tokenToRecord = mContentRecordingSession.getTokenToRecord();
+        if (tokenToRecord == null) {
+            // Unexpectedly missing token. Fall back to prior MediaProjection approach.
+            clearContentRecordingSession();
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Unable to start recording due to null token for display %d",
+                    mDisplayContent.getDisplayId());
+            return;
+        }
+
+        final WindowContainer wc =
+                mDisplayContent.mWmService.mWindowContextListenerController.getContainer(
+                        tokenToRecord);
+        if (wc == null) {
+            // Un-set the window token to record for this VirtualDisplay. Fall back to the
+            // original MediaProjection approach.
+            mDisplayContent.mWmService.mDisplayManagerInternal.setWindowManagerMirroring(
+                    mDisplayContent.getDisplayId(), false);
+            clearContentRecordingSession();
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Unable to retrieve window container to start recording for "
+                            + "display %d",
+                    mDisplayContent.getDisplayId());
+            return;
+        }
+        // TODO(206461622) Migrate to using the RootDisplayArea
+        mRecordedWindowContainer = wc.getDisplayContent();
+
+        final Point surfaceSize = fetchSurfaceSizeIfPresent();
+        if (surfaceSize == null) {
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Unable to start recording for display %d since the surface is not "
+                            + "available.",
+                    mDisplayContent.getDisplayId());
+            return;
+        }
+        ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                "Display %d has no content and is on, so start recording for state %d",
+                mDisplayContent.getDisplayId(), mDisplayContent.getDisplay().getState());
+
+        // Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.
+        mRecordedSurface = SurfaceControl.mirrorSurface(
+                mRecordedWindowContainer.getSurfaceControl());
+        SurfaceControl.Transaction transaction =
+                mDisplayContent.mWmService.mTransactionFactory.get()
+                        // Set the mMirroredSurface's parent to the root SurfaceControl for this
+                        // DisplayContent. This brings the new mirrored hierarchy under this
+                        // DisplayContent,
+                        // so SurfaceControl will write the layers of this hierarchy to the
+                        // output surface
+                        // provided by the app.
+                        .reparent(mRecordedSurface, mDisplayContent.getSurfaceControl())
+                        // Reparent the SurfaceControl of this DisplayContent to null, to prevent
+                        // content
+                        // being added to it. This ensures that no app launched explicitly on the
+                        // VirtualDisplay will show up as part of the mirrored content.
+                        .reparent(mDisplayContent.getWindowingLayer(), null)
+                        .reparent(mDisplayContent.getOverlayLayer(), null);
+        // Retrieve the size of the DisplayArea to mirror.
+        updateMirroredSurface(transaction, mRecordedWindowContainer.getBounds(), surfaceSize);
+
+        // No need to clean up. In SurfaceFlinger, parents hold references to their children. The
+        // mirrored SurfaceControl is alive since the parent DisplayContent SurfaceControl is
+        // holding a reference to it. Therefore, the mirrored SurfaceControl will be cleaned up
+        // when the VirtualDisplay is destroyed - which will clean up this DisplayContent.
+    }
+
+    /**
+     * Apply transformations to the mirrored surface to ensure the captured contents are scaled to
+     * fit and centred in the output surface.
+     *
+     * @param transaction           the transaction to include transformations of mMirroredSurface
+     *                              to. Transaction is not applied before returning.
+     * @param recordedContentBounds bounds of the content to record to the surface provided by
+     *                              the app.
+     * @param surfaceSize           the default size of the surface to write the display area
+     *                              content to
+     */
+    @VisibleForTesting void updateMirroredSurface(SurfaceControl.Transaction transaction,
+            Rect recordedContentBounds, Point surfaceSize) {
+        // Calculate the scale to apply to the root mirror SurfaceControl to fit the size of the
+        // output surface.
+        float scaleX = surfaceSize.x / (float) recordedContentBounds.width();
+        float scaleY = surfaceSize.y / (float) recordedContentBounds.height();
+        float scale = Math.min(scaleX, scaleY);
+        int scaledWidth = Math.round(scale * (float) recordedContentBounds.width());
+        int scaledHeight = Math.round(scale * (float) recordedContentBounds.height());
+
+        // Calculate the shift to apply to the root mirror SurfaceControl to centre the mirrored
+        // contents in the output surface.
+        int shiftedX = 0;
+        if (scaledWidth != surfaceSize.x) {
+            shiftedX = (surfaceSize.x - scaledWidth) / 2;
+        }
+        int shiftedY = 0;
+        if (scaledHeight != surfaceSize.y) {
+            shiftedY = (surfaceSize.y - scaledHeight) / 2;
+        }
+
+        transaction
+                // Crop the area to capture to exclude the 'extra' wallpaper that is used
+                // for parallax (b/189930234).
+                .setWindowCrop(mRecordedSurface, recordedContentBounds.width(),
+                        recordedContentBounds.height())
+                // Scale the root mirror SurfaceControl, based upon the size difference between the
+                // source (DisplayArea to capture) and output (surface the app reads images from).
+                .setMatrix(mRecordedSurface, scale, 0 /* dtdx */, 0 /* dtdy */, scale)
+                // Position needs to be updated when the mirrored DisplayArea has changed, since
+                // the content will no longer be centered in the output surface.
+                .setPosition(mRecordedSurface, shiftedX /* x */, shiftedY /* y */)
+                .apply();
+        mLastRecordedBounds = new Rect(recordedContentBounds);
+    }
+
+    /**
+     * Returns a non-null {@link Point} if the surface is present, or null otherwise
+     */
+    private Point fetchSurfaceSizeIfPresent() {
+        // Retrieve the default size of the surface the app provided to
+        // MediaProjection#createVirtualDisplay. Note the app is the consumer of the surface,
+        // since it reads out buffers from the surface, and SurfaceFlinger is the producer since
+        // it writes the mirrored layers to the buffers.
+        Point surfaceSize =
+                mDisplayContent.mWmService.mDisplayManagerInternal.getDisplaySurfaceDefaultSize(
+                        mDisplayContent.getDisplayId());
+        if (surfaceSize == null) {
+            // Layer mirroring started with a null surface, so do not apply any transformations yet.
+            // State of virtual display will change to 'ON' when the surface is set.
+            // will get event DISPLAY_DEVICE_EVENT_CHANGED
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Provided surface for recording on display %d is not present, so do not"
+                            + " update the surface",
+                    mDisplayContent.getDisplayId());
+            return null;
+        }
+        return surfaceSize;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/ContentRecordingController.java b/services/core/java/com/android/server/wm/ContentRecordingController.java
new file mode 100644
index 0000000..fca4942
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ContentRecordingController.java
@@ -0,0 +1,94 @@
+/*
+ * 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 static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONTENT_RECORDING;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.view.ContentRecordingSession;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
+
+/**
+ * Orchestrates the handoff between displays if the recording session changes, and keeps track of
+ * the current recording session state. Only supports one content recording session on the device at
+ * once.
+ */
+final class ContentRecordingController {
+
+    /**
+     * The current recording session.
+     */
+    @Nullable
+    private ContentRecordingSession mSession = null;
+
+    @Nullable
+    private DisplayContent mDisplayContent = null;
+
+    /**
+     * Returns the current recording session. If returns {@code null}, then recording is not taking
+     * place.
+     */
+    @Nullable
+    @VisibleForTesting
+    ContentRecordingSession getContentRecordingSessionLocked() {
+        // Copy out the session, to allow it to be modified without updating this reference.
+        return mSession;
+    }
+
+    /**
+     * Updates the current recording session. If a new display is taking over recording, then
+     * stops the prior display from recording.
+     *
+     * @param incomingSession the new recording session. Should either be {@code null}, to stop
+     *                        the current session, or a session on a new/different display than the
+     *                        current session.
+     * @param wmService       the window manager service
+     */
+    void setContentRecordingSessionLocked(@Nullable ContentRecordingSession incomingSession,
+            @NonNull WindowManagerService wmService) {
+        if (incomingSession != null && (!ContentRecordingSession.isValid(incomingSession)
+                || ContentRecordingSession.isSameDisplay(mSession, incomingSession))) {
+            // Ignore an invalid session, or a session for the same display as currently recording.
+            return;
+        }
+        DisplayContent incomingDisplayContent = null;
+        if (incomingSession != null) {
+            // Recording will start on a new display, possibly taking over from a current session.
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Handle incoming session on display %d, with a pre-existing session %s",
+                    incomingSession.getDisplayId(),
+                    mSession == null ? null : mSession.getDisplayId());
+            incomingDisplayContent = wmService.mRoot.getDisplayContentOrCreate(
+                    incomingSession.getDisplayId());
+            incomingDisplayContent.setContentRecordingSession(incomingSession);
+        }
+        if (mSession != null) {
+            // Update the pre-existing display about the new session.
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Pause the recording session on display %s",
+                    mDisplayContent.getDisplayId());
+            mDisplayContent.pauseRecording();
+            mDisplayContent.setContentRecordingSession(null);
+        }
+        // Update the cached states.
+        mDisplayContent = incomingDisplayContent;
+        mSession = incomingSession;
+    }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 4c5c705..d1b9a78 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -26,7 +26,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -89,10 +88,10 @@
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_BOOT;
+import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONTENT_RECORDING;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
-import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LAYER_MIRRORING;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
@@ -132,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;
@@ -198,6 +198,7 @@
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.proto.ProtoOutputStream;
+import android.view.ContentRecordingSession;
 import android.view.Display;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
@@ -306,21 +307,11 @@
     private SurfaceControl mWindowingLayer;
 
     /**
-     * The window token of the layer of the hierarchy to mirror, or null if this DisplayContent
-     * is not being used for layer mirroring.
+     * Delegate for handling all logic around content recording; decides if this DisplayContent is
+     * recording, and if so, applies necessary updates to SurfaceFlinger.
      */
-    @VisibleForTesting IBinder mTokenToMirror = null;
-
-    /**
-     * The surface for mirroring the contents of this hierarchy, or null if layer mirroring is
-     * temporarily disabled.
-     */
-    private SurfaceControl mMirroredSurface = null;
-
-    /**
-     * The last bounds of the DisplayArea to mirror.
-     */
-    private Rect mLastMirroredDisplayAreaBounds = null;
+    @Nullable
+    private ContentRecorder mContentRecorder;
 
     /**
      * The default per Display minimal size of tasks. Calculated at construction.
@@ -424,6 +415,9 @@
     private final Region mSystemGestureExclusionUnrestricted = new Region();
     private int mSystemGestureExclusionLimit;
 
+    private Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>();
+    private Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>();
+
     /**
      * For default display it contains real metrics, empty for others.
      * @see WindowManagerService#createWatermark()
@@ -592,7 +586,15 @@
      * The window which receives input from the input method. This is also a candidate of the
      * input method control target.
      */
-    private WindowState mImeInputTarget;
+    private InputTarget mImeInputTarget;
+
+    /**
+     * The last ime input target processed from setImeLayeringTargetInner
+     * this is to ensure we update the control target in the case when the IME
+     * target changes while the IME layering target stays the same, for example
+     * the case of the IME moving to a SurfaceControlViewHost backed EmbeddedWindow
+     */
+    private InputTarget mLastImeInputTarget;
 
     /**
      * This controls the visibility and animation of the input method window.
@@ -608,14 +610,6 @@
     static final int IME_TARGET_LAYERING = 0;
 
     /**
-     * Used by {@link #getImeTarget} to return the IME target which received the input connection
-     * from IME.
-     *
-     * @see #mImeInputTarget
-     */
-    static final int IME_TARGET_INPUT = 1;
-
-    /**
      * Used by {@link #getImeTarget} to return the IME target which controls the IME insets
      * visibility and animation.
      *
@@ -625,7 +619,6 @@
 
     @IntDef(flag = false, prefix = { "IME_TARGET_" }, value = {
             IME_TARGET_LAYERING,
-            IME_TARGET_INPUT,
             IME_TARGET_CONTROL,
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -635,9 +628,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;
@@ -1642,18 +1632,12 @@
             // It has been set and not yet finished.
             return true;
         }
-        if (!r.occludesParent()) {
+        if (!r.occludesParent() || r.isReportedDrawn()) {
             // While entering or leaving a translucent or floating activity (e.g. dialog style),
             // there is a visible activity in the background. Then it still needs rotation animation
             // to cover the activity configuration change.
             return false;
         }
-        if (mTransitionController.isShellTransitionsEnabled()
-                ? mTransitionController.wasVisibleAtStart(r) : r.isVisible()) {
-            // If activity is already visible, then it's not "launching". However, shell-transitions
-            // will make it visible immediately.
-            return false;
-        }
         if (checkOpening) {
             if (mTransitionController.isShellTransitionsEnabled()) {
                 if (!mTransitionController.isCollecting(r)) {
@@ -1742,19 +1726,19 @@
     }
 
     void setFixedRotationLaunchingAppUnchecked(@Nullable ActivityRecord r, int rotation) {
-        final boolean useAsyncRotation = !mTransitionController.isShellTransitionsEnabled();
         if (mFixedRotationLaunchingApp == null && r != null) {
-            mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this,
-                    rotation);
-            if (useAsyncRotation) {
-                startAsyncRotation(
-                        // Delay the hide animation to avoid blinking by clicking navigation bar
-                        // that may toggle fixed rotation in a short time.
-                        r == mFixedRotationTransitionListener.mAnimatingRecents);
-            }
+            mWmService.mDisplayNotificationController.dispatchFixedRotationStarted(this, rotation);
+            // Delay the hide animation to avoid blinking by clicking navigation bar that may
+            // toggle fixed rotation in a short time.
+            final boolean shouldDebounce = r == mFixedRotationTransitionListener.mAnimatingRecents
+                    || mTransitionController.isTransientLaunch(r);
+            startAsyncRotation(shouldDebounce);
         } else if (mFixedRotationLaunchingApp != null && r == null) {
             mWmService.mDisplayNotificationController.dispatchFixedRotationFinished(this);
-            if (useAsyncRotation) finishAsyncRotationIfPossible();
+            // Keep async rotation controller if the next transition of display is requested.
+            if (!mTransitionController.isCollecting(this)) {
+                finishAsyncRotationIfPossible();
+            }
         }
         mFixedRotationLaunchingApp = r;
     }
@@ -1812,7 +1796,6 @@
         }
         // Update directly because the app which will change the orientation of display is ready.
         if (mDisplayRotation.updateOrientation(getOrientation(), false /* forceUpdate */)) {
-            mTransitionController.setSeamlessRotation(this);
             sendNewConfiguration();
             return;
         }
@@ -2544,46 +2527,9 @@
         // Update IME parent if needed.
         updateImeParent();
 
-        // Update mirroring surface for MediaProjection, if this DisplayContent is being used
-        // for layer mirroring.
-        if (isCurrentlyMirroring() && mLastMirroredDisplayAreaBounds != null) {
-            // Mirroring has already begun, but update mirroring since the display is now on.
-            final WindowContainer wc = mWmService.mWindowContextListenerController.getContainer(
-                    mTokenToMirror);
-            if (wc == null) {
-                ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                        "Unable to retrieve window container to update layer mirroring for "
-                                + "display %d",
-                        mDisplayId);
-                return;
-            }
-
-            ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                    "Display %d was already layer mirroring, so apply transformations if necessary",
-                    mDisplayId);
-            // Retrieve the size of the DisplayArea to mirror, and continue with the update
-            // if the bounds or orientation has changed.
-            final Rect displayAreaBounds = wc.getDisplayContent().getBounds();
-            int displayAreaOrientation = wc.getDisplayContent().getOrientation();
-            if (!mLastMirroredDisplayAreaBounds.equals(displayAreaBounds)
-                    || lastOrientation != displayAreaOrientation) {
-                Point surfaceSize = fetchSurfaceSizeIfPresent();
-                if (surfaceSize != null) {
-                    ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                            "Going ahead with updating layer mirroring for display %d to new "
-                                    + "bounds %s and/or orientation %d.",
-                            mDisplayId, displayAreaBounds, displayAreaOrientation);
-                    updateMirroredSurface(mWmService.mTransactionFactory.get(),
-                            displayAreaBounds, surfaceSize);
-                } else {
-                    // If the surface removed, do nothing. We will handle this via onDisplayChanged
-                    // (the display will be off if the surface is removed).
-                    ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                            "Unable to update layer mirroring for display %d to new bounds %s"
-                            + " and/or orientation %d, since the surface is not available.",
-                            mDisplayId, displayAreaBounds, displayAreaOrientation);
-                }
-            }
+        // Update surface for MediaProjection, if this DisplayContent is being used for recording.
+        if (mContentRecorder != null) {
+            mContentRecorder.onConfigurationChanged(lastOrientation);
         }
 
         if (lastOrientation != getConfiguration().orientation) {
@@ -3241,7 +3187,15 @@
                 this, this, null /* remoteTransition */, displayChange);
         if (t != null) {
             mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY);
-            if (isRotationChanging()) {
+            if (mFixedRotationLaunchingApp != null) {
+                // A fixed-rotation transition is done, then continue to start a seamless display
+                // transition. And be fore the start transaction is applied, the non-app windows
+                // need to keep in previous rotation to avoid showing inconsistent content.
+                t.setSeamlessRotation(this);
+                if (mAsyncRotationController != null) {
+                    mAsyncRotationController.keepAppearanceInPreviousRotation();
+                }
+            } else if (isRotationChanging()) {
                 mWmService.mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
                 controller.mTransitionMetricsReporter.associate(t,
                         startTime -> mWmService.mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN));
@@ -3314,7 +3268,7 @@
             mImeLayeringTarget.dumpDebug(proto, INPUT_METHOD_TARGET, logLevel);
         }
         if (mImeInputTarget != null) {
-            mImeInputTarget.dumpDebug(proto, INPUT_METHOD_INPUT_TARGET, logLevel);
+            mImeInputTarget.dumpProto(proto, INPUT_METHOD_INPUT_TARGET, logLevel);
         }
         if (mImeControlTarget != null
                 && mImeControlTarget.getWindow() != null) {
@@ -3398,7 +3352,7 @@
             pw.println(mSystemGestureExclusion);
         }
 
-        final List<Rect> keepClearAreas = getKeepClearAreas();
+        final Set<Rect> keepClearAreas = getKeepClearAreas();
         if (!keepClearAreas.isEmpty()) {
             pw.println();
             pw.print("  keepClearAreas=");
@@ -3877,7 +3831,7 @@
     }
 
     private boolean isImeControlledByApp() {
-        return mImeInputTarget != null && !mImeInputTarget.inMultiWindowMode();
+        return mImeInputTarget != null && mImeInputTarget.shouldControlIme();
     }
 
     boolean shouldImeAttachedToApp() {
@@ -3940,19 +3894,21 @@
      *
      * @param type The type of the IME target.
      * @see #IME_TARGET_LAYERING
-     * @see #IME_TARGET_INPUT
      * @see #IME_TARGET_CONTROL
      */
     InsetsControlTarget getImeTarget(@InputMethodTarget int type) {
         switch (type) {
             case IME_TARGET_LAYERING: return mImeLayeringTarget;
-            case IME_TARGET_INPUT: return mImeInputTarget;
             case IME_TARGET_CONTROL: return mImeControlTarget;
             default:
                 return null;
         }
     }
 
+    InputTarget getImeInputTarget() {
+        return mImeInputTarget;
+    }
+
     // IMPORTANT: When introducing new dependencies in this method, make sure that
     // changes to those result in RootWindowContainer.updateDisplayImePolicyCache()
     // being called.
@@ -4001,16 +3957,28 @@
      *               placed at its parent's surface.
      */
     private void setImeLayeringTargetInner(@Nullable WindowState target) {
-        if (target == mImeLayeringTarget) {
+        /**
+         * This function is also responsible for updating the IME control target
+         * and so in the case where the IME layering target does not change
+         * but the Input target does (for example, IME moving to a SurfaceControlViewHost
+         * we have to continue executing this function, otherwise there is no work
+         * to do.
+         */
+        if (target == mImeLayeringTarget && mLastImeInputTarget == mImeInputTarget) {
             return;
         }
+        mLastImeInputTarget = mImeInputTarget;
+
         // 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);
@@ -4045,9 +4013,9 @@
     }
 
     @VisibleForTesting
-    void setImeInputTarget(WindowState target) {
+    void setImeInputTarget(InputTarget target) {
         mImeInputTarget = target;
-        boolean canScreenshot = mImeInputTarget == null || !mImeInputTarget.isSecureLocked();
+        boolean canScreenshot = mImeInputTarget == null || mImeInputTarget.canScreenshotIme();
         if (mImeWindowsContainer.setCanScreenshot(canScreenshot)) {
             mWmService.requestTraversal();
         }
@@ -4058,8 +4026,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;
@@ -4068,61 +4145,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;
     }
 
     /**
@@ -4144,8 +4170,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();
         }
     }
@@ -4153,17 +4178,17 @@
     /** 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
      * which controls the visibility and animation of the input method window.
      */
-    void updateImeInputAndControlTarget(WindowState target) {
+    void updateImeInputAndControlTarget(InputTarget target) {
         if (mImeInputTarget != target) {
             ProtoLog.i(WM_DEBUG_IME, "setInputMethodInputTarget %s", target);
             setImeInputTarget(target);
@@ -4173,8 +4198,8 @@
         }
         // Unfreeze IME insets after the new target updated, in case updateAboveInsetsState may
         // deliver unrelated IME insets change to the non-IME requester.
-        if (target != null && target.mActivityRecord != null) {
-            target.mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
+        if (target != null) {
+            target.unfreezeInsetsAfterStartInput();
         }
     }
 
@@ -4232,11 +4257,11 @@
     InsetsControlTarget computeImeControlTarget() {
         if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null
                 || (mImeInputTarget != null
-                        && getImeHostOrFallback(mImeInputTarget.getWindow())
-                                == mRemoteInsetsControlTarget)) {
+                        && getImeHostOrFallback(mImeInputTarget.getWindowState())
+                               == mRemoteInsetsControlTarget)) {
             return mRemoteInsetsControlTarget;
         } else {
-            return mImeInputTarget;
+            return mImeInputTarget != null ? mImeInputTarget.getWindowState() : null;
         }
     }
 
@@ -4249,7 +4274,7 @@
         // screen. If it's not covering the entire screen the IME might extend beyond the apps
         // bounds.
         if (shouldImeAttachedToApp()) {
-            if (mImeLayeringTarget.mActivityRecord != mImeInputTarget.mActivityRecord) {
+            if (mImeLayeringTarget.mActivityRecord != mImeInputTarget.getActivityRecord()) {
                 // Do not change parent if the window hasn't requested IME.
                 return null;
             }
@@ -4466,7 +4491,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();
         }
     }
@@ -4553,8 +4580,8 @@
                     mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing,
                     true /* inTraversal, must call performTraversalInTrans... below */);
         }
-        // If the display now has content, or no longer has content, update layer mirroring.
-        updateMirroring();
+        // If the display now has content, or no longer has content, update recording.
+        updateRecording();
 
         final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible();
         if (wallpaperVisible != mLastWallpaperVisible) {
@@ -5009,6 +5036,10 @@
             final boolean canImeTargetSetRelativeLayer = imeTarget.getSurfaceControl() != null
                     && imeTarget.mToken == imeControlTargetToken
                     && !imeTarget.inMultiWindowMode()
+                    // We don't need to set relative layer if the IME target in non-multi-window
+                    // mode is the activity main window since updateImeParent will ensure the IME
+                    // surface be attached on the fullscreen activity.
+                    && imeTarget.mAttrs.type != TYPE_BASE_APPLICATION
                     && imeTarget.mToken.getActivity(app -> app.isAnimating(TRANSITION | PARENTS,
                             ANIMATION_TYPE_ALL & ~ANIMATION_TYPE_RECENTS)) == null;
             if (canImeTargetSetRelativeLayer) {
@@ -5485,11 +5516,17 @@
     }
 
     void updateKeepClearAreas() {
-        final List<Rect> restrictedKeepClearAreas = new ArrayList();
-        final List<Rect> unrestrictedKeepClearAreas = new ArrayList();
+        final Set<Rect> restrictedKeepClearAreas = new ArraySet<>();
+        final Set<Rect> unrestrictedKeepClearAreas = new ArraySet<>();
         getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas);
-        mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged(
-                this, restrictedKeepClearAreas, unrestrictedKeepClearAreas);
+
+        if (!mRestrictedKeepClearAreas.equals(restrictedKeepClearAreas)
+                || !mUnrestrictedKeepClearAreas.equals(unrestrictedKeepClearAreas)) {
+            mRestrictedKeepClearAreas = restrictedKeepClearAreas;
+            mUnrestrictedKeepClearAreas = unrestrictedKeepClearAreas;
+            mWmService.mDisplayNotificationController.dispatchKeepClearAreasChanged(
+                    this, restrictedKeepClearAreas, unrestrictedKeepClearAreas);
+        }
     }
 
     /**
@@ -5499,18 +5536,14 @@
      * display, which set unrestricted keep-clear areas.
      *
      * For context on restricted vs unrestricted keep-clear areas, see
-     * {@link android.Manifest.permission.USE_UNRESTRICTED_KEEP_CLEAR_AREAS}.
+     * {@link android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS}.
      */
-    void getKeepClearAreas(List<Rect> outRestricted, List<Rect> outUnrestricted) {
+    void getKeepClearAreas(Set<Rect> outRestricted, Set<Rect> outUnrestricted) {
         final Matrix tmpMatrix = new Matrix();
         final float[] tmpFloat9 = new float[9];
         forAllWindows(w -> {
             if (w.isVisible() && !w.inPinnedWindowingMode()) {
-                if (w.mSession.mSetsUnrestrictedKeepClearAreas) {
-                    outUnrestricted.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9));
-                } else {
-                    outRestricted.addAll(w.getKeepClearAreas(tmpMatrix, tmpFloat9));
-                }
+                w.getKeepClearAreas(outRestricted, outUnrestricted, tmpMatrix, tmpFloat9);
             }
 
             // We stop traversing when we reach the base of a fullscreen app.
@@ -5522,8 +5555,8 @@
     /**
      * Returns all keep-clear areas from visible, relevant windows on this display.
      */
-    ArrayList<Rect> getKeepClearAreas() {
-        final ArrayList<Rect> keepClearAreas = new ArrayList<Rect>();
+    Set<Rect> getKeepClearAreas() {
+        final Set<Rect> keepClearAreas = new ArraySet<>();
         getKeepClearAreas(keepClearAreas, keepClearAreas);
         return keepClearAreas;
     }
@@ -5548,13 +5581,13 @@
             } else if (displayState == Display.STATE_ON) {
                 mOffTokenAcquirer.release(mDisplayId);
             }
-            ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                    "Display %d state is now (%d), so update layer mirroring?",
+            ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+                    "Display %d state is now (%d), so update recording?",
                     mDisplayId, displayState);
             if (lastDisplayState != displayState) {
-                // If state is on due to surface being added, then start layer mirroring.
-                // If state is off due to surface being removed, then stop layer mirroring.
-                updateMirroring();
+                // If state is on due to surface being added, then start recording.
+                // If state is off due to surface being removed, then stop recording.
+                updateRecording();
             }
         }
         // Dispatch pending Configuration to WindowContext if the associated display changes to
@@ -5568,13 +5601,12 @@
     }
 
     static boolean alwaysCreateRootTask(int windowingMode, int activityType) {
-        // Always create a root task for fullscreen, freeform, and split-screen-secondary windowing
+        // Always create a root task for fullscreen, freeform, and multi windowing
         // modes so that we can manage visual ordering and return types correctly.
         return activityType == ACTIVITY_TYPE_STANDARD
                 && (windowingMode == WINDOWING_MODE_FULLSCREEN
                 || windowingMode == WINDOWING_MODE_FREEFORM
                 || windowingMode == WINDOWING_MODE_PINNED
-                || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
                 || windowingMode == WINDOWING_MODE_MULTI_WINDOW);
     }
 
@@ -5858,11 +5890,8 @@
         }
         mRemoved = true;
 
-        if (mMirroredSurface != null) {
-            // Do not wait for the mirrored surface to be garbage collected, but clean up
-            // immediately.
-            mWmService.mTransactionFactory.get().remove(mMirroredSurface).apply();
-            mMirroredSurface = null;
+        if (mContentRecorder != null) {
+            mContentRecorder.remove();
         }
 
         // Only update focus/visibility for the last one because there may be many root tasks are
@@ -6102,183 +6131,45 @@
         return mSandboxDisplayApis;
     }
 
-    /**
-     * Start mirroring to this DisplayContent if it does not have its own content. Captures the
-     * content of a WindowContainer indicated by a WindowToken. If unable to start mirroring, falls
-     * back to original MediaProjection approach.
-     */
-    private void startMirrorIfNeeded() {
-        // Only mirror if this display does not have its own content, is not mirroring already,
-        // and if this display is on (it has a surface to write output to).
-        if (mLastHasContent || isCurrentlyMirroring() || mDisplay.getState() == Display.STATE_OFF) {
-            return;
+    private ContentRecorder getContentRecorder() {
+        if (mContentRecorder == null) {
+            mContentRecorder = new ContentRecorder(this);
         }
-
-        // Given the WindowToken of the DisplayArea to mirror, retrieve the associated
-        // SurfaceControl.
-        IBinder tokenToMirror = mWmService.mDisplayManagerInternal.getWindowTokenClientToMirror(
-                mDisplayId);
-        if (tokenToMirror == null) {
-            // This DisplayContent instance is not involved in layer mirroring. If the display
-            // has been created for capturing, fall back to prior MediaProjection approach.
-            return;
-        }
-
-        final WindowContainer wc = mWmService.mWindowContextListenerController.getContainer(
-                tokenToMirror);
-        if (wc == null) {
-            // Un-set the window token to mirror for this VirtualDisplay, to fall back to the
-            // original MediaProjection approach.
-            mWmService.mDisplayManagerInternal.setWindowTokenClientToMirror(mDisplayId, null);
-            ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                    "Unable to retrieve window container to start layer mirroring for display %d",
-                    mDisplayId);
-            return;
-        }
-
-        Point surfaceSize = fetchSurfaceSizeIfPresent();
-        if (surfaceSize == null) {
-            ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                    "Unable to start layer mirroring for display %d since the surface is not "
-                            + "available.",
-                    mDisplayId);
-            return;
-        }
-        ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                "Display %d has no content and is on, so start layer mirroring for state %d",
-                mDisplayId, mDisplay.getState());
-
-        // Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.
-        SurfaceControl sc = wc.getDisplayContent().getSurfaceControl();
-        mMirroredSurface = SurfaceControl.mirrorSurface(sc);
-        SurfaceControl.Transaction transaction = mWmService.mTransactionFactory.get()
-                // Set the mMirroredSurface's parent to the root SurfaceControl for this
-                // DisplayContent. This brings the new mirrored hierarchy under this DisplayContent,
-                // so SurfaceControl will write the layers of this hierarchy to the output surface
-                // provided by the app.
-                .reparent(mMirroredSurface, mSurfaceControl)
-                // Reparent the SurfaceControl of this DisplayContent to null, to prevent content
-                // being added to it. This ensures that no app launched explicitly on the
-                // VirtualDisplay will show up as part of the mirrored content.
-                .reparent(mWindowingLayer, null)
-                .reparent(mOverlayLayer, null);
-        // Retrieve the size of the DisplayArea to mirror.
-        updateMirroredSurface(transaction, wc.getDisplayContent().getBounds(), surfaceSize);
-        mTokenToMirror = tokenToMirror;
-
-        // No need to clean up. In SurfaceFlinger, parents hold references to their children. The
-        // mirrored SurfaceControl is alive since the parent DisplayContent SurfaceControl is
-        // holding a reference to it. Therefore, the mirrored SurfaceControl will be cleaned up
-        // when the VirtualDisplay is destroyed - which will clean up this DisplayContent.
+        return mContentRecorder;
     }
 
     /**
-     * Start mirroring if this DisplayContent no longer has content. Stop mirroring if it now
+     * Pause the recording session.
+     */
+    @VisibleForTesting void pauseRecording() {
+        if (mContentRecorder != null) {
+            mContentRecorder.pauseRecording();
+        }
+    }
+
+    /**
+     * Sets the incoming recording session. Should only be used when starting to record on
+     * this display; stopping recording is handled separately when the display is destroyed.
+     *
+     * @param session the new session indicating recording will begin on this display.
+     */
+    void setContentRecordingSession(@Nullable ContentRecordingSession session) {
+        getContentRecorder().setContentRecordingSession(session);
+    }
+
+    /**
+     * Start recording if this DisplayContent no longer has content. Stop recording if it now
      * has content or the display is not on.
      */
-    private void updateMirroring() {
-        if (isCurrentlyMirroring() && (mLastHasContent
-                || mDisplay.getState() == Display.STATE_OFF)) {
-            ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                    "Display %d has content (%b) so disable layer mirroring", mDisplayId,
-                    mLastHasContent);
-            // If the display is not on and it is a virtual display, then it no longer has an
-            // associated surface to write output to.
-            // If the display now has content, stop mirroring to it.
-            mWmService.mTransactionFactory.get()
-                    // Remove the reference to mMirroredSurface, to clean up associated memory.
-                    .remove(mMirroredSurface)
-                    // Reparent the SurfaceControl of this DisplayContent back to mSurfaceControl,
-                    // to allow content to be added to it. This allows this DisplayContent to stop
-                    // mirroring and show content normally.
-                    .reparent(mWindowingLayer, mSurfaceControl)
-                    .reparent(mOverlayLayer, mSurfaceControl)
-                    .apply();
-            // Stop mirroring by destroying the reference to the mirrored layer.
-            mMirroredSurface = null;
-            // Do not un-set the token, in case content is removed and mirroring should begin again.
-        } else {
-            // Display no longer has content, or now has a surface to write to, so try to start
-            // mirroring to it.
-            startMirrorIfNeeded();
-        }
+    @VisibleForTesting void updateRecording() {
+        getContentRecorder().updateRecording();
     }
 
     /**
-     * Apply transformations to the mirrored surface to ensure the captured contents are scaled to
-     * fit and centred in the output surface.
-     *
-     * @param transaction       the transaction to include transformations of mMirroredSurface
-     *                          to. Transaction is not applied before returning.
-     * @param displayAreaBounds bounds of the DisplayArea to mirror to the surface provided by
-     *                          the app.
-     * @param surfaceSize       the default size of the surface to write the display area content to
+     * Returns {@code true} if this DisplayContent is currently recording.
      */
-    @VisibleForTesting
-    void updateMirroredSurface(SurfaceControl.Transaction transaction,
-            Rect displayAreaBounds, Point surfaceSize) {
-        // Calculate the scale to apply to the root mirror SurfaceControl to fit the size of the
-        // output surface.
-        float scaleX = surfaceSize.x / (float) displayAreaBounds.width();
-        float scaleY = surfaceSize.y / (float) displayAreaBounds.height();
-        float scale = Math.min(scaleX, scaleY);
-        int scaledWidth = Math.round(scale * (float) displayAreaBounds.width());
-        int scaledHeight = Math.round(scale * (float) displayAreaBounds.height());
-
-        // Calculate the shift to apply to the root mirror SurfaceControl to centre the mirrored
-        // contents in the output surface.
-        int shiftedX = 0;
-        if (scaledWidth != surfaceSize.x) {
-            shiftedX = (surfaceSize.x - scaledWidth) / 2;
-        }
-        int shiftedY = 0;
-        if (scaledHeight != surfaceSize.y) {
-            shiftedY = (surfaceSize.y - scaledHeight) / 2;
-        }
-
-        transaction
-                // Crop the area to capture to exclude the 'extra' wallpaper that is used
-                // for parallax (b/189930234).
-                .setWindowCrop(mMirroredSurface, displayAreaBounds.width(),
-                        displayAreaBounds.height())
-                // Scale the root mirror SurfaceControl, based upon the size difference between the
-                // source (DisplayArea to capture) and output (surface the app reads images from).
-                .setMatrix(mMirroredSurface, scale, 0 /* dtdx */, 0 /* dtdy */, scale)
-                // Position needs to be updated when the mirrored DisplayArea has changed, since
-                // the content will no longer be centered in the output surface.
-                .setPosition(mMirroredSurface, shiftedX /* x */, shiftedY /* y */)
-                .apply();
-        mLastMirroredDisplayAreaBounds = new Rect(displayAreaBounds);
-    }
-
-    /**
-     * Returns a non-null {@link Point} if the surface is present, or null otherwise
-     */
-    Point fetchSurfaceSizeIfPresent() {
-        // Retrieve the default size of the surface the app provided to
-        // MediaProjection#createVirtualDisplay. Note the app is the consumer of the surface,
-        // since it reads out buffers from the surface, and SurfaceFlinger is the producer since
-        // it writes the mirrored layers to the buffers.
-        Point surfaceSize = mWmService.mDisplayManagerInternal.getDisplaySurfaceDefaultSize(
-                mDisplayId);
-        if (surfaceSize == null) {
-            // Layer mirroring started with a null surface, so do not apply any transformations yet.
-            // State of virtual display will change to 'ON' when the surface is set.
-            // will get event DISPLAY_DEVICE_EVENT_CHANGED
-            ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
-                    "Provided surface for layer mirroring on display %d is not present, so do not"
-                            + " update the surface",
-                    mDisplayId);
-            return null;
-        }
-        return surfaceSize;
-    }
-
-    /**
-     * Returns {@code true} if this DisplayContent is currently layer mirroring.
-     */
-    boolean isCurrentlyMirroring() {
-        return mTokenToMirror != null && mMirroredSurface != null;
+    boolean isCurrentlyRecording() {
+        return mContentRecorder != null && mContentRecorder.isCurrentlyRecording();
     }
 
     /** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */
@@ -6353,13 +6244,25 @@
         }
 
         /**
-         * Return {@code true} if there is an ongoing animation to the "Recents" activity and this
-         * activity as a fixed orientation so shouldn't be rotated.
+         * Returns {@code true} if the transient launch (e.g. recents animation) requested a fixed
+         * orientation, then the rotation change should be deferred.
          */
-        boolean isTopFixedOrientationRecentsAnimating() {
-            return mAnimatingRecents != null
-                    && mAnimatingRecents.getRequestedConfigurationOrientation(true /* forDisplay */)
-                    != ORIENTATION_UNDEFINED && !hasTopFixedRotationLaunchingApp();
+        boolean shouldDeferRotation() {
+            ActivityRecord source = null;
+            if (mTransitionController.isShellTransitionsEnabled()) {
+                final ActivityRecord r = mFixedRotationLaunchingApp;
+                if (r != null && mTransitionController.isTransientLaunch(r)) {
+                    source = r;
+                }
+            } else if (mAnimatingRecents != null && !hasTopFixedRotationLaunchingApp()) {
+                source = mAnimatingRecents;
+            }
+            if (source == null || source.getRequestedConfigurationOrientation(
+                    true /* forDisplay */) == ORIENTATION_UNDEFINED) {
+                return false;
+            }
+            // If screen is off or the device is going to sleep, then still allow to update.
+            return mWmService.mPolicy.okToAnimate(false /* ignoreScreenOn */);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 6438d79..262ddae 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -419,11 +419,8 @@
      *         THE SCREEN.
      */
     boolean updateRotationUnchecked(boolean forceUpdate) {
-        final boolean useShellTransitions =
-                mDisplayContent.mTransitionController.isShellTransitionsEnabled();
-
         final int displayId = mDisplayContent.getDisplayId();
-        if (!forceUpdate && !useShellTransitions) {
+        if (!forceUpdate) {
             if (mDeferredRotationPauseCount > 0) {
                 // Rotation updates have been paused temporarily. Defer the update until updates
                 // have been resumed.
@@ -449,17 +446,14 @@
                 return false;
             }
 
-            final RecentsAnimationController recentsAnimController =
-                    mService.getRecentsAnimationController();
-            if (recentsAnimController != null && mDisplayContent.mFixedRotationTransitionListener
-                    .isTopFixedOrientationRecentsAnimating()
-                    // If screen is off or the device is going to sleep, then still allow to update.
-                    && mService.mPolicy.okToAnimate(false /* ignoreScreenOn */)) {
+            if (mDisplayContent.mFixedRotationTransitionListener.shouldDeferRotation()) {
+                // Makes sure that after the transition is finished, updateOrientation() can see
+                // the difference from the latest orientation source.
+                mLastOrientation = SCREEN_ORIENTATION_UNSET;
                 // During the recents animation, the closing app might still be considered on top.
                 // In order to ignore its requested orientation to avoid a sensor led rotation (e.g
                 // user rotating the device while the recents animation is running), we ignore
                 // rotation update while the animation is running.
-                recentsAnimController.setCheckRotationAfterCleanup();
                 return false;
             }
         }
@@ -513,7 +507,7 @@
 
         mDisplayContent.setLayoutNeeded();
 
-        if (useShellTransitions) {
+        if (mDisplayContent.mTransitionController.isShellTransitionsEnabled()) {
             final boolean wasCollecting = mDisplayContent.mTransitionController.isCollecting();
             final TransitionRequestInfo.DisplayChange change = wasCollecting ? null
                     : new TransitionRequestInfo.DisplayChange(mDisplayContent.getDisplayId(),
diff --git a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
index e18d539..fa7a99d 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowListenerController.java
@@ -23,7 +23,8 @@
 import android.util.IntArray;
 import android.view.IDisplayWindowListener;
 
-import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
 
 /**
  * Manages dispatch of relevant hierarchy changes to interested listeners. Listeners are assumed
@@ -120,13 +121,13 @@
         mDisplayListeners.finishBroadcast();
     }
 
-    void dispatchKeepClearAreasChanged(DisplayContent display, List<Rect> restricted,
-            List<Rect> unrestricted) {
+    void dispatchKeepClearAreasChanged(DisplayContent display, Set<Rect> restricted,
+            Set<Rect> unrestricted) {
         int count = mDisplayListeners.beginBroadcast();
         for (int i = 0; i < count; ++i) {
             try {
-                mDisplayListeners.getBroadcastItem(i).onKeepClearAreasChanged(
-                        display.mDisplayId, restricted, unrestricted);
+                mDisplayListeners.getBroadcastItem(i).onKeepClearAreasChanged(display.mDisplayId,
+                        new ArrayList<>(restricted), new ArrayList<>(unrestricted));
             } catch (RemoteException e) {
             }
         }
diff --git a/services/core/java/com/android/server/wm/DragResizeMode.java b/services/core/java/com/android/server/wm/DragResizeMode.java
index d754fd8..684cf06 100644
--- a/services/core/java/com/android/server/wm/DragResizeMode.java
+++ b/services/core/java/com/android/server/wm/DragResizeMode.java
@@ -40,8 +40,6 @@
         switch (mode) {
             case DRAG_RESIZE_MODE_FREEFORM:
                 return rootTask.getWindowingMode() == WINDOWING_MODE_FREEFORM;
-            case DRAG_RESIZE_MODE_DOCKED_DIVIDER:
-                return rootTask.inSplitScreenWindowingMode();
             default:
                 return false;
         }
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/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 2ab08e6..dcc16eb 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -17,6 +17,9 @@
 package com.android.server.wm;
 
 
+import static com.android.server.wm.IdentifierProto.HASH_CODE;
+import static com.android.server.wm.IdentifierProto.TITLE;
+import static com.android.server.wm.WindowContainerProto.IDENTIFIER;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -25,6 +28,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.ArrayMap;
+import android.util.proto.ProtoOutputStream;
 import android.util.Slog;
 import android.view.IWindow;
 import android.view.InputApplicationHandle;
@@ -43,6 +47,8 @@
     private ArrayMap<IBinder /*input token */, EmbeddedWindow> mWindows = new ArrayMap<>();
     private ArrayMap<IBinder /*focus grant token */, EmbeddedWindow> mWindowsByFocusToken =
         new ArrayMap<>();
+    private ArrayMap<IBinder /*window token*/, EmbeddedWindow> mWindowsByWindowToken =
+        new ArrayMap<>();
     private final Object mGlobalLock;
     private final ActivityTaskManagerService mAtmService;
 
@@ -63,6 +69,7 @@
             mWindows.put(inputToken, window);
             final IBinder focusToken = window.getFocusGrantToken();
             mWindowsByFocusToken.put(focusToken, window);
+            mWindowsByWindowToken.put(window.getWindowToken(), window);
             updateProcessController(window);
             window.mClient.asBinder().linkToDeath(()-> {
                 synchronized (mGlobalLock) {
@@ -116,6 +123,7 @@
             if (ew.mClient.asBinder() == client.asBinder()) {
                 mWindows.removeAt(i).onRemoved();
                 mWindowsByFocusToken.remove(ew.getFocusGrantToken());
+                mWindowsByWindowToken.remove(ew.getWindowToken());
                 return;
             }
         }
@@ -127,6 +135,7 @@
             if (ew.mHostWindowState == host) {
                 mWindows.removeAt(i).onRemoved();
                 mWindowsByFocusToken.remove(ew.getFocusGrantToken());
+                mWindowsByWindowToken.remove(ew.getWindowToken());
             }
         }
     }
@@ -139,6 +148,10 @@
         return mWindowsByFocusToken.get(focusGrantToken);
     }
 
+    EmbeddedWindow getByWindowToken(IBinder windowToken) {
+        return mWindowsByWindowToken.get(windowToken);
+    }
+
     void onActivityRemoved(ActivityRecord activityRecord) {
         for (int i = mWindows.size() - 1; i >= 0; i--) {
             final EmbeddedWindow window = mWindows.valueAt(i);
@@ -244,15 +257,29 @@
         }
 
         @Override
+        public DisplayContent getDisplayContent() {
+            return mWmService.mRoot.getDisplayContent(getDisplayId());
+        }
+
+        @Override
         public IWindow getIWindow() {
             return mClient;
         }
 
+        public IBinder getWindowToken() {
+            return mClient.asBinder();
+        }
+
         @Override
         public int getPid() {
             return mOwnerPid;
         }
 
+        @Override
+        public int getUid() {
+            return mOwnerUid;
+        }
+
         void setIsOverlay() {
             mIsOverlay = true;
         }
@@ -297,5 +324,46 @@
         public void handleTapOutsideFocusInsideSelf() {
             handleTap(true);
         }
+
+        @Override
+        public boolean shouldControlIme() {
+            return false;
+        }
+
+        @Override
+        public boolean canScreenshotIme() {
+            return true;
+        }
+
+        @Override
+        public void unfreezeInsetsAfterStartInput() {
+        }
+
+        @Override
+        public InsetsControlTarget getImeControlTarget() {
+            return mWmService.getDefaultDisplayContentLocked().mRemoteInsetsControlTarget;
+        }
+
+        @Override
+        public boolean isInputMethodClientFocus(int uid, int pid) {
+            return uid == mOwnerUid && pid == mOwnerPid;
+        }
+
+        @Override
+        public ActivityRecord getActivityRecord() {
+            return null;
+        }
+
+        @Override
+        public void dumpProto(ProtoOutputStream proto, long fieldId,
+                              @WindowTraceLogLevel int logLevel) {
+            final long token = proto.start(fieldId);
+
+            final long token2 = proto.start(IDENTIFIER);
+            proto.write(HASH_CODE, System.identityHashCode(this));
+            proto.write(TITLE, "EmbeddedWindow");
+            proto.end(token2);
+            proto.end(token);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/EventLogTags.logtags b/services/core/java/com/android/server/wm/EventLogTags.logtags
index e228a4b..6d63331 100644
--- a/services/core/java/com/android/server/wm/EventLogTags.logtags
+++ b/services/core/java/com/android/server/wm/EventLogTags.logtags
@@ -65,3 +65,5 @@
 # bootanim finished:
 31007 wm_boot_animation_done (time|2|3)
 
+# Request surface flinger to show / hide the wallpaper surface.
+33001 wm_wallpaper_surface (Display Id|1|5),(visible|1)
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index f24e429..199517c 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -21,7 +21,6 @@
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
 import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
-import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
 import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
 import static com.android.server.wm.ImeInsetsSourceProviderProto.IME_TARGET_FROM_IME;
 import static com.android.server.wm.ImeInsetsSourceProviderProto.INSETS_SOURCE_PROVIDER;
@@ -249,7 +248,7 @@
     }
 
     private boolean isImeInputTarget(InsetsControlTarget target) {
-        return target == mDisplayContent.getImeTarget(IME_TARGET_INPUT);
+        return target == mDisplayContent.getImeInputTarget();
     }
 
     private boolean sameAsImeControlTarget() {
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/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 1f0fdcf..8d1425d 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -39,6 +39,7 @@
 import com.android.server.input.InputManagerService;
 
 import java.io.PrintWriter;
+import java.util.OptionalInt;
 
 final class InputManagerCallback implements InputManagerService.WindowManagerCallbacks {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "InputManagerCallback" : TAG_WM;
@@ -98,23 +99,14 @@
     }
 
     @Override
-    public void notifyGestureMonitorUnresponsive(int pid, @NonNull String reason) {
-        mService.mAnrController.notifyGestureMonitorUnresponsive(pid, reason);
+    public void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
+            @NonNull String reason) {
+        mService.mAnrController.notifyWindowUnresponsive(token, pid, reason);
     }
 
     @Override
-    public void notifyWindowUnresponsive(@NonNull IBinder token, String reason) {
-        mService.mAnrController.notifyWindowUnresponsive(token, reason);
-    }
-
-    @Override
-    public void notifyGestureMonitorResponsive(int pid) {
-        mService.mAnrController.notifyGestureMonitorResponsive(pid);
-    }
-
-    @Override
-    public void notifyWindowResponsive(@NonNull IBinder token) {
-        mService.mAnrController.notifyWindowResponsive(token);
+    public void notifyWindowResponsive(@NonNull IBinder token, @NonNull OptionalInt pid) {
+        mService.mAnrController.notifyWindowResponsive(token, pid);
     }
 
     /** Notifies that the input device configuration has changed. */
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 44818a8..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();
@@ -414,6 +415,17 @@
         final IBinder focusToken = focus != null ? focus.mInputChannelToken : null;
         if (focusToken == null) {
             mInputFocus = null;
+            // When an app is focused, but its window is not showing yet, remove the input focus
+            // from the current window.
+            if (mDisplayContent.mFocusedApp != null) {
+                ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "App %s is focused,"
+                        + " but the window is not ready. Start a transaction to remove focus from"
+                        + " the window of non-focused apps.",
+                        mDisplayContent.mFocusedApp.getName());
+                EventLog.writeEvent(LOGTAG_INPUT_FOCUS, "Requesting to set focus to null window",
+                        "reason=UpdateInputWindows");
+                mInputTransaction.removeCurrentInputFocus(mDisplayId);
+            }
             return;
         }
 
@@ -511,6 +523,8 @@
                 layer = layer != null ? layer : activeRecents;
                 // Handle edge-case for SUW where windows don't exist yet
                 if (layer.getSurfaceControl() != null) {
+                    mRecentsAnimationInputConsumer.mWindowHandle
+                            .replaceTouchableRegionWithCrop(layer.getSurfaceControl());
                     mRecentsAnimationInputConsumer.show(mInputTransaction, layer);
                     mAddRecentsAnimationInputConsumerHandle = false;
                 }
@@ -577,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;
@@ -618,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);
     }
@@ -653,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/InputTarget.java b/services/core/java/com/android/server/wm/InputTarget.java
index 5166b8a..b5ab62b 100644
--- a/services/core/java/com/android/server/wm/InputTarget.java
+++ b/services/core/java/com/android/server/wm/InputTarget.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import android.view.IWindow;
+import android.util.proto.ProtoOutputStream;
 
 /**
  * Common interface between focusable objects.
@@ -36,6 +37,7 @@
 
     /* Owning pid of the target. */
     int getPid();
+    int getUid();
 
     /**
      * Indicates whether a target should receive focus from server side
@@ -45,7 +47,25 @@
      */
     boolean receiveFocusFromTapOutside();
 
+    // Gaining focus
     void handleTapOutsideFocusInsideSelf();
+    // Losing focus
     void handleTapOutsideFocusOutsideSelf();
+
+    // Whether this input target can control the IME itself
+    boolean shouldControlIme();
+    // Whether this input target can be screenshoted by the IME system
+    boolean canScreenshotIme();
+
+    ActivityRecord getActivityRecord();
+    void unfreezeInsetsAfterStartInput();
+
+    boolean isInputMethodClientFocus(int uid, int pid);
+
+    DisplayContent getDisplayContent();
+    InsetsControlTarget getImeControlTarget();
+
+    void dumpProto(ProtoOutputStream proto, long fieldId,
+                   @WindowTraceLogLevel int logLevel);
 }
 
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 bb6d83c..398816b 100644
--- a/services/core/java/com/android/server/wm/InsetsPolicy.java
+++ b/services/core/java/com/android/server/wm/InsetsPolicy.java
@@ -449,11 +449,8 @@
             boolean copyState) {
         final WindowState roundedCornerWindow = mPolicy.getRoundedCornerWindow();
         final Task task = w.getTask();
-        final boolean isInSplitScreenMode = task != null && task.inMultiWindowMode()
-                && task.getRootTask() != null
-                && task.getRootTask().getAdjacentTaskFragment() != null;
         if (task != null && !task.getWindowConfiguration().tasksAreFloating()
-                && (roundedCornerWindow != null || isInSplitScreenMode)) {
+                && (roundedCornerWindow != null || task.inSplitScreen())) {
             // Instead of using display frame to calculating rounded corner, for the fake rounded
             // corners drawn by divider bar or task bar, we need to re-calculate rounded corners
             // based on task bounds and if the task bounds is intersected with task bar, we should
@@ -586,10 +583,10 @@
             // Notification shade has control anyways, no reason to force anything.
             return focusedWin;
         }
-        if (mPolicy.isForceShowNavigationBarEnabled()
+        if (mPolicy.isForceShowNavigationBarEnabled() && focusedWin != null
                 && focusedWin.getActivityType() == ACTIVITY_TYPE_STANDARD) {
-            // When "force show navigation bar" is enabled, it means we are in kid navigation bar
-            // and 3-button navigation bar mode. In this mode, the navigation bar is forcibly shown
+            // When "force show navigation bar" is enabled, it means both force visible is true, and
+            // we are in 3-button navigation. In this mode, the navigation bar is forcibly shown
             // when activity type is ACTIVITY_TYPE_STANDARD which means Launcher or Recent could
             // still control the navigation bar in this mode.
             return 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/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 8a2d116..160fc95 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -542,7 +542,7 @@
         if (mLockTaskModeTasks.isEmpty()) {
             return;
         }
-        task.performClearTaskLocked();
+        task.performClearTaskForReuse(false /* excludingTaskOverlay*/);
         mSupervisor.mRootWindowContainer.resumeFocusedTasksTopActivities();
     }
 
@@ -740,7 +740,7 @@
             ProtoLog.d(WM_DEBUG_LOCKTASK, "onLockTaskPackagesUpdated: removing %s"
                     + " mLockTaskAuth()=%s", lockedTask, lockedTask.lockTaskAuthToString());
             removeLockedTask(lockedTask);
-            lockedTask.performClearTaskLocked();
+            lockedTask.performClearTaskForReuse(false /* excludingTaskOverlay*/);
             taskChanged = true;
         }
 
diff --git a/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java b/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java
index 3b8631a..073bbbb 100644
--- a/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java
+++ b/services/core/java/com/android/server/wm/PendingRemoteAnimationRegistry.java
@@ -19,6 +19,7 @@
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
 import android.os.Handler;
+import android.os.IBinder;
 import android.util.ArrayMap;
 import android.view.RemoteAnimationAdapter;
 
@@ -43,8 +44,9 @@
     /**
      * Adds a remote animation to be run for all activity starts originating from a certain package.
      */
-    void addPendingAnimation(String packageName, RemoteAnimationAdapter adapter) {
-        mEntries.put(packageName, new Entry(packageName, adapter));
+    void addPendingAnimation(String packageName, RemoteAnimationAdapter adapter,
+            @Nullable IBinder launchCookie) {
+        mEntries.put(packageName, new Entry(packageName, adapter, launchCookie));
     }
 
     /**
@@ -62,6 +64,10 @@
         } else {
             options.setRemoteAnimationAdapter(entry.adapter);
         }
+        IBinder launchCookie = entry.launchCookie;
+        if (launchCookie != null) {
+            options.setLaunchCookie(launchCookie);
+        }
         mEntries.remove(callingPackage);
         return options;
     }
@@ -69,10 +75,13 @@
     private class Entry {
         final String packageName;
         final RemoteAnimationAdapter adapter;
+        @Nullable
+        final IBinder launchCookie;
 
-        Entry(String packageName, RemoteAnimationAdapter adapter) {
+        Entry(String packageName, RemoteAnimationAdapter adapter, @Nullable IBinder launchCookie) {
             this.packageName = packageName;
             this.adapter = adapter;
+            this.launchCookie = launchCookie;
             mHandler.postDelayed(() -> {
                 synchronized (mLock) {
                     final Entry entry = mEntries.get(packageName);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 30906e5..a407021 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -18,7 +18,6 @@
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.view.RemoteAnimationTarget.MODE_CLOSING;
@@ -122,7 +121,6 @@
     private final int mDisplayId;
     private boolean mWillFinishToHome = false;
     private final Runnable mFailsafeRunnable = this::onFailsafe;
-    private Runnable mCheckRotationAfterCleanup;
 
     // The recents component app token that is shown behind the visibile tasks
     private ActivityRecord mTargetActivityRecord;
@@ -611,8 +609,7 @@
             final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
             final Task task = adapter.mTask;
             final TaskFragment adjacentTask = task.getRootTask().getAdjacentTaskFragment();
-            final boolean inSplitScreen = task.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
-                    && adjacentTask != null;
+            final boolean inSplitScreen = task.inSplitScreen();
             if (task.isActivityTypeHomeOrRecents()
                     // Skip if the task is in split screen and in landscape.
                     || (inSplitScreen && isDisplayLandscape)
@@ -920,24 +917,6 @@
     }
 
     /**
-     * If the display rotation change is ignored while recents animation is running, make sure that
-     * the pending rotation change will be applied after the animation finishes.
-     */
-    void setCheckRotationAfterCleanup() {
-        if (mCheckRotationAfterCleanup != null) return;
-        mCheckRotationAfterCleanup = () -> {
-            synchronized (mService.mGlobalLock) {
-                if (mDisplayContent.getDisplayRotation()
-                        .updateRotationAndSendNewConfigIfChanged()) {
-                    if (mTargetActivityRecord != null) {
-                        mTargetActivityRecord.finishFixedRotationTransform();
-                    }
-                }
-            }
-        };
-    }
-
-    /**
      * @return Whether we should defer the cancel from a root task order change until the next app
      * transition.
      */
@@ -1037,10 +1016,6 @@
         if (mStatusBar != null) {
             mStatusBar.onRecentsAnimationStateChanged(false /* running */);
         }
-        if (mCheckRotationAfterCleanup != null) {
-            mService.mH.post(mCheckRotationAfterCleanup);
-            mCheckRotationAfterCleanup = null;
-        }
     }
 
     void scheduleFailsafe() {
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 8ab2ee0..2355333 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -18,15 +18,9 @@
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.KeyguardManager.ACTION_CONFIRM_DEVICE_CREDENTIAL_WITH_USER;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
@@ -155,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;
@@ -2733,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 */);
     }
 
@@ -2750,81 +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) {
-            taskDisplayArea = launchParams.mPreferredTaskDisplayArea;
-        }
-
-        if (taskDisplayArea == null && displayId != INVALID_DISPLAY) {
-            final DisplayContent displayContent = getDisplayContent(displayId);
-            if (displayContent != null) {
-                taskDisplayArea = displayContent.getDefaultTaskDisplayArea();
-            }
-        }
-
         if (taskDisplayArea != null) {
-            final int tdaDisplayId = taskDisplayArea.getDisplayId();
-            if (canLaunchOnDisplay(r, tdaDisplayId)) {
-                if (r != null) {
-                    final Task result = getValidLaunchRootTaskInTaskDisplayArea(
-                            taskDisplayArea, r, candidateTask, options, launchParams);
-                    if (result != null) {
-                        return result;
-                    }
-                }
-                // Falling back to default task container
-                taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea();
-                rootTask = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
+            if (canLaunchOnDisplay(r, taskDisplayArea.getDisplayId())) {
+                return taskDisplayArea.getOrCreateRootTask(r, options, candidateTask,
                         sourceTask, launchParams, launchFlags, activityType, onTop);
-                if (rootTask != null) {
-                    return rootTask;
-                }
+            } 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();
         }
@@ -2834,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
@@ -2846,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. */
@@ -2866,104 +2862,11 @@
         if (r == null) {
             return true;
         }
-        return r.canBeLaunchedOnDisplay(displayId);
-    }
-
-    /**
-     * Get a topmost root task on the display area, that is a valid launch root task for
-     * specified activity. If there is no such root task, new dynamic root task can be created.
-     *
-     * @param taskDisplayArea Target display area.
-     * @param r               Activity that should be launched there.
-     * @param candidateTask   The possible task the activity might be put in.
-     * @return Existing root task if there is a valid one, new dynamic root task if it is valid
-     * or null.
-     */
-    @VisibleForTesting
-    Task getValidLaunchRootTaskInTaskDisplayArea(@NonNull TaskDisplayArea taskDisplayArea,
-            @NonNull ActivityRecord r, @Nullable Task candidateTask,
-            @Nullable ActivityOptions options,
-            @Nullable LaunchParamsController.LaunchParams launchParams) {
-        if (!r.canBeLaunchedOnDisplay(taskDisplayArea.getDisplayId())) {
-            return null;
-        }
-
-        // If {@code r} is already in target display area and its task is the same as the candidate
-        // task, the intention should be getting a launch root task for the reusable activity, so we
-        // can use the existing root task.
-        if (candidateTask != null) {
-            final TaskDisplayArea attachedTaskDisplayArea = candidateTask.getDisplayArea();
-            if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) {
-                return candidateTask.getRootTask();
-            }
-            // Or the candidate task is already a root task that can be reused by reparenting
-            // it to the target display.
-            if (candidateTask.isRootTask()) {
-                final Task rootTask = candidateTask.getRootTask();
-                rootTask.reparent(taskDisplayArea, true /* onTop */);
-                return rootTask;
-            }
-        }
-
-        int windowingMode;
-        if (launchParams != null) {
-            // When launch params is not null, we always defer to its windowing mode. Sometimes
-            // it could be unspecified, which indicates it should inherit windowing mode from
-            // display.
-            windowingMode = launchParams.mWindowingMode;
-        } else {
-            windowingMode = options != null ? options.getLaunchWindowingMode()
-                    : r.getWindowingMode();
-        }
-        windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask);
-
-        // Return the topmost valid root task on the display.
-        final int targetWindowingMode = windowingMode;
-        final Task topmostValidRootTask = taskDisplayArea.getRootTask(rootTask ->
-                isValidLaunchRootTask(rootTask, r, targetWindowingMode));
-        if (topmostValidRootTask != null) {
-            return topmostValidRootTask;
-        }
-
-        // If there is no valid root task on the secondary display area - check if new dynamic root
-        // task will do.
-        if (taskDisplayArea != getDisplayContent(taskDisplayArea.getDisplayId())
-                .getDefaultTaskDisplayArea()) {
-            final int activityType =
-                    options != null && options.getLaunchActivityType() != ACTIVITY_TYPE_UNDEFINED
-                            ? options.getLaunchActivityType() : r.getActivityType();
-            return taskDisplayArea.createRootTask(
-                    windowingMode, activityType, true /*onTop*/, options);
-        }
-
-        return null;
-    }
-
-    // TODO: Can probably be consolidated into getLaunchRootTask()...
-    private boolean isValidLaunchRootTask(Task task, ActivityRecord r, int windowingMode) {
-        switch (task.getActivityType()) {
-            case ACTIVITY_TYPE_HOME:
-                return r.isActivityTypeHome();
-            case ACTIVITY_TYPE_RECENTS:
-                return r.isActivityTypeRecents();
-            case ACTIVITY_TYPE_ASSISTANT:
-                return r.isActivityTypeAssistant();
-            case ACTIVITY_TYPE_DREAM:
-                return r.isActivityTypeDream();
-        }
-        if (task.mCreatedByOrganizer) {
-            // Don't launch directly into task created by organizer...but why can't we?
+        if (!r.canBeLaunchedOnDisplay(displayId)) {
+            Slog.w(TAG, "Not allow to launch " + r + " on display " + displayId);
             return false;
         }
-        // There is a 1-to-1 relationship between root task and task when not in
-        // primary split-windowing mode.
-        if (task.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                && r.supportsSplitScreenWindowingModeInDisplayArea(task.getDisplayArea())
-                && (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
-                || windowingMode == WINDOWING_MODE_UNDEFINED)) {
-            return true;
-        }
-        return false;
+        return true;
     }
 
     int resolveActivityType(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
@@ -3333,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");
                 }
             }
@@ -3430,15 +3333,45 @@
     }
 
     /**
+     * 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.
      */
     ArrayList<ActivityRecord> getDumpActivities(String name, boolean dumpVisibleRootTasksOnly,
-            boolean dumpFocusedRootTaskOnly) {
+            boolean dumpFocusedRootTaskOnly, @UserIdInt int userId) {
         if (dumpFocusedRootTaskOnly) {
             final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
             if (topFocusedRootTask != null) {
-                return topFocusedRootTask.getDumpActivitiesLocked(name);
+                return topFocusedRootTask.getDumpActivitiesLocked(name, userId);
             } else {
                 return new ArrayList<>();
             }
@@ -3446,7 +3379,7 @@
             final ArrayList<ActivityRecord> activities = new ArrayList<>();
             forAllRootTasks(rootTask -> {
                 if (!dumpVisibleRootTasksOnly || rootTask.shouldBeVisible(null)) {
-                    activities.addAll(rootTask.getDumpActivitiesLocked(name));
+                    activities.addAll(rootTask.getDumpActivitiesLocked(name, userId));
                 }
             });
             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 d31b007..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,16 +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.getAdjacentTaskFragment() != null) {
-            mTopDisplayAdjacentTask = mTopDisplayFocusRootTask.getAdjacentTaskFragment().asTask();
-        } else {
-            mTopDisplayAdjacentTask = null;
-        }
-
         final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
                 PooledLambda.__(Task.class));
         root.forAllLeafTasks(c, false);
@@ -131,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 cd8ddf4..0c609191 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -69,13 +69,13 @@
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.InsetsVisibilities;
-import android.view.OnBackInvokedDispatcher;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 import android.view.View;
 import android.view.WindowManager;
 import android.window.ClientWindowFrames;
 import android.window.IOnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.logging.MetricsLoggerWrapper;
@@ -84,6 +84,7 @@
 import com.android.server.wm.WindowManagerService.H;
 
 import java.io.PrintWriter;
+import java.util.Collections;
 import java.util.List;
 import java.util.function.BiConsumer;
 
@@ -521,10 +522,15 @@
     }
 
     @Override
-    public void reportKeepClearAreasChanged(IWindow window, List<Rect> keepClearAreas) {
+    public void reportKeepClearAreasChanged(IWindow window, List<Rect> restricted,
+            List<Rect> unrestricted) {
+        if (!mSetsUnrestrictedKeepClearAreas && !unrestricted.isEmpty()) {
+            unrestricted = Collections.emptyList();
+        }
+
         final long ident = Binder.clearCallingIdentity();
         try {
-            mService.reportKeepClearAreasChanged(this, window, keepClearAreas);
+            mService.reportKeepClearAreasChanged(this, window, restricted, unrestricted);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java
index 2eab3ba..f9d7b53 100644
--- a/services/core/java/com/android/server/wm/ShellRoot.java
+++ b/services/core/java/com/android/server/wm/ShellRoot.java
@@ -25,15 +25,14 @@
 import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Point;
-import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Slog;
 import android.view.DisplayInfo;
 import android.view.IWindow;
 import android.view.SurfaceControl;
-import android.view.WindowInfo;
 import android.view.WindowManager;
 import android.view.animation.Animation;
 
@@ -136,46 +135,12 @@
                 ANIMATION_TYPE_WINDOW_ANIMATION);
     }
 
-    WindowInfo getWindowInfo() {
-        if (mShellRootLayer != SHELL_ROOT_LAYER_DIVIDER
-                && mShellRootLayer != SHELL_ROOT_LAYER_PIP) {
-            return null;
+    @Nullable
+    IBinder getAccessibilityWindowToken() {
+        if (mAccessibilityWindow != null) {
+            return mAccessibilityWindow.asBinder();
         }
-        if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER) {
-            return null;
-        }
-        if (mShellRootLayer == SHELL_ROOT_LAYER_PIP
-                && mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask() == null) {
-            return null;
-        }
-        if (mAccessibilityWindow == null) {
-            return null;
-        }
-        WindowInfo windowInfo = WindowInfo.obtain();
-        windowInfo.displayId = mToken.getDisplayArea().getDisplayContent().mDisplayId;
-        windowInfo.type = mToken.windowType;
-        windowInfo.layer = mToken.getWindowLayerFromType();
-        windowInfo.token = mAccessibilityWindow.asBinder();
-        windowInfo.focused = false;
-        windowInfo.hasFlagWatchOutsideTouch = false;
-        final Rect regionRect = new Rect();
-
-
-        // DividerView
-        if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER) {
-            windowInfo.inPictureInPicture = false;
-            mDisplayContent.getDockedDividerController().getTouchRegion(regionRect);
-            windowInfo.regionInScreen.set(regionRect);
-            windowInfo.title = "Splitscreen Divider";
-        }
-        // PipMenuView
-        if (mShellRootLayer == SHELL_ROOT_LAYER_PIP) {
-            windowInfo.inPictureInPicture = true;
-            mDisplayContent.getDefaultTaskDisplayArea().getRootPinnedTask().getBounds(regionRect);
-            windowInfo.regionInScreen.set(regionRect);
-            windowInfo.title = "Picture-in-Picture menu";
-        }
-        return windowInfo;
+        return null;
     }
 
     void setAccessibilityWindow(IWindow window) {
@@ -196,9 +161,5 @@
                 mAccessibilityWindow = null;
             }
         }
-        if (mDisplayContent.mWmService.mAccessibilityController.hasCallbacks()) {
-            mDisplayContent.mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(
-                    mDisplayContent.getDisplayId());
-        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java
index 58091c8..4ab9d2f 100644
--- a/services/core/java/com/android/server/wm/StartingSurfaceController.java
+++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java
@@ -18,13 +18,13 @@
 
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_DRAWN;
-import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN;
+import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
-import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;
+import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN;
 
 import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -51,12 +51,12 @@
     private static final String TAG = TAG_WITH_CLASS_NAME
             ? StartingSurfaceController.class.getSimpleName() : TAG_WM;
     /**
-     * Allow the empty style splash screen view can be copy and transfer to another process if
+     * Allow the solid color style splash screen view can be copy and transfer to another process if
      * the app targeting to {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher.
      */
     @ChangeId
     @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
-    private static final long ALLOW_COPY_EMPTY_VIEW = 205907456L;
+    private static final long ALLOW_COPY_SOLID_COLOR_VIEW = 205907456L;
 
     private final WindowManagerService mService;
     private final SplashScreenExceptionList mSplashScreenExceptionsList;
@@ -96,7 +96,7 @@
 
     static int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch,
             boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated,
-            boolean useEmpty, boolean useLegacy, boolean activityDrawn, int startingWindowType,
+            boolean isSolidColor, boolean useLegacy, boolean activityDrawn, int startingWindowType,
             String packageName, int userId) {
         int parameter = 0;
         if (newTask) {
@@ -114,8 +114,8 @@
         if (activityCreated) {
             parameter |= TYPE_PARAMETER_ACTIVITY_CREATED;
         }
-        if (useEmpty) {
-            parameter |= TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;
+        if (isSolidColor) {
+            parameter |= TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN;
         }
         if (useLegacy) {
             parameter |= TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
@@ -124,9 +124,9 @@
             parameter |= TYPE_PARAMETER_ACTIVITY_DRAWN;
         }
         if (startingWindowType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
-                && CompatChanges.isChangeEnabled(ALLOW_COPY_EMPTY_VIEW, packageName,
+                && CompatChanges.isChangeEnabled(ALLOW_COPY_SOLID_COLOR_VIEW, packageName,
                 UserHandle.of(userId))) {
-            parameter |= TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN;
+            parameter |= TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN;
         }
         return parameter;
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 98c74f8..b3ae602 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -29,6 +29,7 @@
 import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.activityTypeToString;
@@ -137,6 +138,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RecentTaskInfo.PersistedTaskSnapshotData;
@@ -502,13 +504,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();
 
@@ -1583,19 +1578,23 @@
     }
 
     /** Completely remove all activities associated with an existing task. */
-    void performClearTask(String reason) {
+    void removeActivities(String reason, boolean excludingTaskOverlay) {
         clearPinnedTaskIfNeed();
         // Broken down into to cases to avoid object create due to capturing mStack.
         if (getRootTask() == null) {
             forAllActivities((r) -> {
-                if (r.finishing) return;
+                if (r.finishing || (excludingTaskOverlay && r.isTaskOverlay())) {
+                    return;
+                }
                 // Task was restored from persistent storage.
                 r.takeFromHistory();
                 removeChild(r, reason);
             });
         } else {
             forAllActivities((r) -> {
-                if (r.finishing) return;
+                if (r.finishing || (excludingTaskOverlay && r.isTaskOverlay())) {
+                    return;
+                }
                 // Prevent the transition from being executed too early if the top activity is
                 // resumed but the mVisibleRequested of any other activity is true, the transition
                 // should wait until next activity resumed.
@@ -1612,26 +1611,24 @@
     /**
      * Completely remove all activities associated with an existing task.
      */
-    void performClearTaskLocked() {
+    void performClearTaskForReuse(boolean excludingTaskOverlay) {
         mReuseTask = true;
         mTaskSupervisor.beginDeferResume();
         try {
-            performClearTask("clear-task-all");
+            removeActivities("clear-task-all", excludingTaskOverlay);
         } finally {
             mTaskSupervisor.endDeferResume();
             mReuseTask = false;
         }
     }
 
-    ActivityRecord performClearTaskForReuseLocked(ActivityRecord newR, int launchFlags) {
-        mReuseTask = true;
+    ActivityRecord performClearTop(ActivityRecord newR, int launchFlags) {
         mTaskSupervisor.beginDeferResume();
         final ActivityRecord result;
         try {
-            result = performClearTaskLocked(newR, launchFlags);
+            result = clearTopActivities(newR, launchFlags);
         } finally {
             mTaskSupervisor.endDeferResume();
-            mReuseTask = false;
         }
         return result;
     }
@@ -1647,7 +1644,7 @@
      * @return Returns the old activity that should be continued to be used,
      * or {@code null} if none was found.
      */
-    private ActivityRecord performClearTaskLocked(ActivityRecord newR, int launchFlags) {
+    private ActivityRecord clearTopActivities(ActivityRecord newR, int launchFlags) {
         final ActivityRecord r = findActivityInHistory(newR.mActivityComponent);
         if (r == null) return null;
 
@@ -1674,7 +1671,7 @@
         // Stop operation once we reach the boundary activity.
         if (r == boundaryActivity) return true;
 
-        if (!r.finishing) {
+        if (!r.finishing && !r.isTaskOverlay()) {
             final ActivityOptions opts = r.getOptions();
             if (opts != null) {
                 r.clearOptionsAnimation();
@@ -1719,6 +1716,13 @@
                 && (topTask == null || topTask.supportsSplitScreenWindowingModeInner(tda));
     }
 
+    /** Returns {@code true} if this task is currently in split-screen. */
+    boolean inSplitScreen() {
+        return getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
+                && getRootTask() != null
+                && getRootTask().getAdjacentTaskFragment() != null;
+    }
+
     private boolean supportsSplitScreenWindowingModeInner(@Nullable TaskDisplayArea tda) {
         return super.supportsSplitScreenWindowingMode()
                 && mAtmService.mSupportsSplitScreenMultiWindow
@@ -3289,7 +3293,7 @@
         // We intend to let organizer manage task visibility but it doesn't
         // have enough information until we finish shell transitions.
         // In the mean time we do an easy fix here.
-        final boolean show = isVisible() || isAnimating(TRANSITION | PARENTS);
+        final boolean show = isVisible() || isAnimating(TRANSITION | PARENTS | CHILDREN);
         if (mSurfaceControl != null) {
             if (show != mLastSurfaceShowing) {
                 getSyncTransaction().setVisibility(mSurfaceControl, show);
@@ -4276,7 +4280,7 @@
     /**
      * @return true if the task is currently focused.
      */
-    private boolean isFocused() {
+    boolean isFocused() {
         if (mDisplayContent == null || mDisplayContent.mFocusedApp == null) {
             return false;
         }
@@ -4379,17 +4383,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,
@@ -5691,7 +5694,7 @@
         }
     }
 
-    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
+    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name, @UserIdInt int userId) {
         ArrayList<ActivityRecord> activities = new ArrayList<>();
 
         if ("all".equals(name)) {
@@ -5711,7 +5714,13 @@
                 }
             });
         }
-
+        if (userId != UserHandle.USER_ALL) {
+            for (int i = activities.size() - 1; i >= 0; --i) {
+                if (activities.get(i).mUserId != userId) {
+                    activities.remove(i);
+                }
+            }
+        }
         return activities;
     }
 
@@ -6011,9 +6020,6 @@
     }
 
     boolean shouldIgnoreInput() {
-        if (inSplitScreenPrimaryWindowingMode() && !isFocusable()) {
-            return true;
-        }
         if (mAtmService.mHasLeanbackFeature && inPinnedWindowingMode()
                 && !isFocusedRootTaskOnDisplay()) {
             // Preventing Picture-in-Picture root task from receiving input on TVs.
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index f0cca18..2f50b14 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -941,36 +941,32 @@
     Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop,
             @Nullable Task candidateTask, @Nullable Task sourceTask,
             @Nullable ActivityOptions options, int launchFlags) {
+        final int resolvedWindowingMode =
+                windowingMode == WINDOWING_MODE_UNDEFINED ? getWindowingMode() : windowingMode;
         // Need to pass in a determined windowing mode to see if a new root task should be created,
         // so use its parent's windowing mode if it is undefined.
-        if (!alwaysCreateRootTask(
-                windowingMode != WINDOWING_MODE_UNDEFINED ? windowingMode : getWindowingMode(),
-                activityType)) {
-            Task rootTask = getRootTask(windowingMode, activityType);
+        if (!alwaysCreateRootTask(resolvedWindowingMode, activityType)) {
+            Task rootTask = getRootTask(resolvedWindowingMode, activityType);
             if (rootTask != null) {
                 return rootTask;
             }
         } else if (candidateTask != null) {
             final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
-            final Task launchRootTask = getLaunchRootTask(windowingMode, activityType, options,
-                    sourceTask, launchFlags);
+            final Task launchRootTask = getLaunchRootTask(resolvedWindowingMode, activityType,
+                    options, sourceTask, launchFlags);
             if (launchRootTask != null) {
                 if (candidateTask.getParent() == null) {
                     launchRootTask.addChild(candidateTask, position);
                 } else if (candidateTask.getParent() != launchRootTask) {
                     candidateTask.reparent(launchRootTask, position);
                 }
-            } else if (candidateTask.getDisplayArea() != this || !candidateTask.isRootTask()) {
+            } else if (candidateTask.getDisplayArea() != this) {
                 if (candidateTask.getParent() == null) {
                     addChild(candidateTask, position);
                 } else {
                     candidateTask.reparent(this, onTop);
                 }
             }
-            // Update windowing mode if necessary, e.g. moving a pinned task to fullscreen.
-            if (candidateTask.getWindowingMode() != windowingMode) {
-                candidateTask.setWindowingMode(windowingMode);
-            }
             return candidateTask.getRootTask();
         }
         return new Task.Builder(mAtmService)
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 7fab94c..3411104 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -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;
@@ -1767,8 +1768,7 @@
         // Resolve override windowing mode to fullscreen for home task (even on freeform
         // display), or split-screen if in split-screen mode.
         if (getActivityType() == ACTIVITY_TYPE_HOME && windowingMode == WINDOWING_MODE_UNDEFINED) {
-            windowingMode = WindowConfiguration.isSplitScreenWindowingMode(parentWindowingMode)
-                    ? parentWindowingMode : WINDOWING_MODE_FULLSCREEN;
+            windowingMode = WINDOWING_MODE_FULLSCREEN;
             getResolvedOverrideConfiguration().windowConfiguration.setWindowingMode(windowingMode);
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index b8ceb4a..9bb0271 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -157,12 +157,26 @@
         // display.
         if (launchMode == WINDOWING_MODE_UNDEFINED
                 && canInheritWindowingModeFromSource(display, source)) {
-            launchMode = source.getWindowingMode();
+            // The source's windowing mode may be different from its task, e.g. activity is set
+            // to fullscreen and its task is pinned windowing mode when the activity is entering
+            // pip.
+            launchMode = source.getTask().getWindowingMode();
             if (DEBUG) {
                 appendLog("inherit-from-source="
                         + WindowConfiguration.windowingModeToString(launchMode));
             }
         }
+        // If the launch windowing mode is still undefined, inherit from the target task if the
+        // task is already on the right display area (otherwise, the task may be on a different
+        // display area that has incompatible windowing mode).
+        if (launchMode == WINDOWING_MODE_UNDEFINED
+                && task != null && task.getTaskDisplayArea() == suggestedDisplayArea) {
+            launchMode = task.getWindowingMode();
+            if (DEBUG) {
+                appendLog("inherit-from-task="
+                        + WindowConfiguration.windowingModeToString(launchMode));
+            }
+        }
         // hasInitialBounds is set if either activity options or layout has specified bounds. If
         // that's set we'll skip some adjustments later to avoid overriding the initial bounds.
         boolean hasInitialBounds = false;
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 9d644b6e..ff5bfbe 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -729,6 +729,16 @@
             // Skip if task still not appeared.
             return;
         }
+        if (force && mPendingTaskEvents.isEmpty()) {
+            // There are task-info changed events do not result in
+            // - RootWindowContainer#performSurfacePlacementNoTrace OR
+            // - WindowAnimator#animate
+            // For instance, when an app requesting aspect ratio change when in PiP mode.
+            // To solve this, we directly dispatch the pending event if there are no events queued (
+            // otherwise, all pending events should be dispatched on next drawn).
+            dispatchTaskInfoChanged(task, true /* force */);
+            return;
+        }
 
         // Defer task info reporting while layout is deferred. This is because layout defer
         // blocks tend to do lots of re-ordering which can mess up animations in receivers.
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/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 6a23eb5..cde9927 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -534,7 +534,7 @@
             // Since RecentsAnimation will handle task snapshot while switching apps with the
             // best capture timing (e.g. IME window capture),
             // No need additional task capture while task is controlled by RecentsAnimation.
-            if (task.isAnimatingByRecents()) {
+            if (isAnimatingByRecents(task)) {
                 mSkipClosingAppSnapshotTasks.add(task);
             }
             // If the task of the app is not visible anymore, it means no other app in that task
@@ -686,7 +686,7 @@
             // Since RecentsAnimation will handle task snapshot while switching apps with the best
             // capture timing (e.g. IME window capture), No need additional task capture while task
             // is controlled by RecentsAnimation.
-            if (task.isVisible() && !task.isAnimatingByRecents()) {
+            if (task.isVisible() && !isAnimatingByRecents(task)) {
                 mTmpTasks.add(task);
             }
         });
@@ -717,6 +717,11 @@
                 frame, Type.systemBars(), false /* ignoreVisibility */).toRect();
     }
 
+    private boolean isAnimatingByRecents(@NonNull Task task) {
+        return task.isAnimatingByRecents()
+                || mService.mAtmService.getTransitionController().inRecentsTransition(task);
+    }
+
     void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "mHighResTaskSnapshotScale=" + mHighResTaskSnapshotScale);
         pw.println(prefix + "mTaskSnapshotEnabled=" + mTaskSnapshotEnabled);
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 3a3103e..4c23f39 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -80,9 +80,12 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
+import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.internal.protolog.ProtoLogGroup;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.LocalServices;
+import com.android.server.inputmethod.InputMethodManagerInternal;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -167,8 +170,11 @@
      */
     private final ArraySet<WindowToken> mVisibleAtTransitionEndTokens = new ArraySet<>();
 
-    /** Set of transient activities (lifecycle initially tied to this transition). */
-    private ArraySet<ActivityRecord> mTransientLaunches = null;
+    /**
+     * Set of transient activities (lifecycle initially tied to this transition) and their
+     * restore-below tasks.
+     */
+    private ArrayMap<ActivityRecord, Task> mTransientLaunches = null;
 
     /** Custom activity-level animation options and callbacks. */
     private TransitionInfo.AnimationOptions mOverrideOptions;
@@ -196,17 +202,26 @@
     }
 
     /** Records an activity as transient-launch. This activity must be already collected. */
-    void setTransientLaunch(@NonNull ActivityRecord activity) {
+    void setTransientLaunch(@NonNull ActivityRecord activity, @Nullable Task restoreBelow) {
         if (mTransientLaunches == null) {
-            mTransientLaunches = new ArraySet<>();
+            mTransientLaunches = new ArrayMap<>();
         }
-        mTransientLaunches.add(activity);
+        mTransientLaunches.put(activity, restoreBelow);
         ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Transition %d: Set %s as "
                 + "transient-launch", mSyncId, activity);
     }
 
     boolean isTransientLaunch(@NonNull ActivityRecord activity) {
-        return mTransientLaunches != null && mTransientLaunches.contains(activity);
+        return mTransientLaunches != null && mTransientLaunches.containsKey(activity);
+    }
+
+    Task getTransientLaunchRestoreTarget(@NonNull WindowContainer container) {
+        for (int i = 0; i < mTransientLaunches.size(); ++i) {
+            if (mTransientLaunches.keyAt(i).isDescendantOf(container)) {
+                return mTransientLaunches.valueAt(i);
+            }
+        }
+        return null;
     }
 
     boolean isOnDisplay(@NonNull DisplayContent dc) {
@@ -464,7 +479,7 @@
                                 && ar.pictureInPictureArgs.isAutoEnterEnabled()) {
                             if (mTransientLaunches != null) {
                                 for (int j = 0; j < mTransientLaunches.size(); ++j) {
-                                    if (mTransientLaunches.valueAt(j).isVisibleRequested()) {
+                                    if (mTransientLaunches.keyAt(j).isVisibleRequested()) {
                                         // force enable pip-on-task-switch now that we've committed
                                         // to actually launching to the transient activity.
                                         ar.supportsEnterPipOnTaskSwitch = true;
@@ -536,19 +551,30 @@
         for (int i = 0; i < mTargetDisplays.size(); ++i) {
             final DisplayContent dc = mTargetDisplays.get(i);
             final AsyncRotationController asyncRotationController = dc.getAsyncRotationController();
-            if (asyncRotationController != null) {
+            if (asyncRotationController != null && mTargets.contains(dc)) {
                 asyncRotationController.onTransitionFinished();
             }
             if (mTransientLaunches != null) {
+                InsetsControlTarget prevImeTarget = dc.getImeTarget(
+                        DisplayContent.IME_TARGET_CONTROL);
+                InsetsControlTarget newImeTarget = null;
                 // Transient-launch activities cannot be IME target (WindowState#canBeImeTarget),
                 // so re-compute in case the IME target is changed after transition.
                 for (int t = 0; t < mTransientLaunches.size(); ++t) {
-                    if (mTransientLaunches.valueAt(t).getDisplayContent() == dc) {
-                        dc.computeImeTarget(true /* updateImeTarget */);
+                    if (mTransientLaunches.keyAt(t).getDisplayContent() == dc) {
+                        newImeTarget = dc.computeImeTarget(true /* updateImeTarget */);
                         break;
                     }
                 }
+                if (mRecentsDisplayId != INVALID_DISPLAY && prevImeTarget == newImeTarget) {
+                    // Restore IME icon only when moving the original app task to front from
+                    // recents, in case IME icon may missing if the moving task has already been
+                    // the current focused task.
+                    InputMethodManagerInternal.get().updateImeWindowStatus(
+                            false /* disableImeIcon */);
+                }
             }
+            dc.removeImeSurfaceImmediately();
             dc.handleCompleteDeferredRemoval();
         }
     }
@@ -684,7 +710,7 @@
         // This is non-null only if display has changes. It handles the visible windows that don't
         // need to be participated in the transition.
         final AsyncRotationController controller = dc.getAsyncRotationController();
-        if (controller != null) {
+        if (controller != null && mTargets.contains(dc)) {
             controller.setupStartTransaction(transaction);
         }
         mStartTransaction = transaction;
@@ -769,6 +795,26 @@
             }
         }
 
+        // Hiding IME/IME icon when starting quick-step with resents animation.
+        if (!mTargetDisplays.get(mRecentsDisplayId).isImeAttachedToApp()) {
+            // Hiding IME if IME window is not attached to app.
+            // Since some windowing mode is not proper to snapshot Task with IME window
+            // while the app transitioning to the next task (e.g. split-screen mode)
+            final InputMethodManagerInternal inputMethodManagerInternal =
+                    LocalServices.getService(InputMethodManagerInternal.class);
+            if (inputMethodManagerInternal != null) {
+                inputMethodManagerInternal.hideCurrentInputMethod(
+                        SoftInputShowHideReason.HIDE_RECENTS_ANIMATION);
+            }
+        } else {
+            // Disable IME icon explicitly when IME attached to the app in case
+            // IME icon might flickering while swiping to the next app task still
+            // in animating before the next app window focused, or IME icon
+            // persists on the bottom when swiping the task to recents.
+            InputMethodManagerInternal.get().updateImeWindowStatus(
+                    true /* disableImeIcon */);
+        }
+
         // The rest of this function handles nav-bar reparenting
 
         if (!dc.getDisplayPolicy().shouldAttachNavBarToAppDuringTransition()
@@ -1262,7 +1308,11 @@
                 change.setAllowEnterPip(topMostActivity != null
                         && topMostActivity.checkEnterPictureInPictureAppOpsState());
                 final ActivityRecord topRunningActivity = task.topRunningActivity();
-                if (topRunningActivity != null && task.mDisplayContent != null) {
+                if (topRunningActivity != null && task.mDisplayContent != null
+                        // Display won't be rotated for multi window Task, so the fixed rotation
+                        // won't be applied. This can happen when the windowing mode is changed
+                        // before the previous fixed rotation is applied.
+                        && !task.inMultiWindowMode()) {
                     // If Activity is in fixed rotation, its will be applied with the next rotation,
                     // when the Task is still in the previous rotation.
                     final int taskRotation = task.getWindowConfiguration().getDisplayRotation();
@@ -1477,6 +1527,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 c13ae95..8840cd5 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.view.WindowManager.TRANSIT_CHANGE;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
@@ -62,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;
@@ -246,7 +245,7 @@
 
     /** @return {@code true} if wc is in a participant subtree */
     boolean inTransition(@NonNull WindowContainer wc) {
-        if (isCollecting(wc))  return true;
+        if (isCollecting(wc)) return true;
         for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
             for (WindowContainer p = wc; p != null; p = p.getParent()) {
                 if (mPlayingTransitions.get(i).mParticipants.contains(p)) {
@@ -257,6 +256,28 @@
         return false;
     }
 
+    boolean inRecentsTransition(@NonNull WindowContainer wc) {
+        for (WindowContainer p = wc; p != null; p = p.getParent()) {
+            // TODO(b/221417431): replace this with deterministic snapshots
+            if (mCollectingTransition == null) break;
+            if ((mCollectingTransition.getFlags() & TRANSIT_FLAG_IS_RECENTS) != 0
+                    && mCollectingTransition.mParticipants.contains(wc)) {
+                return true;
+            }
+        }
+
+        for (int i = mPlayingTransitions.size() - 1; i >= 0; --i) {
+            for (WindowContainer p = wc; p != null; p = p.getParent()) {
+                // TODO(b/221417431): replace this with deterministic snapshots
+                if ((mPlayingTransitions.get(i).getFlags() & TRANSIT_FLAG_IS_RECENTS) != 0
+                        && mPlayingTransitions.get(i).mParticipants.contains(p)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
     /** @return {@code true} if wc is in a participant subtree */
     boolean isTransitionOnDisplay(@NonNull DisplayContent dc) {
         if (mCollectingTransition != null && mCollectingTransition.isOnDisplay(dc)) {
@@ -282,21 +303,6 @@
         return false;
     }
 
-    /**
-     * Temporary work-around to deal with integration of legacy fixed-rotation. Returns whether
-     * the activity was visible before the collecting transition.
-     * TODO: at-least replace the polling mechanism.
-     */
-    boolean wasVisibleAtStart(@NonNull ActivityRecord ar) {
-        if (mCollectingTransition == null) return ar.isVisible();
-        final Transition.ChangeInfo ci = mCollectingTransition.mChanges.get(ar);
-        if (ci == null) {
-            // not part of transition, so use current state.
-            return ar.isVisible();
-        }
-        return ci.mVisible;
-    }
-
     @WindowConfiguration.WindowingMode
     int getWindowingModeAtStart(@NonNull WindowContainer wc) {
         if (mCollectingTransition == null) return wc.getWindowingMode();
@@ -520,23 +526,25 @@
     /**
      * Record that the launch of {@param activity} is transient (meaning its lifecycle is currently
      * tied to the transition).
+     * @param restoreBelowTask If non-null, the activity's task will be ordered right below this
+     *                         task if requested.
      */
-    void setTransientLaunch(@NonNull ActivityRecord activity) {
+    void setTransientLaunch(@NonNull ActivityRecord activity, @Nullable Task restoreBelowTask) {
         if (mCollectingTransition == null) return;
-        mCollectingTransition.setTransientLaunch(activity);
+        mCollectingTransition.setTransientLaunch(activity, restoreBelowTask);
 
         // TODO(b/188669821): Remove once legacy recents behavior is moved to shell.
         // Also interpret HOME transient launch as recents
-        if (activity.getActivityType() == ACTIVITY_TYPE_HOME) {
+        if (activity.isActivityTypeHomeOrRecents()) {
             mCollectingTransition.addFlag(TRANSIT_FLAG_IS_RECENTS);
+            // When starting recents animation, we assume the recents activity is behind the app
+            // task and should not affect system bar appearance,
+            // until WMS#setRecentsAppBehindSystemBars be called from launcher when passing
+            // the gesture threshold.
+            activity.getTask().setCanAffectSystemUiFlags(false);
         }
     }
 
-    void setSeamlessRotation(@NonNull WindowContainer wc) {
-        if (mCollectingTransition == null) return;
-        mCollectingTransition.setSeamlessRotation(wc);
-    }
-
     void legacyDetachNavigationBarFromApp(@NonNull IBinder token) {
         final Transition transition = Transition.fromBinder(token);
         if (transition == null || !mPlayingTransitions.contains(transition)) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 24493e2..14737d4 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -196,8 +196,11 @@
                         "Win " + w + ": token animating, looking behind.");
             }
             mFindResults.setIsWallpaperTargetForLetterbox(w.hasWallpaperForLetterboxBackground());
-            // Found a target! End search.
-            return true;
+            // While the keyguard is going away, both notification shade and a normal activity such
+            // as a launcher can satisfy criteria for a wallpaper target. In this case, we should
+            // chose the normal activity, otherwise wallpaper becomes invisible when a new animation
+            // starts before the keyguard going away animation finishes.
+            return w.mActivityRecord != null;
         }
         return false;
     };
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index bbc8462..dab02de 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -47,6 +47,7 @@
 import static com.android.server.wm.IdentifierProto.USER_ID;
 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.WindowContainer.AnimationFlags.CHILDREN;
 import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
 import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
@@ -72,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;
@@ -437,15 +439,9 @@
                             + " already exists. Overwriting");
                 }
             }
-            if (insetsSourceProvider == null
-                    || !(insetsSourceProvider instanceof RectInsetsSourceProvider)) {
-                insetsSourceProvider =
-                        new RectInsetsSourceProvider(
-                                new InsetsSource(insetsTypes[i]),
-                                mDisplayContent.getInsetsStateController(),
-                                mDisplayContent);
-                mLocalInsetsSourceProviders.put(insetsTypes[i], insetsSourceProvider);
-            }
+            insetsSourceProvider = new RectInsetsSourceProvider(new InsetsSource(insetsTypes[i]),
+                    mDisplayContent.getInsetsStateController(), mDisplayContent);
+            mLocalInsetsSourceProviders.put(insetsTypes[i], insetsSourceProvider);
             ((RectInsetsSourceProvider) insetsSourceProvider).setRect(providerFrame);
         }
         mDisplayContent.getInsetsStateController().updateAboveInsetsState(true);
@@ -1029,7 +1025,7 @@
         return mProvidedInsetsSources;
     }
 
-    DisplayContent getDisplayContent() {
+    public DisplayContent getDisplayContent() {
         return mDisplayContent;
     }
 
@@ -1179,6 +1175,27 @@
         return mTransitionController.inTransition(this);
     }
 
+    boolean inAppOrRecentsTransition() {
+        if (!mTransitionController.isShellTransitionsEnabled()) {
+            return isAnimating(PARENTS | TRANSITION,
+                    ANIMATION_TYPE_APP_TRANSITION | ANIMATION_TYPE_RECENTS);
+        }
+        for (WindowContainer p = this; p != null; p = p.getParent()) {
+            if (mTransitionController.isCollecting(p)) {
+                return true;
+            }
+        }
+        if (inTransition() || mTransitionController.inRecentsTransition(this)) return true;
+
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            WindowContainer child = mChildren.get(i);
+            if (child.inAppOrRecentsTransition()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     void sendAppVisibilityToClients() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
             final WindowContainer wc = mChildren.get(i);
@@ -3791,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 5b1021e..4e47659 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -25,6 +25,7 @@
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
 import static android.Manifest.permission.RESTRICTED_VR_ACCESS;
+import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.Manifest.permission.WRITE_SECURE_SETTINGS;
 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
@@ -114,7 +115,6 @@
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
 import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL;
-import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
 import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
 import static com.android.server.wm.RootWindowContainer.MATCH_ATTACHED_TASK_OR_RECENT_TASKS;
 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_ALL;
@@ -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;
@@ -200,6 +202,7 @@
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
 import android.os.RemoteCallback;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceManager;
@@ -228,6 +231,7 @@
 import android.util.TypedValue;
 import android.util.proto.ProtoOutputStream;
 import android.view.Choreographer;
+import android.view.ContentRecordingSession;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -288,6 +292,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.policy.IKeyguardLockedStateListener;
 import com.android.internal.policy.IShortcutService;
 import com.android.internal.policy.KeyInterceptionInfo;
 import com.android.internal.protolog.ProtoLogImpl;
@@ -401,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
@@ -460,6 +465,10 @@
 
     final private KeyguardDisableHandler mKeyguardDisableHandler;
 
+    private final RemoteCallbackList<IKeyguardLockedStateListener> mKeyguardLockedStateListeners =
+            new RemoteCallbackList<>();
+    private boolean mDispatchedKeyguardLockedState = false;
+
     // VR Vr2d Display Id.
     int mVr2dDisplayId = INVALID_DISPLAY;
     boolean mVrModeEnabled = false;
@@ -743,6 +752,9 @@
     private InputTarget mFocusedInputTarget;
 
     @VisibleForTesting
+    final ContentRecordingController mContentRecordingController = new ContentRecordingController();
+
+    @VisibleForTesting
     final class SettingsObserver extends ContentObserver {
         private final Uri mDisplayInversionEnabledUri =
                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
@@ -2888,6 +2900,16 @@
         }
     }
 
+    /**
+     * Updates the current content mirroring session.
+     */
+    @Override
+    public void setContentRecordingSession(@Nullable ContentRecordingSession incomingSession) {
+        synchronized (mGlobalLock) {
+            mContentRecordingController.setContentRecordingSessionLocked(incomingSession, this);
+        }
+    }
+
     // TODO(multi-display): remove when no default display use case.
     void prepareAppTransitionNone() {
         if (!checkCallingPermission(MANAGE_APP_TOKENS, "prepareAppTransition()")) {
@@ -3029,6 +3051,7 @@
     @Override
     public void onKeyguardShowingAndNotOccludedChanged() {
         mH.sendEmptyMessage(H.RECOMPUTE_FOCUS);
+        dispatchKeyguardLockedState();
     }
 
     @Override
@@ -3218,6 +3241,50 @@
         }
     }
 
+    @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+    @Override
+    public void addKeyguardLockedStateListener(IKeyguardLockedStateListener listener) {
+        enforceSubscribeToKeyguardLockedStatePermission();
+        boolean registered = mKeyguardLockedStateListeners.register(listener);
+        if (!registered) {
+            Slog.w(TAG, "Failed to register listener: " + listener);
+        }
+    }
+
+    @RequiresPermission(Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)
+    @Override
+    public void removeKeyguardLockedStateListener(IKeyguardLockedStateListener listener) {
+        enforceSubscribeToKeyguardLockedStatePermission();
+        mKeyguardLockedStateListeners.unregister(listener);
+    }
+
+    private void enforceSubscribeToKeyguardLockedStatePermission() {
+        mContext.enforceCallingOrSelfPermission(
+                Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE,
+                Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE
+                        + " permission required to read keyguard visibility");
+    }
+
+    private void dispatchKeyguardLockedState() {
+        mH.post(() -> {
+            final boolean isKeyguardLocked = mPolicy.isKeyguardShowing();
+            if (mDispatchedKeyguardLockedState == isKeyguardLocked) {
+                return;
+            }
+            final int n = mKeyguardLockedStateListeners.beginBroadcast();
+            for (int i = 0; i < n; i++) {
+                try {
+                    mKeyguardLockedStateListeners.getBroadcastItem(i).onKeyguardLockedStateChanged(
+                            isKeyguardLocked);
+                } catch (RemoteException e) {
+                    // Handled by the RemoteCallbackList.
+                }
+            }
+            mKeyguardLockedStateListeners.finishBroadcast();
+            mDispatchedKeyguardLockedState = isKeyguardLocked;
+        });
+    }
+
     @Override
     public void setSwitchingUser(boolean switching) {
         if (!checkCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL,
@@ -3869,7 +3936,13 @@
                 return null;
             }
 
+            // The bounds returned by the task represent the task's position on the screen. However,
+            // we need to specify a crop relative to the task's surface control. Therefore, shift
+            // the task's bounds to 0,0 so that we have the correct size and position within the
+            // task's surface control.
             task.getBounds(mTmpRect);
+            mTmpRect.offsetTo(0, 0);
+
             final SurfaceControl sc = task.getSurfaceControl();
             final SurfaceControl.ScreenshotHardwareBuffer buffer = SurfaceControl.captureLayers(
                     layerCaptureArgsBuilder.setLayer(sc).setSourceCrop(mTmpRect).build());
@@ -4361,10 +4434,11 @@
         }
     }
 
-    void reportKeepClearAreasChanged(Session session, IWindow window, List<Rect> keepClearAreas) {
+    void reportKeepClearAreasChanged(Session session, IWindow window,
+            List<Rect> restricted, List<Rect> unrestricted) {
         synchronized (mGlobalLock) {
             final WindowState win = windowForClientLocked(session, window, true);
-            if (win.setKeepClearAreas(keepClearAreas)) {
+            if (win.setKeepClearAreas(restricted, unrestricted)) {
                 win.getDisplayContent().updateKeepClearAreas();
             }
         }
@@ -4849,7 +4923,7 @@
         }
     }
 
-    private WindowState getFocusedWindowLocked() {
+    WindowState getFocusedWindowLocked() {
         // Return the focused window in the focused display.
         return mRoot.getTopFocusedDisplayContent().mCurrentFocus;
     }
@@ -5018,6 +5092,15 @@
         return null;
     }
 
+    @Nullable InputTarget getInputTargetFromWindowTokenLocked(IBinder windowToken) {
+        InputTarget window = mWindowMap.get(windowToken);
+        if (window != null) {
+            return window;
+        }
+        window = mEmbeddedWindowController.getByWindowToken(windowToken);
+        return window;
+    }
+
     void reportFocusChanged(IBinder oldToken, IBinder newToken) {
         InputTarget lastTarget;
         InputTarget newTarget;
@@ -6356,9 +6439,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,
@@ -6455,7 +6542,7 @@
         mRoot.forAllDisplays(dc -> {
             final int displayId = dc.getDisplayId();
             final InsetsControlTarget imeLayeringTarget = dc.getImeTarget(IME_TARGET_LAYERING);
-            final InsetsControlTarget imeInputTarget = dc.getImeTarget(IME_TARGET_INPUT);
+            final InputTarget imeInputTarget = dc.getImeInputTarget();
             final InsetsControlTarget imeControlTarget = dc.getImeTarget(IME_TARGET_CONTROL);
             if (imeLayeringTarget != null) {
                 pw.print("  imeLayeringTarget in display# "); pw.print(displayId);
@@ -7663,7 +7750,8 @@
                         + " imeTargetWindowToken=" + imeTargetWindowToken);
             }
             synchronized (mGlobalLock) {
-                final WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
+                InputTarget imeTarget =
+                    getInputTargetFromWindowTokenLocked(imeTargetWindowToken);
                 if (imeTarget != null) {
                     imeTarget.getDisplayContent().updateImeInputAndControlTarget(imeTarget);
                 }
@@ -7743,11 +7831,11 @@
             }
             synchronized (mGlobalLock) {
                 final DisplayContent displayContent = mRoot.getTopFocusedDisplayContent();
-                final WindowState window = mWindowMap.get(windowToken);
-                if (window == null) {
+                InputTarget target = getInputTargetFromWindowTokenLocked(windowToken);
+                if (target == null) {
                     return ImeClientFocusResult.NOT_IME_TARGET_WINDOW;
                 }
-                final int tokenDisplayId = window.getDisplayContent().getDisplayId();
+                final int tokenDisplayId = target.getDisplayContent().getDisplayId();
                 if (tokenDisplayId != displayId) {
                     Slog.e(TAG, "isInputMethodClientFocus: display ID mismatch."
                             + " from client: " + displayId
@@ -7760,7 +7848,7 @@
                     return ImeClientFocusResult.INVALID_DISPLAY_ID;
                 }
 
-                if (displayContent.isInputMethodClientFocus(uid, pid)) {
+                if (target.isInputMethodClientFocus(uid, pid)) {
                     return ImeClientFocusResult.HAS_IME_FOCUS;
                 }
                 // Okay, how about this...  what is the current focus?
@@ -7784,7 +7872,7 @@
         @Override
         public void showImePostLayout(IBinder imeTargetWindowToken) {
             synchronized (mGlobalLock) {
-                WindowState imeTarget = mWindowMap.get(imeTargetWindowToken);
+                InputTarget imeTarget = getInputTargetFromWindowTokenLocked(imeTargetWindowToken);
                 if (imeTarget == null) {
                     return;
                 }
@@ -7881,18 +7969,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));
             }
         }
 
@@ -8365,43 +8455,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();
@@ -8923,4 +9018,24 @@
         return Bitmap.wrapHardwareBuffer(taskSnapshot.getHardwareBuffer(),
                 taskSnapshot.getColorSpace());
     }
+
+    @Override
+    public void setRecentsAppBehindSystemBars(boolean behindSystemBars) {
+        if (!checkCallingPermission(START_TASKS_FROM_RECENTS, "setRecentsAppBehindSystemBars()")) {
+            throw new SecurityException("Requires START_TASKS_FROM_RECENTS permission");
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                final Task recentsApp = mRoot.getTask(task -> task.isActivityTypeHomeOrRecents()
+                        && task.getTopVisibleActivity() != null);
+                if (recentsApp != null) {
+                    recentsApp.getTask().setCanAffectSystemUiFlags(behindSystemBars);
+                    mWindowPlacerLocked.requestTraversal();
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 4c7891b..81344ac 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -21,15 +21,18 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.window.WindowContainerTransaction.Change.CHANGE_BOUNDS_TRANSACTION;
 import static android.window.WindowContainerTransaction.Change.CHANGE_BOUNDS_TRANSACTION_RECT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_CREATE_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_DELETE_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_LAUNCH_TASK;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_PENDING_INTENT;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_ACTIVITY_TO_TASK_FRAGMENT;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT_CHILDREN;
+import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_TASK_FRAGMENTS;
 import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT;
@@ -358,10 +361,11 @@
                 if (t != null && callback != null) {
                     syncId = startSyncWithOrganizer(callback);
                 }
+                final Transition transition = Transition.fromBinder(transitionToken);
                 // apply the incoming transaction before finish in case it alters the visibility
                 // of the participants.
                 if (t != null) {
-                    applyTransaction(t, syncId, null /*transition*/, caller);
+                    applyTransaction(t, syncId, null /*transition*/, caller, transition);
                 }
                 getTransitionController().finishTransition(transitionToken);
                 if (syncId >= 0) {
@@ -374,13 +378,20 @@
         }
     }
 
+    private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
+            @Nullable Transition transition, @NonNull CallerInfo caller) {
+        applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
+    }
+
     /**
      * @param syncId If non-null, this will be a sync-transaction.
      * @param transition A transition to collect changes into.
      * @param caller Info about the calling process.
+     * @param finishTransition The transition that is currently being finished.
      */
     private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
-            @Nullable Transition transition, @NonNull CallerInfo caller) {
+            @Nullable Transition transition, @NonNull CallerInfo caller,
+            @Nullable Transition finishTransition) {
         int effects = 0;
         ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Apply window transaction, syncId=%d", syncId);
         mService.deferWindowLayout();
@@ -433,7 +444,7 @@
                 for (int i = 0; i < hopSize; ++i) {
                     effects |= applyHierarchyOp(hops.get(i), effects, syncId, transition,
                             isInLockTaskMode, caller, t.getErrorCallbackToken(),
-                            t.getTaskFragmentOrganizer());
+                            t.getTaskFragmentOrganizer(), finishTransition);
                 }
             }
             // Queue-up bounds-change transactions for tasks which are now organized. Do
@@ -604,7 +615,7 @@
     private int applyHierarchyOp(WindowContainerTransaction.HierarchyOp hop, int effects,
             int syncId, @Nullable Transition transition, boolean isInLockTaskMode,
             @NonNull CallerInfo caller, @Nullable IBinder errorCallbackToken,
-            @Nullable ITaskFragmentOrganizer organizer) {
+            @Nullable ITaskFragmentOrganizer organizer, @Nullable Transition finishTransition) {
         final int type = hop.getType();
         switch (type) {
             case HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT: {
@@ -690,6 +701,8 @@
                     sendTaskFragmentOperationFailure(tf.getTaskFragmentOrganizer(),
                             errorCallbackToken,
                             convertStartFailureToThrowable(result, activityIntent));
+                } else {
+                    effects |= TRANSACT_EFFECTS_LIFECYCLE;
                 }
                 break;
             }
@@ -873,6 +886,30 @@
                 effects |= TRANSACT_EFFECTS_LIFECYCLE;
                 break;
             }
+            case HIERARCHY_OP_TYPE_RESTORE_TRANSIENT_ORDER: {
+                if (finishTransition == null) break;
+                final WindowContainer container = WindowContainer.fromBinder(hop.getContainer());
+                if (container == null) break;
+                final Task thisTask = container.asActivityRecord() != null
+                        ? container.asActivityRecord().getTask() : container.asTask();
+                if (thisTask == null) break;
+                final Task restoreAt = finishTransition.getTransientLaunchRestoreTarget(container);
+                if (restoreAt == null) break;
+                final TaskDisplayArea taskDisplayArea = thisTask.getTaskDisplayArea();
+                taskDisplayArea.moveRootTaskBehindRootTask(thisTask.getRootTask(), restoreAt);
+                break;
+            }
+            case HIERARCHY_OP_TYPE_ADD_RECT_INSETS_PROVIDER:
+                final Rect insetsProviderWindowContainer = hop.getInsetsProviderFrame();
+                final WindowContainer receiverWindowContainer =
+                        WindowContainer.fromBinder(hop.getContainer());
+                receiverWindowContainer.addLocalRectInsetsSourceProvider(
+                        insetsProviderWindowContainer, hop.getInsetsTypes());
+                break;
+            case HIERARCHY_OP_TYPE_REMOVE_INSETS_PROVIDER:
+                WindowContainer.fromBinder(hop.getContainer())
+                        .removeLocalInsetsSourceProvider(hop.getInsetsTypes());
+                break;
         }
         return effects;
     }
diff --git a/services/core/java/com/android/server/wm/WindowOrientationListener.java b/services/core/java/com/android/server/wm/WindowOrientationListener.java
index a967ea8..de87ab9 100644
--- a/services/core/java/com/android/server/wm/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/wm/WindowOrientationListener.java
@@ -1167,6 +1167,10 @@
                 if (mRotationResolverService == null) {
                     mRotationResolverService = LocalServices.getService(
                             RotationResolverInternal.class);
+                    if (mRotationResolverService == null) {
+                        finalizeRotation(reportedRotation);
+                        return;
+                    }
                 }
 
                 String packageName = null;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 87ef09e..db687f6 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -22,7 +22,6 @@
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.graphics.GraphicsProtos.dumpPointProto;
 import static android.hardware.display.DisplayManager.SWITCHING_TYPE_NONE;
@@ -120,7 +119,6 @@
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_EXIT;
 import static com.android.server.policy.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
 import static com.android.server.wm.AnimationSpecProto.MOVE;
-import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
 import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING;
 import static com.android.server.wm.DisplayContent.logsGestureExclusionRestrictions;
 import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
@@ -182,6 +180,7 @@
 import static com.android.server.wm.WindowStateProto.STACK_ID;
 import static com.android.server.wm.WindowStateProto.SURFACE_INSETS;
 import static com.android.server.wm.WindowStateProto.SURFACE_POSITION;
+import static com.android.server.wm.WindowStateProto.UNRESTRICTED_KEEP_CLEAR_AREAS;
 import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY;
 import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES;
@@ -264,6 +263,7 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.List;
 import java.util.function.Consumer;
@@ -483,6 +483,12 @@
      */
     private final List<Rect> mKeepClearAreas = new ArrayList<>();
 
+    /**
+     * Like mKeepClearAreas, but the unrestricted ones can be trusted to behave nicely.
+     * Floating windows (like Pip) will be moved away from them without applying restrictions.
+     */
+    private final List<Rect> mUnrestrictedKeepClearAreas = new ArrayList<>();
+
     // 0 = left, 1 = right
     private final int[] mLastRequestedExclusionHeight = {0, 0};
     private final int[] mLastGrantedExclusionHeight = {0, 0};
@@ -1024,51 +1030,86 @@
     }
 
     /**
-     * @return a list of rects that should ideally not be covered by floating windows like pip.
-     *         The returned rect coordinates are relative to the display origin.
+     * Collects all restricted and unrestricted keep-clear areas for this window.
+     * Keep-clear areas are rects that should ideally not be covered by floating windows like Pip.
+     * The system is more careful about restricted ones and may apply restrictions to them, while
+     * the unrestricted ones are considered safe.
+     *
+     * @param outRestricted collection to add restricted keep-clear areas to
+     * @param outUnrestricted collection to add unrestricted keep-clear areas to
      */
-    List<Rect> getKeepClearAreas() {
+    void getKeepClearAreas(Collection<Rect> outRestricted, Collection<Rect> outUnrestricted) {
         final Matrix tmpMatrix = new Matrix();
         final float[] tmpFloat9 = new float[9];
-        return getKeepClearAreas(tmpMatrix, tmpFloat9);
+        getKeepClearAreas(outRestricted, outUnrestricted, tmpMatrix, tmpFloat9);
     }
 
     /**
+     * Collects all restricted and unrestricted keep-clear areas for this window.
+     * Keep-clear areas are rects that should ideally not be covered by floating windows like Pip.
+     * The system is more careful about restricted ones and may apply restrictions to them, while
+     * the unrestricted ones are considered safe.
+     *
+     * @param outRestricted collection to add restricted keep-clear areas to
+     * @param outUnrestricted collection to add unrestricted keep-clear areas to
      * @param tmpMatrix a temporary matrix to be used for transformations
      * @param float9 a temporary array of 9 floats
-     *
-     * @return a list of rects that should ideally not be covered by floating windows like pip.
-     *         The returned rect coordinates are relative to the display origin.
      */
-    List<Rect> getKeepClearAreas(Matrix tmpMatrix, float[] float9) {
+    void getKeepClearAreas(Collection<Rect> outRestricted, Collection<Rect> outUnrestricted,
+            Matrix tmpMatrix, float[] float9) {
+        outRestricted.addAll(getRectsInScreenSpace(mKeepClearAreas, tmpMatrix, float9));
+        outUnrestricted.addAll(
+                getRectsInScreenSpace(mUnrestrictedKeepClearAreas, tmpMatrix, float9));
+    }
+
+    /**
+     * Transforms the given rects from window coordinate space to screen space.
+     */
+    List<Rect> getRectsInScreenSpace(List<Rect> rects, Matrix tmpMatrix, float[] float9) {
         getTransformationMatrix(float9, tmpMatrix);
 
-        // Translate all keep-clear rects to screen coordinates.
-        final List<Rect> transformedKeepClearAreas = new ArrayList<Rect>();
+        final List<Rect> transformedRects = new ArrayList<Rect>();
         final RectF tmpRect = new RectF();
         Rect curr;
-        for (Rect r : mKeepClearAreas) {
+        for (Rect r : rects) {
             tmpRect.set(r);
             tmpMatrix.mapRect(tmpRect);
             curr = new Rect();
             tmpRect.roundOut(curr);
-            transformedKeepClearAreas.add(curr);
+            transformedRects.add(curr);
         }
-        return transformedKeepClearAreas;
+        return transformedRects;
     }
 
     /**
-     * @param keepClearAreas the new keep-clear areas for this window. The rects should be defined
-     *                       in window coordinate space
+     * Sets the new keep-clear areas for this window. The rects should be defined in window
+     * coordinate space.
+     * Keep-clear areas can be restricted or unrestricted, depending on whether the app holds the
+     * {@link android.Manifest.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS} system permission.
+     * Restricted ones will be handled more carefully by the system. Restrictions may be applied.
+     * Unrestricted ones are considered safe. The system should move floating windows away from them
+     * without applying restrictions.
+     *
+     * @param restricted the new restricted keep-clear areas for this window
+     * @param unrestricted the new unrestricted keep-clear areas for this window
      *
      * @return true if there is a change in the list of keep-clear areas; false otherwise
      */
-    boolean setKeepClearAreas(List<Rect> keepClearAreas) {
-        if (mKeepClearAreas.equals(keepClearAreas)) {
+    boolean setKeepClearAreas(List<Rect> restricted, List<Rect> unrestricted) {
+        final boolean newRestrictedAreas = !mKeepClearAreas.equals(restricted);
+        final boolean newUnrestrictedAreas = !mUnrestrictedKeepClearAreas.equals(unrestricted);
+        if (!newRestrictedAreas && !newUnrestrictedAreas) {
             return false;
         }
-        mKeepClearAreas.clear();
-        mKeepClearAreas.addAll(keepClearAreas);
+        if (newRestrictedAreas) {
+            mKeepClearAreas.clear();
+            mKeepClearAreas.addAll(restricted);
+        }
+
+        if (newUnrestrictedAreas) {
+            mUnrestrictedKeepClearAreas.clear();
+            mUnrestrictedKeepClearAreas.addAll(unrestricted);
+        }
         return true;
     }
 
@@ -1149,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());
@@ -1602,14 +1644,14 @@
     }
 
     @Override
-    DisplayContent getDisplayContent() {
+    public DisplayContent getDisplayContent() {
         return mToken.getDisplayContent();
     }
 
     @Override
     void onDisplayChanged(DisplayContent dc) {
         if (dc != null && mDisplayContent != null && dc != mDisplayContent
-                && getImeInputTarget() == this) {
+                && mDisplayContent.getImeInputTarget() == this) {
             dc.updateImeInputAndControlTarget(getImeInputTarget());
             mDisplayContent.setImeInputTarget(null);
         }
@@ -1749,6 +1791,11 @@
         return mSession.mPid;
     }
 
+    @Override
+    public int getUid() {
+        return mSession.mUid;
+    }
+
     Task getTask() {
         return mActivityRecord != null ? mActivityRecord.getTask() : null;
     }
@@ -2348,7 +2395,7 @@
 
     @Override
     public void onConfigurationChanged(Configuration newParentConfig) {
-        if (getDisplayContent().getImeTarget(IME_TARGET_INPUT) != this && !isImeLayeringTarget()) {
+        if (getDisplayContent().getImeInputTarget() != this && !isImeLayeringTarget()) {
             super.onConfigurationChanged(newParentConfig);
             return;
         }
@@ -2424,7 +2471,7 @@
             dc.setImeLayeringTarget(null);
             dc.computeImeTarget(true /* updateImeTarget */);
         }
-        if (dc.getImeTarget(IME_TARGET_INPUT) == this) {
+        if (dc.getImeInputTarget() == this) {
             dc.updateImeInputAndControlTarget(null);
         }
 
@@ -3538,6 +3585,10 @@
         // Clear animating flags now, since the surface is now gone. (Note this is true even
         // if the surface is saved, to outside world the surface is still NO_SURFACE.)
         mAnimatingExit = false;
+
+        if (useBLASTSync()) {
+            immediatelyNotifyBlastSync();
+        }
     }
 
     void onSurfaceShownChanged(boolean shown) {
@@ -3578,11 +3629,13 @@
         final int requested = mLastRequestedExclusionHeight[side];
         final int granted = mLastGrantedExclusionHeight[side];
 
+        final boolean inSplitScreen = getTask() != null && getTask().inSplitScreen();
+
         FrameworkStatsLog.write(FrameworkStatsLog.EXCLUSION_RECT_STATE_CHANGED,
                 mAttrs.packageName, requested, requested - granted /* rejected */,
                 side + 1 /* Sides are 1-indexed in atoms.proto */,
                 (getConfiguration().orientation == ORIENTATION_LANDSCAPE),
-                isSplitScreenWindowingMode(getWindowingMode()), (int) duration);
+                inSplitScreen, (int) duration);
     }
 
     private void initExclusionRestrictions() {
@@ -4117,8 +4170,7 @@
         if (task == null) {
             return false;
         }
-        if (!inSplitScreenWindowingMode() && !inFreeformWindowingMode()
-                && !task.getRootTask().mCreatedByOrganizer) {
+        if (!inFreeformWindowingMode() && !task.getRootTask().mCreatedByOrganizer) {
             return false;
         }
         // TODO(157912944): formalize drag-resizing so that exceptions aren't hardcoded like this
@@ -4198,9 +4250,12 @@
         proto.write(FORCE_SEAMLESS_ROTATION, mForceSeamlesslyRotate);
         proto.write(HAS_COMPAT_SCALE, hasCompatScale());
         proto.write(GLOBAL_SCALE, mGlobalScale);
-        for (Rect r : getKeepClearAreas()) {
+        for (Rect r : mKeepClearAreas) {
             r.dumpDebug(proto, KEEP_CLEAR_AREAS);
         }
+        for (Rect r : mUnrestrictedKeepClearAreas) {
+            r.dumpDebug(proto, UNRESTRICTED_KEEP_CLEAR_AREAS);
+        }
         proto.end(token);
     }
 
@@ -4369,7 +4424,8 @@
         }
         pw.println(prefix + "isOnScreen=" + isOnScreen());
         pw.println(prefix + "isVisible=" + isVisible());
-        pw.println(prefix + "keepClearAreas=" + getKeepClearAreas());
+        pw.println(prefix + "keepClearAreas: restricted=" + mKeepClearAreas
+                          + ", unrestricted=" + mUnrestrictedKeepClearAreas);
         if (dumpAll) {
             final String visibilityString = mRequestedVisibilities.toString();
             if (!visibilityString.isEmpty()) {
@@ -4992,9 +5048,6 @@
         if (isAnimating()) {
             return;
         }
-        if (mWmService.mAccessibilityController.hasCallbacks()) {
-            mWmService.mAccessibilityController.onSomeWindowResizedOrMoved(getDisplayId());
-        }
 
         if (!isSelfOrAncestorWindowAnimatingExit()) {
             return;
@@ -5599,7 +5652,8 @@
      * @return {@link InsetsControlTarget} of host that controls the IME.
      *         When window is doesn't have a parent, it is returned as-is.
      */
-    InsetsControlTarget getImeControlTarget() {
+    @Override
+    public InsetsControlTarget getImeControlTarget() {
         return getDisplayContent().getImeHostOrFallback(this);
     }
 
@@ -5734,8 +5788,8 @@
     }
 
     WindowState getImeInputTarget() {
-        final InsetsControlTarget target = mDisplayContent.getImeTarget(IME_TARGET_INPUT);
-        return target != null ? target.getWindow() : null;
+        final InputTarget target = mDisplayContent.getImeInputTarget();
+        return target != null ? target.getWindowState() : null;
     }
 
     void forceReportingResized() {
@@ -5934,15 +5988,6 @@
         finishDrawing(null);
         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
@@ -5979,10 +6024,6 @@
         if (mRedrawForSyncReported) {
             return false;
         }
-        final Task task = getTask();
-        if (task != null && task.getMainWindowSizeChangeTransaction() != null) {
-            return true;
-        }
         return useBLASTSync();
     }
 
@@ -6120,4 +6161,37 @@
         mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
         mGivenTouchableRegion.setEmpty();
     }
+
+    @Override
+    public boolean shouldControlIme() {
+        return !inMultiWindowMode();
+    }
+
+    @Override
+    public boolean canScreenshotIme() {
+        return !isSecureLocked();
+    }
+
+    @Override
+    public ActivityRecord getActivityRecord() {
+        return mActivityRecord;
+    }
+
+    @Override
+    public void unfreezeInsetsAfterStartInput() {
+        if (mActivityRecord != null) {
+            mActivityRecord.mImeInsetsFrozenUntilStartInput = false;
+        }
+    }
+
+    @Override
+    public boolean isInputMethodClientFocus(int uid, int pid) {
+        return getDisplayContent().isInputMethodClientFocus(uid, pid);
+    }
+
+    @Override
+    public void dumpProto(ProtoOutputStream proto, long fieldId,
+                          @WindowTraceLogLevel int logLevel) {
+        dumpDebug(proto, fieldId, logLevel);
+    }
 }
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/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 665857c..c2414e7 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -33,6 +33,7 @@
 
 import android.os.Debug;
 import android.os.Trace;
+import android.util.EventLog;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
@@ -124,6 +125,10 @@
         setShown(false);
         try {
             transaction.hide(mSurfaceControl);
+            if (mAnimator.mIsWallpaper) {
+                EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
+                        mAnimator.mWin.getDisplayId(), 0 /* request hidden */);
+            }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Exception hiding surface in " + this);
         }
@@ -249,6 +254,10 @@
 
         setShown(true);
         t.show(mSurfaceControl);
+        if (mAnimator.mIsWallpaper) {
+            EventLog.writeEvent(EventLogTags.WM_WALLPAPER_SURFACE,
+                    mAnimator.mWin.getDisplayId(), 1 /* request shown */);
+        }
         return true;
     }
 
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 3c122b0..31b5579 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -96,8 +96,6 @@
     jmethodID notifyNoFocusedWindowAnr;
     jmethodID notifyWindowUnresponsive;
     jmethodID notifyWindowResponsive;
-    jmethodID notifyMonitorUnresponsive;
-    jmethodID notifyMonitorResponsive;
     jmethodID notifyFocusChanged;
     jmethodID notifySensorEvent;
     jmethodID notifySensorAccuracy;
@@ -308,10 +306,9 @@
     void notifyConfigurationChanged(nsecs_t when) override;
     // ANR-related callbacks -- start
     void notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle>& handle) override;
-    void notifyWindowUnresponsive(const sp<IBinder>& token, const std::string& reason) override;
-    void notifyWindowResponsive(const sp<IBinder>& token) override;
-    void notifyMonitorUnresponsive(int32_t pid, const std::string& reason) override;
-    void notifyMonitorResponsive(int32_t pid) override;
+    void notifyWindowUnresponsive(const sp<IBinder>& token, std::optional<int32_t> pid,
+                                  const std::string& reason) override;
+    void notifyWindowResponsive(const sp<IBinder>& token, std::optional<int32_t> pid) override;
     // ANR-related callbacks -- end
     void notifyInputChannelBroken(const sp<IBinder>& token) override;
     void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken) override;
@@ -838,6 +835,7 @@
 }
 
 void NativeInputManager::notifyWindowUnresponsive(const sp<IBinder>& token,
+                                                  std::optional<int32_t> pid,
                                                   const std::string& reason) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
     ALOGD("notifyWindowUnresponsive");
@@ -851,11 +849,12 @@
     ScopedLocalRef<jstring> reasonObj(env, env->NewStringUTF(reason.c_str()));
 
     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowUnresponsive, tokenObj,
-                        reasonObj.get());
+                        pid.value_or(0), pid.has_value(), reasonObj.get());
     checkAndClearExceptionFromCallback(env, "notifyWindowUnresponsive");
 }
 
-void NativeInputManager::notifyWindowResponsive(const sp<IBinder>& token) {
+void NativeInputManager::notifyWindowResponsive(const sp<IBinder>& token,
+                                                std::optional<int32_t> pid) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
     ALOGD("notifyWindowResponsive");
 #endif
@@ -866,39 +865,11 @@
 
     jobject tokenObj = javaObjectForIBinder(env, token);
 
-    env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowResponsive, tokenObj);
+    env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowResponsive, tokenObj,
+                        pid.value_or(0), pid.has_value());
     checkAndClearExceptionFromCallback(env, "notifyWindowResponsive");
 }
 
-void NativeInputManager::notifyMonitorUnresponsive(int32_t pid, const std::string& reason) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-    ALOGD("notifyMonitorUnresponsive");
-#endif
-    ATRACE_CALL();
-
-    JNIEnv* env = jniEnv();
-    ScopedLocalFrame localFrame(env);
-
-    ScopedLocalRef<jstring> reasonObj(env, env->NewStringUTF(reason.c_str()));
-
-    env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyMonitorUnresponsive, pid,
-                        reasonObj.get());
-    checkAndClearExceptionFromCallback(env, "notifyMonitorUnresponsive");
-}
-
-void NativeInputManager::notifyMonitorResponsive(int32_t pid) {
-#if DEBUG_INPUT_DISPATCHER_POLICY
-    ALOGD("notifyMonitorResponsive");
-#endif
-    ATRACE_CALL();
-
-    JNIEnv* env = jniEnv();
-    ScopedLocalFrame localFrame(env);
-
-    env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyMonitorResponsive, pid);
-    checkAndClearExceptionFromCallback(env, "notifyMonitorResponsive");
-}
-
 void NativeInputManager::notifyInputChannelBroken(const sp<IBinder>& token) {
 #if DEBUG_INPUT_DISPATCHER_POLICY
     ALOGD("notifyInputChannelBroken");
@@ -2506,16 +2477,10 @@
                   "(Landroid/view/InputApplicationHandle;)V");
 
     GET_METHOD_ID(gServiceClassInfo.notifyWindowUnresponsive, clazz, "notifyWindowUnresponsive",
-                  "(Landroid/os/IBinder;Ljava/lang/String;)V");
-
-    GET_METHOD_ID(gServiceClassInfo.notifyMonitorUnresponsive, clazz, "notifyMonitorUnresponsive",
-                  "(ILjava/lang/String;)V");
+                  "(Landroid/os/IBinder;IZLjava/lang/String;)V");
 
     GET_METHOD_ID(gServiceClassInfo.notifyWindowResponsive, clazz, "notifyWindowResponsive",
-                  "(Landroid/os/IBinder;)V");
-
-    GET_METHOD_ID(gServiceClassInfo.notifyMonitorResponsive, clazz, "notifyMonitorResponsive",
-                  "(I)V");
+                  "(Landroid/os/IBinder;IZ)V");
 
     GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
             "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index a9c6b8d..9fa23c2 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -50,6 +50,7 @@
 #include "android_runtime/Log.h"
 #include "gnss/AGnss.h"
 #include "gnss/AGnssRil.h"
+#include "gnss/Gnss.h"
 #include "gnss/GnssAntennaInfo.h"
 #include "gnss/GnssAntennaInfoCallback.h"
 #include "gnss/GnssBatching.h"
@@ -68,18 +69,7 @@
 
 static jclass class_gnssPowerStats;
 
-static jmethodID method_reportLocation;
-static jmethodID method_reportStatus;
-static jmethodID method_reportSvStatus;
-static jmethodID method_reportNmea;
-static jmethodID method_setTopHalCapabilities;
-static jmethodID method_setGnssYearOfHardware;
-static jmethodID method_setGnssHardwareModelName;
-static jmethodID method_psdsDownloadRequest;
 static jmethodID method_reportNiNotification;
-static jmethodID method_requestLocation;
-static jmethodID method_requestUtcTime;
-static jmethodID method_reportGnssServiceDied;
 static jmethodID method_reportGnssPowerStats;
 static jmethodID method_reportNfwNotification;
 static jmethodID method_isInEmergencySession;
@@ -92,7 +82,6 @@
 using android::String16;
 using android::wp;
 using android::binder::Status;
-using android::gnss::GnssConfigurationInterface;
 
 using android::hardware::Return;
 using android::hardware::Void;
@@ -128,12 +117,8 @@
 using android::hardware::gnss::GnssPowerStats;
 using android::hardware::gnss::IGnssPowerIndication;
 using android::hardware::gnss::IGnssPowerIndicationCallback;
-using android::hardware::gnss::PsdsType;
 
-using IAGnssAidl = android::hardware::gnss::IAGnss;
-using IAGnssRilAidl = android::hardware::gnss::IAGnssRil;
 using IGnssAidl = android::hardware::gnss::IGnss;
-using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback;
 using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching;
 using IGnssDebugAidl = android::hardware::gnss::IGnssDebug;
 using IGnssPsdsAidl = android::hardware::gnss::IGnssPsds;
@@ -142,575 +127,30 @@
 using GnssLocationAidl = android::hardware::gnss::GnssLocation;
 using IGnssAntennaInfoAidl = android::hardware::gnss::IGnssAntennaInfo;
 
-struct GnssDeathRecipient : virtual public hidl_death_recipient
-{
-    // hidl_death_recipient interface
-    virtual void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
-        ALOGE("IGNSS hidl service failed, trying to recover...");
-
-        JNIEnv* env = android::AndroidRuntime::getJNIEnv();
-        env->CallVoidMethod(android::mCallbacksObj, method_reportGnssServiceDied);
-    }
-};
-
-// Must match the value from GnssMeasurement.java
-static const uint32_t SVID_FLAGS_HAS_BASEBAND_CN0 = (1<<4);
-
-sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
-sp<IGnss_V1_0> gnssHal = nullptr;
-sp<IGnss_V1_1> gnssHal_V1_1 = nullptr;
-sp<IGnss_V2_0> gnssHal_V2_0 = nullptr;
-sp<IGnss_V2_1> gnssHal_V2_1 = nullptr;
-sp<IGnssAidl> gnssHalAidl = nullptr;
-sp<IGnssBatchingAidl> gnssBatchingAidlIface = nullptr;
-sp<IGnssPsdsAidl> gnssPsdsAidlIface = nullptr;
-sp<IGnssXtra> gnssXtraIface = nullptr;
 sp<IGnssNi> gnssNiIface = nullptr;
 sp<IGnssPowerIndication> gnssPowerIndicationIface = nullptr;
 
-std::unique_ptr<GnssConfigurationInterface> gnssConfigurationIface = nullptr;
+std::unique_ptr<android::gnss::GnssHal> gnssHal = nullptr;
+std::unique_ptr<android::gnss::AGnssInterface> agnssIface = nullptr;
+std::unique_ptr<android::gnss::AGnssRilInterface> agnssRilIface = nullptr;
+std::unique_ptr<android::gnss::GnssAntennaInfoInterface> gnssAntennaInfoIface = nullptr;
+std::unique_ptr<android::gnss::GnssConfigurationInterface> gnssConfigurationIface = nullptr;
 std::unique_ptr<android::gnss::GnssMeasurementInterface> gnssMeasurementIface = nullptr;
 std::unique_ptr<android::gnss::GnssNavigationMessageInterface> gnssNavigationMessageIface = nullptr;
 std::unique_ptr<android::gnss::GnssBatchingInterface> gnssBatchingIface = nullptr;
-std::unique_ptr<android::gnss::GnssGeofenceInterface> gnssGeofencingIface = nullptr;
-std::unique_ptr<android::gnss::AGnssInterface> agnssIface = nullptr;
 std::unique_ptr<android::gnss::GnssDebugInterface> gnssDebugIface = nullptr;
-std::unique_ptr<android::gnss::AGnssRilInterface> agnssRilIface = nullptr;
+std::unique_ptr<android::gnss::GnssGeofenceInterface> gnssGeofencingIface = nullptr;
+std::unique_ptr<android::gnss::GnssPsdsInterface> gnssPsdsIface = nullptr;
 std::unique_ptr<android::gnss::GnssVisibilityControlInterface> gnssVisibilityControlIface = nullptr;
-std::unique_ptr<android::gnss::GnssAntennaInfoInterface> gnssAntennaInfoIface = nullptr;
 std::unique_ptr<android::gnss::MeasurementCorrectionsInterface> gnssMeasurementCorrectionsIface =
         nullptr;
 
-#define WAKE_LOCK_NAME  "GPS"
-
 namespace android {
 
 namespace {
 
-// Returns true if location has lat/long information.
-bool hasLatLong(const GnssLocationAidl& location) {
-    return (location.gnssLocationFlags & GnssLocationAidl::HAS_LAT_LONG) != 0;
-}
-
-// Returns true if location has lat/long information.
-bool hasLatLong(const GnssLocation_V1_0& location) {
-    return (static_cast<uint32_t>(location.gnssLocationFlags) &
-            GnssLocationFlags::HAS_LAT_LONG) != 0;
-}
-
-// Returns true if location has lat/long information.
-bool hasLatLong(const GnssLocation_V2_0& location) {
-    return hasLatLong(location.v1_0);
-}
-
-bool isSvStatusRegistered = false;
-bool isNmeaRegistered = false;
-
 }  // namespace
 
-static inline jboolean boolToJbool(bool value) {
-    return value ? JNI_TRUE : JNI_FALSE;
-}
-
-static GnssLocationAidl createGnssLocation(jint gnssLocationFlags, jdouble latitudeDegrees,
-                                           jdouble longitudeDegrees, jdouble altitudeMeters,
-                                           jfloat speedMetersPerSec, jfloat bearingDegrees,
-                                           jfloat horizontalAccuracyMeters,
-                                           jfloat verticalAccuracyMeters,
-                                           jfloat speedAccuracyMetersPerSecond,
-                                           jfloat bearingAccuracyDegrees, jlong timestamp,
-                                           jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
-                                           jdouble elapsedRealtimeUncertaintyNanos) {
-    GnssLocationAidl location;
-    location.gnssLocationFlags = static_cast<int>(gnssLocationFlags);
-    location.latitudeDegrees = static_cast<double>(latitudeDegrees);
-    location.longitudeDegrees = static_cast<double>(longitudeDegrees);
-    location.altitudeMeters = static_cast<double>(altitudeMeters);
-    location.speedMetersPerSec = static_cast<double>(speedMetersPerSec);
-    location.bearingDegrees = static_cast<double>(bearingDegrees);
-    location.horizontalAccuracyMeters = static_cast<double>(horizontalAccuracyMeters);
-    location.verticalAccuracyMeters = static_cast<double>(verticalAccuracyMeters);
-    location.speedAccuracyMetersPerSecond = static_cast<double>(speedAccuracyMetersPerSecond);
-    location.bearingAccuracyDegrees = static_cast<double>(bearingAccuracyDegrees);
-    location.timestampMillis = static_cast<uint64_t>(timestamp);
-
-    location.elapsedRealtime.flags = static_cast<int>(elapsedRealtimeFlags);
-    location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
-    location.elapsedRealtime.timeUncertaintyNs =
-            static_cast<double>(elapsedRealtimeUncertaintyNanos);
-
-    return location;
-}
-
-static GnssLocation_V1_0 createGnssLocation_V1_0(
-        jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
-        jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
-        jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
-        jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
-        jlong timestamp) {
-    GnssLocation_V1_0 location;
-    location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
-    location.latitudeDegrees = static_cast<double>(latitudeDegrees);
-    location.longitudeDegrees = static_cast<double>(longitudeDegrees);
-    location.altitudeMeters = static_cast<double>(altitudeMeters);
-    location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
-    location.bearingDegrees = static_cast<float>(bearingDegrees);
-    location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
-    location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
-    location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
-    location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
-    location.timestamp = static_cast<uint64_t>(timestamp);
-
-    return location;
-}
-
-static GnssLocation_V2_0 createGnssLocation_V2_0(
-        jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
-        jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
-        jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
-        jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
-        jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
-        jdouble elapsedRealtimeUncertaintyNanos) {
-    GnssLocation_V2_0 location;
-    location.v1_0 = createGnssLocation_V1_0(
-            gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
-            speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
-            verticalAccuracyMeters, speedAccuracyMetersPerSecond,
-            bearingAccuracyDegrees, timestamp);
-
-    location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
-    location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
-    location.elapsedRealtime.timeUncertaintyNs = static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
-
-    return location;
-}
-
-/*
- * GnssCallback class implements the callback methods for IGnss interface.
- */
-struct GnssCallback : public IGnssCallback_V2_1 {
-    Return<void> gnssLocationCb(const GnssLocation_V1_0& location) override;
-    Return<void> gnssStatusCb(const IGnssCallback_V1_0::GnssStatusValue status) override;
-    Return<void> gnssSvStatusCb(const IGnssCallback_V1_0::GnssSvStatus& svStatus) override {
-        return gnssSvStatusCbImpl<IGnssCallback_V1_0::GnssSvStatus, IGnssCallback_V1_0::GnssSvInfo>(
-                svStatus);
-    }
-    Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
-    Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
-    Return<void> gnssAcquireWakelockCb() override;
-    Return<void> gnssReleaseWakelockCb() override;
-    Return<void> gnssRequestTimeCb() override;
-    Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
-
-    Return<void> gnssSetSystemInfoCb(const IGnssCallback_V1_0::GnssSystemInfo& info) override;
-
-    // New in 1.1
-    Return<void> gnssNameCb(const android::hardware::hidl_string& name) override;
-
-    // New in 2.0
-    Return<void> gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool isUserEmergency)
-            override;
-    Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
-    Return<void> gnssLocationCb_2_0(const GnssLocation_V2_0& location) override;
-    Return<void> gnssSvStatusCb_2_0(const hidl_vec<IGnssCallback_V2_0::GnssSvInfo>& svInfoList) override {
-        return gnssSvStatusCbImpl<hidl_vec<IGnssCallback_V2_0::GnssSvInfo>,
-                                  IGnssCallback_V1_0::GnssSvInfo>(svInfoList);
-    }
-
-    // New in 2.1
-    Return<void> gnssSvStatusCb_2_1(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList) override {
-        return gnssSvStatusCbImpl<hidl_vec<IGnssCallback_V2_1::GnssSvInfo>,
-                                  IGnssCallback_V1_0::GnssSvInfo>(svInfoList);
-    }
-    Return<void> gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override;
-
-    // TODO: Reconsider allocation cost vs threadsafety on these statics
-    static const char* sNmeaString;
-    static size_t sNmeaStringLength;
-
-    template <class T>
-    static Return<void> gnssLocationCbImpl(const T& location);
-
-    template <class T_list, class T_sv_info>
-    static Return<void> gnssSvStatusCbImpl(const T_list& svStatus);
-
-private:
-    template <class T>
-    static uint32_t getHasBasebandCn0DbHzFlag(const T& svStatus) {
-        return 0;
-    }
-
-    template <class T>
-    static double getBasebandCn0DbHz(const T& svStatus, size_t i) {
-        return 0.0;
-    }
-
-    template <class T>
-    static uint32_t getGnssSvInfoListSize(const T& svInfoList) {
-        return svInfoList.size();
-    }
-
-    static const IGnssCallbackAidl::GnssSvInfo& getGnssSvInfoOfIndex(
-            const std::vector<IGnssCallbackAidl::GnssSvInfo>& svInfoList, size_t i) {
-        return svInfoList[i];
-    }
-
-    static const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
-            const IGnssCallback_V1_0::GnssSvStatus& svStatus, size_t i) {
-        return svStatus.gnssSvList.data()[i];
-    }
-
-    static const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
-            const hidl_vec<IGnssCallback_V2_0::GnssSvInfo>& svInfoList, size_t i) {
-        return svInfoList[i].v1_0;
-    }
-
-    static const IGnssCallback_V1_0::GnssSvInfo& getGnssSvInfoOfIndex(
-            const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList, size_t i) {
-        return svInfoList[i].v2_0.v1_0;
-    }
-
-    template <class T>
-    static uint32_t getConstellationType(const T& svInfoList, size_t i) {
-        return static_cast<uint32_t>(svInfoList[i].constellation);
-    }
-};
-
-Return<void> GnssCallback::gnssNameCb(const android::hardware::hidl_string& name) {
-    ALOGD("%s: name=%s\n", __func__, name.c_str());
-
-    JNIEnv* env = getJniEnv();
-    jstring jstringName = env->NewStringUTF(name.c_str());
-    env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
-    if (jstringName) {
-        env->DeleteLocalRef(jstringName);
-    }
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-
-    return Void();
-}
-
-const char* GnssCallback::sNmeaString = nullptr;
-size_t GnssCallback::sNmeaStringLength = 0;
-
-template<class T>
-Return<void> GnssCallback::gnssLocationCbImpl(const T& location) {
-    JNIEnv* env = getJniEnv();
-
-    jobject jLocation = translateGnssLocation(env, location);
-
-    env->CallVoidMethod(mCallbacksObj,
-                        method_reportLocation,
-                        boolToJbool(hasLatLong(location)),
-                        jLocation);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    env->DeleteLocalRef(jLocation);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssLocationCb(const GnssLocation_V1_0& location) {
-    return gnssLocationCbImpl<GnssLocation_V1_0>(location);
-}
-
-Return<void>
-GnssCallback::gnssLocationCb_2_0(const GnssLocation_V2_0& location) {
-    return gnssLocationCbImpl<GnssLocation_V2_0>(location);
-}
-
-Return<void> GnssCallback::gnssStatusCb(const IGnssCallback_V2_0::GnssStatusValue status) {
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-template<>
-uint32_t GnssCallback::getHasBasebandCn0DbHzFlag(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>&
-        svStatus) {
-    return SVID_FLAGS_HAS_BASEBAND_CN0;
-}
-
-template <>
-uint32_t GnssCallback::getHasBasebandCn0DbHzFlag(
-        const std::vector<IGnssCallbackAidl::GnssSvInfo>& svStatus) {
-    return SVID_FLAGS_HAS_BASEBAND_CN0;
-}
-
-template <>
-double GnssCallback::getBasebandCn0DbHz(
-        const std::vector<IGnssCallbackAidl::GnssSvInfo>& svInfoList, size_t i) {
-    return svInfoList[i].basebandCN0DbHz;
-}
-
-template<>
-double GnssCallback::getBasebandCn0DbHz(const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList,
-        size_t i) {
-    return svInfoList[i].basebandCN0DbHz;
-}
-
-template <>
-uint32_t GnssCallback::getGnssSvInfoListSize(const IGnssCallback_V1_0::GnssSvStatus& svStatus) {
-    return svStatus.numSvs;
-}
-
-template <>
-uint32_t GnssCallback::getConstellationType(const IGnssCallback_V1_0::GnssSvStatus& svStatus,
-                                            size_t i) {
-    return static_cast<uint32_t>(svStatus.gnssSvList.data()[i].constellation);
-}
-
-template <>
-uint32_t GnssCallback::getConstellationType(
-        const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList, size_t i) {
-    return static_cast<uint32_t>(svInfoList[i].v2_0.constellation);
-}
-
-template <class T_list, class T_sv_info>
-Return<void> GnssCallback::gnssSvStatusCbImpl(const T_list& svStatus) {
-    // In HIDL or AIDL v1, if no listener is registered, do not report svInfoList to the framework.
-    if (gnssHalAidl == nullptr || gnssHalAidl->getInterfaceVersion() <= 1) {
-        if (!isSvStatusRegistered) {
-            return Void();
-        }
-    }
-
-    JNIEnv* env = getJniEnv();
-
-    uint32_t listSize = getGnssSvInfoListSize(svStatus);
-
-    jintArray svidWithFlagArray = env->NewIntArray(listSize);
-    jfloatArray cn0Array = env->NewFloatArray(listSize);
-    jfloatArray elevArray = env->NewFloatArray(listSize);
-    jfloatArray azimArray = env->NewFloatArray(listSize);
-    jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
-    jfloatArray basebandCn0Array = env->NewFloatArray(listSize);
-
-    jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
-    jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
-    jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
-    jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
-    jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
-    jfloat* basebandCn0s = env->GetFloatArrayElements(basebandCn0Array, 0);
-
-    /*
-     * Read GNSS SV info.
-     */
-    for (size_t i = 0; i < listSize; ++i) {
-        enum ShiftWidth: uint8_t {
-            SVID_SHIFT_WIDTH = 12,
-            CONSTELLATION_TYPE_SHIFT_WIDTH = 8
-        };
-
-        const T_sv_info& info = getGnssSvInfoOfIndex(svStatus, i);
-        svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
-            (getConstellationType(svStatus, i) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
-            static_cast<uint32_t>(info.svFlag);
-        cn0s[i] = info.cN0Dbhz;
-        elev[i] = info.elevationDegrees;
-        azim[i] = info.azimuthDegrees;
-        carrierFreq[i] = info.carrierFrequencyHz;
-        svidWithFlags[i] |= getHasBasebandCn0DbHzFlag(svStatus);
-        basebandCn0s[i] = getBasebandCn0DbHz(svStatus, i);
-    }
-
-    env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
-    env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
-    env->ReleaseFloatArrayElements(elevArray, elev, 0);
-    env->ReleaseFloatArrayElements(azimArray, azim, 0);
-    env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
-    env->ReleaseFloatArrayElements(basebandCn0Array, basebandCn0s, 0);
-
-    env->CallVoidMethod(mCallbacksObj, method_reportSvStatus,
-            static_cast<jint>(listSize), svidWithFlagArray, cn0Array, elevArray, azimArray,
-            carrierFreqArray, basebandCn0Array);
-
-    env->DeleteLocalRef(svidWithFlagArray);
-    env->DeleteLocalRef(cn0Array);
-    env->DeleteLocalRef(elevArray);
-    env->DeleteLocalRef(azimArray);
-    env->DeleteLocalRef(carrierFreqArray);
-    env->DeleteLocalRef(basebandCn0Array);
-
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssNmeaCb(int64_t timestamp,
-                                      const ::android::hardware::hidl_string& nmea) {
-    // In HIDL, if no listener is registered, do not report nmea to the framework.
-    if (!isNmeaRegistered) {
-        return Void();
-    }
-    JNIEnv* env = getJniEnv();
-    /*
-     * The Java code will call back to read these values.
-     * We do this to avoid creating unnecessary String objects.
-     */
-    sNmeaString = nmea.c_str();
-    sNmeaStringLength = nmea.size();
-
-    env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
-    ALOGD("%s: %du\n", __func__, capabilities);
-
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
-    return GnssCallback::gnssSetCapabilitesCb(capabilities);
-}
-
-Return<void> GnssCallback::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) {
-    return GnssCallback::gnssSetCapabilitesCb(capabilities);
-}
-
-Return<void> GnssCallback::gnssAcquireWakelockCb() {
-    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssReleaseWakelockCb() {
-    release_wake_lock(WAKE_LOCK_NAME);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssRequestTimeCb() {
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssRequestLocationCb(const bool independentFromGnss) {
-    return GnssCallback::gnssRequestLocationCb_2_0(independentFromGnss, /* isUserEmergency= */
-            false);
-}
-
-Return<void> GnssCallback::gnssRequestLocationCb_2_0(const bool independentFromGnss, const bool
-        isUserEmergency) {
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss),
-            boolToJbool(isUserEmergency));
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSystemInfo& info) {
-    ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
-
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
-                        info.yearOfHw);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-class GnssCallbackAidl : public android::hardware::gnss::BnGnssCallback {
-public:
-    Status gnssSetCapabilitiesCb(const int capabilities) override;
-    Status gnssStatusCb(const GnssStatusValue status) override;
-    Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
-    Status gnssLocationCb(const GnssLocationAidl& location) override;
-    Status gnssNmeaCb(const int64_t timestamp, const std::string& nmea) override;
-    Status gnssAcquireWakelockCb() override;
-    Status gnssReleaseWakelockCb() override;
-    Status gnssSetSystemInfoCb(const GnssSystemInfo& info) override;
-    Status gnssRequestTimeCb() override;
-    Status gnssRequestLocationCb(const bool independentFromGnss,
-                                 const bool isUserEmergency) override;
-};
-
-Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
-    ALOGD("GnssCallbackAidl::%s: %du\n", __func__, capabilities);
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue status) {
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
-    GnssCallback::gnssSvStatusCbImpl<std::vector<GnssSvInfo>, GnssSvInfo>(svInfoList);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssLocationCb(const GnssLocationAidl& location) {
-    GnssCallback::gnssLocationCbImpl<GnssLocationAidl>(location);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssNmeaCb(const int64_t timestamp, const std::string& nmea) {
-    // In AIDL v1, if no listener is registered, do not report nmea to the framework.
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() <= 1) {
-        if (!isNmeaRegistered) {
-            return Status::ok();
-        }
-    }
-    JNIEnv* env = getJniEnv();
-    /*
-     * The Java code will call back to read these values.
-     * We do this to avoid creating unnecessary String objects.
-     */
-    GnssCallback::sNmeaString = nmea.c_str();
-    GnssCallback::sNmeaStringLength = nmea.size();
-
-    env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssAcquireWakelockCb() {
-    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssReleaseWakelockCb() {
-    release_wake_lock(WAKE_LOCK_NAME);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssSetSystemInfoCb(const GnssSystemInfo& info) {
-    ALOGD("%s: yearOfHw=%d, name=%s\n", __func__, info.yearOfHw, info.name.c_str());
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, info.yearOfHw);
-    jstring jstringName = env->NewStringUTF(info.name.c_str());
-    env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
-    if (jstringName) {
-        env->DeleteLocalRef(jstringName);
-    }
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssRequestTimeCb() {
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Status::ok();
-}
-
-Status GnssCallbackAidl::gnssRequestLocationCb(const bool independentFromGnss,
-                                               const bool isUserEmergency) {
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss),
-                        boolToJbool(isUserEmergency));
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Status::ok();
-}
-
 /*
  * GnssPowerIndicationCallback class implements the callback methods for the IGnssPowerIndication
  * interface.
@@ -756,35 +196,6 @@
 }
 
 /*
- * GnssPsdsCallback class implements the callback methods for the IGnssPsds
- * interface.
- */
-struct GnssPsdsCallbackAidl : public android::hardware::gnss::BnGnssPsdsCallback {
-    Status downloadRequestCb(PsdsType psdsType) override {
-        ALOGD("%s. psdsType: %d", __func__, static_cast<int32_t>(psdsType));
-        JNIEnv* env = getJniEnv();
-        env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, psdsType);
-        checkAndClearExceptionFromCallback(env, __FUNCTION__);
-        return Status::ok();
-    }
-};
-
-/**
- * GnssXtraCallback class implements the callback methods for the IGnssXtra
- * interface.
- */
-class GnssXtraCallback : public IGnssXtraCallback {
-    Return<void> downloadRequestCb() override;
-};
-
-Return<void> GnssXtraCallback::downloadRequestCb() {
-    JNIEnv* env = getJniEnv();
-    env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, /* psdsType= */ 1);
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return Void();
-}
-
-/*
  * GnssNiCallback implements callback methods required by the IGnssNi interface.
  */
 struct GnssNiCallback : public IGnssNiCallback {
@@ -822,41 +233,7 @@
 
 /* Initializes the GNSS service handle. */
 static void android_location_gnss_hal_GnssNative_set_gps_service_handle() {
-    gnssHalAidl = waitForVintfService<IGnssAidl>();
-    if (gnssHalAidl != nullptr) {
-        ALOGD("Successfully got GNSS AIDL handle. Version=%d.", gnssHalAidl->getInterfaceVersion());
-        if (gnssHalAidl->getInterfaceVersion() >= 2) {
-            return;
-        }
-    }
-
-    ALOGD("Trying IGnss_V2_1::getService()");
-    gnssHal_V2_1 = IGnss_V2_1::getService();
-    if (gnssHal_V2_1 != nullptr) {
-        gnssHal = gnssHal_V2_1;
-        gnssHal_V2_0 = gnssHal_V2_1;
-        gnssHal_V1_1 = gnssHal_V2_1;
-        gnssHal = gnssHal_V2_1;
-        return;
-    }
-
-    ALOGD("gnssHal 2.1 was null, trying 2.0");
-    gnssHal_V2_0 = IGnss_V2_0::getService();
-    if (gnssHal_V2_0 != nullptr) {
-        gnssHal = gnssHal_V2_0;
-        gnssHal_V1_1 = gnssHal_V2_0;
-        return;
-    }
-
-    ALOGD("gnssHal 2.0 was null, trying 1.1");
-    gnssHal_V1_1 = IGnss_V1_1::getService();
-    if (gnssHal_V1_1 != nullptr) {
-        gnssHal = gnssHal_V1_1;
-        return;
-    }
-
-    ALOGD("gnssHal 1.1 was null, trying 1.0");
-    gnssHal = IGnss_V1_0::getService();
+    gnssHal = std::make_unique<gnss::GnssHal>();
 }
 
 /* One time initialization at system boot */
@@ -865,21 +242,10 @@
     android_location_gnss_hal_GnssNative_set_gps_service_handle();
 
     // Cache methodIDs and class IDs.
-    method_reportLocation = env->GetMethodID(clazz, "reportLocation",
-            "(ZLandroid/location/Location;)V");
-    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
-    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V");
-    method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
-    method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V");
-    method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
-    method_setGnssHardwareModelName = env->GetMethodID(clazz, "setGnssHardwareModelName",
-            "(Ljava/lang/String;)V");
-    method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "(I)V");
+
     method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
             "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
-    method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V");
-    method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
-    method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
+
     method_reportNfwNotification = env->GetMethodID(clazz, "reportNfwNotification",
             "(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
     method_reportGnssPowerStats =
@@ -894,17 +260,19 @@
     class_gnssPowerStats = (jclass)env->NewGlobalRef(gnssPowerStatsClass);
     method_gnssPowerStatsCtor = env->GetMethodID(class_gnssPowerStats, "<init>", "(IJDDDDDD[D)V");
 
+    gnss::AGnss_class_init_once(env, clazz);
+    gnss::AGnssRil_class_init_once(env, clazz);
+    gnss::Gnss_class_init_once(env, clazz);
     gnss::GnssAntennaInfo_class_init_once(env, clazz);
     gnss::GnssBatching_class_init_once(env, clazz);
     gnss::GnssConfiguration_class_init_once(env);
     gnss::GnssGeofence_class_init_once(env, clazz);
     gnss::GnssMeasurement_class_init_once(env, clazz);
     gnss::GnssNavigationMessage_class_init_once(env, clazz);
+    gnss::GnssPsds_class_init_once(env, clazz);
     gnss::GnssVisibilityControl_class_init_once(env, clazz);
     gnss::MeasurementCorrections_class_init_once(env, clazz);
     gnss::MeasurementCorrectionsCallback_class_init_once(env, clazz);
-    gnss::AGnss_class_init_once(env, clazz);
-    gnss::AGnssRil_class_init_once(env, clazz);
     gnss::Utils_class_init_once(env);
 }
 
@@ -923,313 +291,26 @@
         android_location_gnss_hal_GnssNative_set_gps_service_handle();
     }
 
-    if (gnssHal == nullptr && gnssHalAidl == nullptr) {
+    if (gnssHal == nullptr || !gnssHal->isSupported()) {
         ALOGE("Unable to get GPS service\n");
         return;
     }
 
-    // TODO: linkToDeath for AIDL HAL
-
-    if (gnssHal != nullptr) {
-        gnssHalDeathRecipient = new GnssDeathRecipient();
-        hardware::Return<bool> linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0);
-        if (!linked.isOk()) {
-            ALOGE("Transaction error in linking to GnssHAL death: %s",
-                  linked.description().c_str());
-        } else if (!linked) {
-            ALOGW("Unable to link to GnssHal death notifications");
-        } else {
-            ALOGD("Link to death notification successful");
-        }
-    }
-
-    if (gnssHalAidl != nullptr) {
-        sp<IGnssPsdsAidl> gnssPsdsAidl;
-        auto status = gnssHalAidl->getExtensionPsds(&gnssPsdsAidl);
-        if (status.isOk()) {
-            gnssPsdsAidlIface = gnssPsdsAidl;
-        } else {
-            ALOGD("Unable to get a handle to PSDS AIDL interface.");
-        }
-    } else if (gnssHal != nullptr) {
-        auto gnssXtra = gnssHal->getExtensionXtra();
-        if (!gnssXtra.isOk()) {
-            ALOGD("Unable to get a handle to Xtra");
-        } else {
-            gnssXtraIface = gnssXtra;
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<IAGnssRilAidl> agnssRilAidl;
-        auto status = gnssHalAidl->getExtensionAGnssRil(&agnssRilAidl);
-        if (checkAidlStatus(status, "Unable to get a handle to AGnssRil interface.")) {
-            agnssRilIface = std::make_unique<gnss::AGnssRil>(agnssRilAidl);
-        }
-    } else if (gnssHal_V2_0 != nullptr) {
-        auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0();
-        if (checkHidlReturn(agnssRil_V2_0, "Unable to get a handle to AGnssRil_V2_0")) {
-            agnssRilIface = std::make_unique<gnss::AGnssRil_V2_0>(agnssRil_V2_0);
-        }
-    } else if (gnssHal != nullptr) {
-        auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil();
-        if (checkHidlReturn(agnssRil_V1_0, "Unable to get a handle to AGnssRil_V1_0")) {
-            agnssRilIface = std::make_unique<gnss::AGnssRil_V1_0>(agnssRil_V1_0);
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<IAGnssAidl> agnssAidl;
-        auto status = gnssHalAidl->getExtensionAGnss(&agnssAidl);
-        if (checkAidlStatus(status, "Unable to get a handle to AGnss interface.")) {
-            agnssIface = std::make_unique<gnss::AGnss>(agnssAidl);
-        }
-    } else if (gnssHal_V2_0 != nullptr) {
-        auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0();
-        if (checkHidlReturn(agnss_V2_0, "Unable to get a handle to AGnss_V2_0")) {
-            agnssIface = std::make_unique<gnss::AGnss_V2_0>(agnss_V2_0);
-        }
-    } else if (gnssHal != nullptr) {
-        auto agnss_V1_0 = gnssHal->getExtensionAGnss();
-        if (checkHidlReturn(agnss_V1_0, "Unable to get a handle to AGnss_V1_0")) {
-            agnssIface = std::make_unique<gnss::AGnss_V1_0>(agnss_V1_0);
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<hardware::gnss::IGnssNavigationMessageInterface> gnssNavigationMessage;
-        auto status = gnssHalAidl->getExtensionGnssNavigationMessage(&gnssNavigationMessage);
-        if (checkAidlStatus(status,
-                            "Unable to get a handle to GnssNavigationMessage AIDL interface.")) {
-            gnssNavigationMessageIface =
-                    std::make_unique<gnss::GnssNavigationMessageAidl>(gnssNavigationMessage);
-        }
-    } else if (gnssHal != nullptr) {
-        auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
-        if (checkHidlReturn(gnssNavigationMessage,
-                            "Unable to get a handle to GnssNavigationMessage interface.")) {
-            gnssNavigationMessageIface =
-                    std::make_unique<gnss::GnssNavigationMessageHidl>(gnssNavigationMessage);
-        }
-    }
-
-    // Allow all causal combinations between IGnss.hal and IGnssMeasurement.hal. That means,
-    // 2.1@IGnss can be paired with {1.0, 1,1, 2.0, 2.1}@IGnssMeasurement
-    // 2.0@IGnss can be paired with {1.0, 1,1, 2.0}@IGnssMeasurement
-    // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
-    // 1.0@IGnss is paired with 1.0@IGnssMeasurement
-    gnssMeasurementIface = nullptr;
-    if (gnssHalAidl != nullptr) {
-        sp<hardware::gnss::IGnssMeasurementInterface> gnssMeasurement;
-        auto status = gnssHalAidl->getExtensionGnssMeasurement(&gnssMeasurement);
-        if (checkAidlStatus(status, "Unable to get a handle to GnssMeasurement AIDL interface.")) {
-            gnssMeasurementIface =
-                    std::make_unique<android::gnss::GnssMeasurement>(gnssMeasurement);
-        }
-    }
-    if (gnssHal_V2_1 != nullptr && gnssMeasurementIface == nullptr) {
-        auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1();
-        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_1")) {
-            gnssMeasurementIface =
-                    std::make_unique<android::gnss::GnssMeasurement_V2_1>(gnssMeasurement);
-        }
-    }
-    if (gnssHal_V2_0 != nullptr && gnssMeasurementIface == nullptr) {
-        auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
-        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_0")) {
-            gnssMeasurementIface =
-                    std::make_unique<android::gnss::GnssMeasurement_V2_0>(gnssMeasurement);
-        }
-    }
-    if (gnssHal_V1_1 != nullptr && gnssMeasurementIface == nullptr) {
-        auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
-        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_1")) {
-            gnssMeasurementIface =
-                    std::make_unique<android::gnss::GnssMeasurement_V1_1>(gnssMeasurement);
-        }
-    }
-    if (gnssHal != nullptr && gnssMeasurementIface == nullptr) {
-        auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
-        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_0")) {
-            gnssMeasurementIface =
-                    std::make_unique<android::gnss::GnssMeasurement_V1_0>(gnssMeasurement);
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<IGnssAntennaInfoAidl> gnssAntennaInfoAidl;
-        auto status = gnssHalAidl->getExtensionGnssAntennaInfo(&gnssAntennaInfoAidl);
-        if (checkAidlStatus(status, "Unable to get a handle to GnssAntennaInfo interface.")) {
-            gnssAntennaInfoIface = std::make_unique<gnss::GnssAntennaInfoAidl>(gnssAntennaInfoAidl);
-        }
-    } else if (gnssHal_V2_1 != nullptr) {
-        auto gnssAntennaInfo_V2_1 = gnssHal_V2_1->getExtensionGnssAntennaInfo();
-        if (checkHidlReturn(gnssAntennaInfo_V2_1,
-                            "Unable to get a handle to GnssAntennaInfo_V2_1")) {
-            gnssAntennaInfoIface =
-                    std::make_unique<gnss::GnssAntennaInfo_V2_1>(gnssAntennaInfo_V2_1);
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<android::hardware::gnss::measurement_corrections::IMeasurementCorrectionsInterface>
-                gnssMeasurementCorrectionsAidl;
-        auto status =
-                gnssHalAidl->getExtensionMeasurementCorrections(&gnssMeasurementCorrectionsAidl);
-        if (checkAidlStatus(status,
-                            "Unable to get a handle to GnssVisibilityControl AIDL interface.")) {
-            gnssMeasurementCorrectionsIface =
-                    std::make_unique<gnss::MeasurementCorrectionsIface_Aidl>(
-                            gnssMeasurementCorrectionsAidl);
-        }
-    }
-    if (gnssHal_V2_1 != nullptr && gnssMeasurementCorrectionsIface == nullptr) {
-        auto gnssCorrections = gnssHal_V2_1->getExtensionMeasurementCorrections_1_1();
-        if (checkHidlReturn(gnssCorrections,
-                            "Unable to get a handle to GnssMeasurementCorrections HIDL "
-                            "interface")) {
-            gnssMeasurementCorrectionsIface =
-                    std::make_unique<gnss::MeasurementCorrectionsIface_V1_1>(gnssCorrections);
-        }
-    }
-    if (gnssHal_V2_0 != nullptr && gnssMeasurementCorrectionsIface == nullptr) {
-        auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
-        if (checkHidlReturn(gnssCorrections,
-                            "Unable to get a handle to GnssMeasurementCorrections HIDL "
-                            "interface")) {
-            gnssMeasurementCorrectionsIface =
-                    std::make_unique<gnss::MeasurementCorrectionsIface_V1_0>(gnssCorrections);
-        }
-    }
-
-    // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means,
-    // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug
-    // 1.0@IGnss is paired with 1.0@IGnssDebug
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<IGnssDebugAidl> gnssDebugAidl;
-        auto status = gnssHalAidl->getExtensionGnssDebug(&gnssDebugAidl);
-        if (checkAidlStatus(status, "Unable to get a handle to GnssDebug interface.")) {
-            gnssDebugIface = std::make_unique<gnss::GnssDebug>(gnssDebugAidl);
-        }
-    }
-    if (gnssHal_V2_0 != nullptr && gnssDebugIface == nullptr) {
-        auto gnssDebug_V2_0 = gnssHal_V2_0->getExtensionGnssDebug_2_0();
-        if (checkHidlReturn(gnssDebug_V2_0, "Unable to get a handle to GnssDebug_V2_0.")) {
-            gnssDebugIface = std::make_unique<gnss::GnssDebug_V2_0>(gnssDebug_V2_0);
-        }
-    }
-    if (gnssHal != nullptr && gnssDebugIface == nullptr) {
-        auto gnssDebug_V1_0 = gnssHal->getExtensionGnssDebug();
-        if (checkHidlReturn(gnssDebug_V1_0, "Unable to get a handle to GnssDebug_V1_0.")) {
-            gnssDebugIface = std::make_unique<gnss::GnssDebug_V1_0>(gnssDebug_V1_0);
-        }
-    }
-
-    if (gnssHal != nullptr) {
-        auto gnssNi = gnssHal->getExtensionGnssNi();
-        if (!gnssNi.isOk()) {
-            ALOGD("Unable to get a handle to GnssNi");
-        } else {
-            gnssNiIface = gnssNi;
-        }
-    }
-
-    if (gnssHalAidl != nullptr) {
-        sp<IGnssConfigurationAidl> gnssConfigurationAidl;
-        auto status = gnssHalAidl->getExtensionGnssConfiguration(&gnssConfigurationAidl);
-        if (checkAidlStatus(status,
-                            "Unable to get a handle to GnssConfiguration AIDL interface.")) {
-            gnssConfigurationIface =
-                    std::make_unique<android::gnss::GnssConfiguration>(gnssConfigurationAidl);
-        }
-    } else if (gnssHal_V2_1 != nullptr) {
-        auto gnssConfiguration = gnssHal_V2_1->getExtensionGnssConfiguration_2_1();
-        if (checkHidlReturn(gnssConfiguration,
-                            "Unable to get a handle to GnssConfiguration_V2_1")) {
-            gnssConfigurationIface =
-                    std::make_unique<android::gnss::GnssConfiguration_V2_1>(gnssConfiguration);
-        }
-    } else if (gnssHal_V2_0 != nullptr) {
-        auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0();
-        if (checkHidlReturn(gnssConfiguration,
-                            "Unable to get a handle to GnssConfiguration_V2_0")) {
-            gnssConfigurationIface =
-                    std::make_unique<android::gnss::GnssConfiguration_V2_0>(gnssConfiguration);
-        }
-    } else if (gnssHal_V1_1 != nullptr) {
-        auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
-        if (checkHidlReturn(gnssConfiguration,
-                            "Unable to get a handle to GnssConfiguration_V1_1")) {
-            gnssConfigurationIface =
-                    std::make_unique<gnss::GnssConfiguration_V1_1>(gnssConfiguration);
-        }
-    } else if (gnssHal != nullptr) {
-        auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
-        if (checkHidlReturn(gnssConfiguration,
-                            "Unable to get a handle to GnssConfiguration_V1_0")) {
-            gnssConfigurationIface =
-                    std::make_unique<gnss::GnssConfiguration_V1_0>(gnssConfiguration);
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<hardware::gnss::IGnssGeofence> gnssGeofence;
-        auto status = gnssHalAidl->getExtensionGnssGeofence(&gnssGeofence);
-        if (checkAidlStatus(status, "Unable to get a handle to GnssGeofence AIDL interface.")) {
-            gnssGeofencingIface = std::make_unique<gnss::GnssGeofenceAidl>(gnssGeofence);
-        }
-    } else if (gnssHal != nullptr) {
-        auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
-        if (checkHidlReturn(gnssGeofencing, "Unable to get a handle to GnssGeofencing")) {
-            gnssGeofencingIface = std::make_unique<gnss::GnssGeofenceHidl>(gnssGeofencing);
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<android::hardware::gnss::IGnssBatching> gnssBatchingAidl;
-        auto status = gnssHalAidl->getExtensionGnssBatching(&gnssBatchingAidl);
-        if (checkAidlStatus(status, "Unable to get a handle to GnssBatching interface.")) {
-            gnssBatchingIface = std::make_unique<gnss::GnssBatching>(gnssBatchingAidl);
-        }
-    } else if (gnssHal_V2_0 != nullptr) {
-        auto gnssBatching_V2_0 = gnssHal_V2_0->getExtensionGnssBatching_2_0();
-        if (checkHidlReturn(gnssBatching_V2_0, "Unable to get a handle to GnssBatching_V2_0")) {
-            gnssBatchingIface = std::make_unique<gnss::GnssBatching_V2_0>(gnssBatching_V2_0);
-        }
-    }
-    if (gnssHal != nullptr && gnssBatchingIface == nullptr) {
-        auto gnssBatching_V1_0 = gnssHal->getExtensionGnssBatching();
-        if (checkHidlReturn(gnssBatching_V1_0, "Unable to get a handle to GnssBatching")) {
-            gnssBatchingIface = std::make_unique<gnss::GnssBatching_V1_0>(gnssBatching_V1_0);
-        }
-    }
-
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        sp<android::hardware::gnss::visibility_control::IGnssVisibilityControl>
-                gnssVisibilityControlAidl;
-        auto status = gnssHalAidl->getExtensionGnssVisibilityControl(&gnssVisibilityControlAidl);
-        if (checkAidlStatus(status,
-                            "Unable to get a handle to GnssVisibilityControl AIDL interface.")) {
-            gnssVisibilityControlIface =
-                    std::make_unique<gnss::GnssVisibilityControlAidl>(gnssVisibilityControlAidl);
-        }
-    } else if (gnssHal_V2_0 != nullptr) {
-        auto gnssVisibilityControlHidl = gnssHal_V2_0->getExtensionVisibilityControl();
-        if (checkHidlReturn(gnssVisibilityControlHidl,
-                            "Unable to get a handle to GnssVisibilityControl HIDL interface")) {
-            gnssVisibilityControlIface =
-                    std::make_unique<gnss::GnssVisibilityControlHidl>(gnssVisibilityControlHidl);
-        }
-    }
-
-    if (gnssHalAidl != nullptr) {
-        sp<IGnssPowerIndication> gnssPowerIndication;
-        auto status = gnssHalAidl->getExtensionGnssPowerIndication(&gnssPowerIndication);
-        if (checkAidlStatus(status, "Unable to get a handle to GnssPowerIndication interface.")) {
-            gnssPowerIndicationIface = gnssPowerIndication;
-        }
-    }
+    gnssHal->linkToDeath();
+    gnssPsdsIface = gnssHal->getGnssPsdsInterface();
+    agnssRilIface = gnssHal->getAGnssRilInterface();
+    agnssIface = gnssHal->getAGnssInterface();
+    gnssNavigationMessageIface = gnssHal->getGnssNavigationMessageInterface();
+    gnssMeasurementIface = gnssHal->getGnssMeasurementInterface();
+    gnssAntennaInfoIface = gnssHal->getGnssAntennaInfoInterface();
+    gnssMeasurementCorrectionsIface = gnssHal->getMeasurementCorrectionsInterface();
+    gnssDebugIface = gnssHal->getGnssDebugInterface();
+    gnssNiIface = gnssHal->getGnssNiInterface();
+    gnssConfigurationIface = gnssHal->getGnssConfigurationInterface();
+    gnssGeofencingIface = gnssHal->getGnssGeofenceInterface();
+    gnssBatchingIface = gnssHal->getGnssBatchingInterface();
+    gnssVisibilityControlIface = gnssHal->getGnssVisibilityControlInterface();
+    gnssPowerIndicationIface = gnssHal->getGnssPowerIndicationInterface();
 
     if (mCallbacksObj) {
         ALOGE("Callbacks already initialized");
@@ -1239,7 +320,7 @@
 }
 
 static jboolean android_location_gnss_hal_GnssNative_is_supported(JNIEnv* /* env */, jclass) {
-    return (gnssHalAidl != nullptr || gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
+    return (gnssHal != nullptr && gnssHal->isSupported()) ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
@@ -1268,52 +349,18 @@
     /*
      * Fail if the main interface fails to initialize
      */
-    if (gnssHal == nullptr && gnssHalAidl == nullptr) {
+    if (!gnssHal->isSupported()) {
         ALOGE("Unable to initialize GNSS HAL.");
         return JNI_FALSE;
     }
 
-    // Set top level IGnss.hal callback.
-    if (gnssHal != nullptr) {
-        Return<bool> result = false;
-        sp<IGnssCallback_V2_1> gnssCbIface = new GnssCallback();
-        if (gnssHal_V2_1 != nullptr) {
-            result = gnssHal_V2_1->setCallback_2_1(gnssCbIface);
-        } else if (gnssHal_V2_0 != nullptr) {
-            result = gnssHal_V2_0->setCallback_2_0(gnssCbIface);
-        } else if (gnssHal_V1_1 != nullptr) {
-            result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
-        } else {
-            result = gnssHal->setCallback(gnssCbIface);
-        }
-        if (!checkHidlReturn(result, "IGnss setCallback() failed.")) {
-            return JNI_FALSE;
-        }
-    }
+    // Set top level IGnss HAL callback.
+    gnssHal->setCallback();
 
-    if (gnssHalAidl != nullptr) {
-        sp<IGnssCallbackAidl> gnssCbIfaceAidl = new GnssCallbackAidl();
-        auto status = gnssHalAidl->setCallback(gnssCbIfaceAidl);
-        if (!checkAidlStatus(status, "IGnssAidl setCallback() failed.")) {
-            return JNI_FALSE;
-        }
-    }
-
-    // Set IGnssPsds or IGnssXtra callback.
-    if (gnssPsdsAidlIface != nullptr) {
-        sp<IGnssPsdsCallbackAidl> gnssPsdsCallbackAidl = new GnssPsdsCallbackAidl();
-        auto status = gnssPsdsAidlIface->setCallback(gnssPsdsCallbackAidl);
-        if (!checkAidlStatus(status, "IGnssPsdsAidl setCallback() failed.")) {
-            gnssPsdsAidlIface = nullptr;
-        }
-    } else if (gnssXtraIface != nullptr) {
-        sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
-        auto result = gnssXtraIface->setCallback(gnssXtraCbIface);
-        if (!checkHidlReturn(result, "IGnssXtra setCallback() failed.")) {
-            gnssXtraIface = nullptr;
-        } else {
-            ALOGI("Unable to initialize IGnssXtra interface.");
-        }
+    // Set IGnssPsds callback.
+    if (gnssPsdsIface == nullptr ||
+        !gnssPsdsIface->setCallback(std::make_unique<gnss::GnssPsdsCallback>())) {
+        ALOGI("Unable to initialize IGnssPsds interface.");
     }
 
     // Set IAGnss callback.
@@ -1373,145 +420,47 @@
 }
 
 static void android_location_gnss_hal_GnssNative_cleanup(JNIEnv* /* env */, jclass) {
-    if (gnssHalAidl != nullptr) {
-        auto status = gnssHalAidl->close();
-        checkAidlStatus(status, "IGnssAidl close() failed.");
-    }
-
-    if (gnssHal != nullptr) {
-        auto result = gnssHal->cleanup();
-        checkHidlReturn(result, "IGnss cleanup() failed.");
-    }
+    gnssHal->close();
 }
 
 static jboolean android_location_gnss_hal_GnssNative_set_position_mode(
         JNIEnv* /* env */, jclass, jint mode, jint recurrence, jint min_interval,
         jint preferred_accuracy, jint preferred_time, jboolean low_power_mode) {
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        IGnssAidl::PositionModeOptions options;
-        options.mode = static_cast<IGnssAidl::GnssPositionMode>(mode);
-        options.recurrence = static_cast<IGnssAidl::GnssPositionRecurrence>(recurrence);
-        options.minIntervalMs = min_interval;
-        options.preferredAccuracyMeters = preferred_accuracy;
-        options.preferredTimeMs = preferred_time;
-        options.lowPowerMode = low_power_mode;
-        auto status = gnssHalAidl->setPositionMode(options);
-        return checkAidlStatus(status, "IGnssAidl setPositionMode() failed.");
-    }
-
-    Return<bool> result = false;
-    if (gnssHal_V1_1 != nullptr) {
-         result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
-                 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
-                 min_interval,
-                 preferred_accuracy,
-                 preferred_time,
-                 low_power_mode);
-     } else if (gnssHal != nullptr) {
-         result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
-                 static_cast<IGnss_V1_0::GnssPositionRecurrence>(recurrence),
-                 min_interval,
-                 preferred_accuracy,
-                 preferred_time);
-    }
-
-    return checkHidlReturn(result, "IGnss setPositionMode() failed.");
+    return gnssHal->setPositionMode(mode, recurrence, min_interval, preferred_accuracy,
+                                    preferred_time, low_power_mode);
 }
 
 static jboolean android_location_gnss_hal_GnssNative_start(JNIEnv* /* env */, jclass) {
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->start();
-        return checkAidlStatus(status, "IGnssAidl start() failed.");
-    }
-
-    if (gnssHal == nullptr) {
-        return JNI_FALSE;
-    }
-
-    auto result = gnssHal->start();
-    return checkHidlReturn(result, "IGnss start() failed.");
+    return gnssHal->start();
 }
 
 static jboolean android_location_gnss_hal_GnssNative_stop(JNIEnv* /* env */, jclass) {
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->stop();
-        return checkAidlStatus(status, "IGnssAidl stop() failed.");
-    }
-
-    if (gnssHal == nullptr) {
-        return JNI_FALSE;
-    }
-
-    auto result = gnssHal->stop();
-    return checkHidlReturn(result, "IGnss stop() failed.");
+    return gnssHal->stop();
 }
 
 static jboolean android_location_gnss_hal_GnssNative_start_sv_status_collection(JNIEnv* /* env */,
                                                                                 jclass) {
-    isSvStatusRegistered = true;
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->startSvStatus();
-        return checkAidlStatus(status, "IGnssAidl startSvStatus() failed.");
-    }
-    if (gnssHal == nullptr) {
-        return JNI_FALSE;
-    }
-    return JNI_TRUE;
+    return gnssHal->startSvStatus();
 }
 
 static jboolean android_location_gnss_hal_GnssNative_stop_sv_status_collection(JNIEnv* /* env */,
                                                                                jclass) {
-    isSvStatusRegistered = false;
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->stopSvStatus();
-        return checkAidlStatus(status, "IGnssAidl stopSvStatus() failed.");
-    }
-    if (gnssHal == nullptr) {
-        return JNI_FALSE;
-    }
-    return JNI_TRUE;
+    return gnssHal->stopSvStatus();
 }
 
 static jboolean android_location_gnss_hal_GnssNative_start_nmea_message_collection(
         JNIEnv* /* env */, jclass) {
-    isNmeaRegistered = true;
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->startNmea();
-        return checkAidlStatus(status, "IGnssAidl startNmea() failed.");
-    }
-    if (gnssHal == nullptr) {
-        return JNI_FALSE;
-    }
-    return JNI_TRUE;
+    return gnssHal->startNmea();
 }
 
 static jboolean android_location_gnss_hal_GnssNative_stop_nmea_message_collection(JNIEnv* /* env */,
                                                                                   jclass) {
-    isNmeaRegistered = false;
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->stopNmea();
-        return checkAidlStatus(status, "IGnssAidl stopNmea() failed.");
-    }
-    if (gnssHal == nullptr) {
-        return JNI_FALSE;
-    }
-    return JNI_TRUE;
+    return gnssHal->stopNmea();
 }
 
 static void android_location_gnss_hal_GnssNative_delete_aiding_data(JNIEnv* /* env */, jclass,
                                                                     jint flags) {
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->deleteAidingData(static_cast<IGnssAidl::GnssAidingData>(flags));
-        checkAidlStatus(status, "IGnssAidl deleteAidingData() failed.");
-        return;
-    }
-
-    if (gnssHal == nullptr) {
-        return;
-    }
-
-    auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
-    checkHidlReturn(result, "IGnss deleteAidingData() failed.");
+    gnssHal->deleteAidingData(flags);
 }
 
 static void android_location_gnss_hal_GnssNative_agps_set_reference_location_cellid(
@@ -1535,30 +484,13 @@
 
 static jint android_location_gnss_hal_GnssNative_read_nmea(JNIEnv* env, jclass,
                                                            jbyteArray nmeaArray, jint buffer_size) {
-    // this should only be called from within a call to reportNmea
-    jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
-    int length = GnssCallback::sNmeaStringLength;
-    if (length > buffer_size)
-        length = buffer_size;
-    memcpy(nmea, GnssCallback::sNmeaString, length);
-    env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
-    return (jint) length;
+    return gnssHal->readNmea(nmeaArray, buffer_size);
 }
 
 static void android_location_gnss_hal_GnssNative_inject_time(JNIEnv* /* env */, jclass, jlong time,
                                                              jlong timeReference,
                                                              jint uncertainty) {
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        auto status = gnssHalAidl->injectTime(time, timeReference, uncertainty);
-        checkAidlStatus(status, "IGnssAidl injectTime() failed.");
-        return;
-    }
-
-    if (gnssHal == nullptr) {
-        return;
-    }
-    auto result = gnssHal->injectTime(time, timeReference, uncertainty);
-    checkHidlReturn(result, "IGnss injectTime() failed.");
+    gnssHal->injectTime(time, timeReference, uncertainty);
 }
 
 static void android_location_gnss_hal_GnssNative_inject_best_location(
@@ -1568,58 +500,12 @@
         jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp,
         jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
         jdouble elapsedRealtimeUncertaintyNanos) {
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        GnssLocationAidl location =
-                createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
-                                   altitudeMeters, speedMetersPerSec, bearingDegrees,
-                                   horizontalAccuracyMeters, verticalAccuracyMeters,
-                                   speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
-                                   elapsedRealtimeFlags, elapsedRealtimeNanos,
-                                   elapsedRealtimeUncertaintyNanos);
-        auto status = gnssHalAidl->injectBestLocation(location);
-        checkAidlStatus(status, "IGnssAidl injectBestLocation() failed.");
-        return;
-    }
-
-    if (gnssHal_V2_0 != nullptr) {
-        GnssLocation_V2_0 location = createGnssLocation_V2_0(
-                gnssLocationFlags,
-                latitudeDegrees,
-                longitudeDegrees,
-                altitudeMeters,
-                speedMetersPerSec,
-                bearingDegrees,
-                horizontalAccuracyMeters,
-                verticalAccuracyMeters,
-                speedAccuracyMetersPerSecond,
-                bearingAccuracyDegrees,
-                timestamp,
-                elapsedRealtimeFlags,
-                elapsedRealtimeNanos,
-                elapsedRealtimeUncertaintyNanos);
-        auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
-        checkHidlReturn(result, "IGnss injectBestLocation_2_0() failed.");
-        return;
-    }
-
-    if (gnssHal_V1_1 != nullptr) {
-        GnssLocation_V1_0 location = createGnssLocation_V1_0(
-                gnssLocationFlags,
-                latitudeDegrees,
-                longitudeDegrees,
-                altitudeMeters,
-                speedMetersPerSec,
-                bearingDegrees,
-                horizontalAccuracyMeters,
-                verticalAccuracyMeters,
-                speedAccuracyMetersPerSecond,
-                bearingAccuracyDegrees,
-                timestamp);
-        auto result = gnssHal_V1_1->injectBestLocation(location);
-        checkHidlReturn(result, "IGnss injectBestLocation() failed.");
-    }
-
-    ALOGE("IGnss injectBestLocation() is called but gnssHal_V1_1 is not available.");
+    gnssHal->injectBestLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
+                                altitudeMeters, speedMetersPerSec, bearingDegrees,
+                                horizontalAccuracyMeters, verticalAccuracyMeters,
+                                speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
+                                elapsedRealtimeFlags, elapsedRealtimeNanos,
+                                elapsedRealtimeUncertaintyNanos);
 }
 
 static void android_location_gnss_hal_GnssNative_inject_location(
@@ -1629,51 +515,25 @@
         jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees, jlong timestamp,
         jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
         jdouble elapsedRealtimeUncertaintyNanos) {
-    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
-        GnssLocationAidl location =
-                createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
-                                   altitudeMeters, speedMetersPerSec, bearingDegrees,
-                                   horizontalAccuracyMeters, verticalAccuracyMeters,
-                                   speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
-                                   elapsedRealtimeFlags, elapsedRealtimeNanos,
-                                   elapsedRealtimeUncertaintyNanos);
-        auto status = gnssHalAidl->injectLocation(location);
-        checkAidlStatus(status, "IGnssAidl injectLocation() failed.");
-        return;
-    }
-
-    if (gnssHal == nullptr) {
-        return;
-    }
-    auto result =
-            gnssHal->injectLocation(latitudeDegrees, longitudeDegrees, horizontalAccuracyMeters);
-    checkHidlReturn(result, "IGnss injectLocation() failed.");
+    gnssHal->injectLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
+                            speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
+                            verticalAccuracyMeters, speedAccuracyMetersPerSecond,
+                            bearingAccuracyDegrees, timestamp, elapsedRealtimeFlags,
+                            elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
 }
 
 static jboolean android_location_gnss_hal_GnssNative_supports_psds(JNIEnv* /* env */, jclass) {
-    return (gnssPsdsAidlIface != nullptr || gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
+    return (gnssPsdsIface != nullptr) ? JNI_TRUE : JNI_FALSE;
 }
 
 static void android_location_gnss_hal_GnssNative_inject_psds_data(JNIEnv* env, jclass,
                                                                   jbyteArray data, jint length,
                                                                   jint psdsType) {
-    if (gnssPsdsAidlIface == nullptr && gnssXtraIface == nullptr) {
-        ALOGE("%s: IGnssPsdsAidl or IGnssXtra interface not available.", __func__);
+    if (gnssPsdsIface == nullptr) {
+        ALOGE("%s: IGnssPsds or IGnssXtra interface not available.", __func__);
         return;
     }
-
-    jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
-    if (gnssPsdsAidlIface != nullptr) {
-        auto status = gnssPsdsAidlIface->injectPsdsData(static_cast<PsdsType>(psdsType),
-                                                        std::vector<uint8_t>((const uint8_t*)bytes,
-                                                                             (const uint8_t*)bytes +
-                                                                                     length));
-        checkAidlStatus(status, "IGnssPsdsAidl injectPsdsData() failed.");
-    } else if (gnssXtraIface != nullptr) {
-        auto result = gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
-        checkHidlReturn(result, "IGnssXtra injectXtraData() failed.");
-    }
-    env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
+    gnssPsdsIface->injectPsdsData(data, length, psdsType);
 }
 
 static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
@@ -1870,8 +730,7 @@
     options.enableCorrVecOutputs = enableCorrVecOutputs;
     options.intervalMs = intervalMs;
 
-    return gnssMeasurementIface->setCallback(std::make_unique<gnss::GnssMeasurementCallback>(
-                                                     mCallbacksObj),
+    return gnssMeasurementIface->setCallback(std::make_unique<gnss::GnssMeasurementCallback>(),
                                              options);
 }
 
diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp
index e52df15..0531ae2 100644
--- a/services/core/jni/gnss/Android.bp
+++ b/services/core/jni/gnss/Android.bp
@@ -28,6 +28,8 @@
         "AGnssRil.cpp",
         "AGnssRilCallback.cpp",
         "GnssAntennaInfo.cpp",
+        "Gnss.cpp",
+        "GnssCallback.cpp",
         "GnssAntennaInfoCallback.cpp",
         "GnssBatching.cpp",
         "GnssBatchingCallback.cpp",
@@ -39,6 +41,8 @@
         "GnssMeasurementCallback.cpp",
         "GnssNavigationMessage.cpp",
         "GnssNavigationMessageCallback.cpp",
+        "GnssPsds.cpp",
+        "GnssPsdsCallback.cpp",
         "GnssVisibilityControl.cpp",
         "GnssVisibilityControlCallback.cpp",
         "MeasurementCorrections.cpp",
@@ -55,6 +59,7 @@
         "libhidlbase",
         "liblog",
         "libnativehelper",
+        "libhardware_legacy",
         "libutils",
         "android.hardware.gnss-V2-cpp",
         "android.hardware.gnss@1.0",
diff --git a/services/core/jni/gnss/Gnss.cpp b/services/core/jni/gnss/Gnss.cpp
new file mode 100644
index 0000000..f6459ea
--- /dev/null
+++ b/services/core/jni/gnss/Gnss.cpp
@@ -0,0 +1,759 @@
+/*
+ * 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.
+ */
+
+// Define LOG_TAG before <log/log.h> to overwrite the default value.
+#define LOG_TAG "GnssJni"
+
+#include "Gnss.h"
+
+#include <binder/IServiceManager.h>
+
+#include "Utils.h"
+
+namespace android::gnss {
+
+using hardware::Return;
+
+using GnssLocationAidl = hardware::gnss::GnssLocation;
+using GnssLocation_V1_0 = hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_V2_0 = hardware::gnss::V2_0::GnssLocation;
+using IAGnssAidl = hardware::gnss::IAGnss;
+using IAGnssRilAidl = hardware::gnss::IAGnssRil;
+using IGnssAidl = hardware::gnss::IGnss;
+using IGnss_V1_0 = hardware::gnss::V1_0::IGnss;
+using IGnss_V1_1 = hardware::gnss::V1_1::IGnss;
+using IGnss_V2_0 = hardware::gnss::V2_0::IGnss;
+using IGnss_V2_1 = hardware::gnss::V2_1::IGnss;
+using IGnssAntennaInfoAidl = hardware::gnss::IGnssAntennaInfo;
+using IGnssCallbackAidl = hardware::gnss::IGnssCallback;
+using IGnssCallback_V1_0 = hardware::gnss::V1_0::IGnssCallback;
+using IGnssCallback_V2_0 = hardware::gnss::V2_0::IGnssCallback;
+using IGnssCallback_V2_1 = hardware::gnss::V2_1::IGnssCallback;
+using IGnssConfigurationAidl = android::hardware::gnss::IGnssConfiguration;
+using IGnssDebugAidl = hardware::gnss::IGnssDebug;
+using android::hardware::gnss::IGnssPsds;
+
+namespace {
+
+GnssLocationAidl createGnssLocation(jint gnssLocationFlags, jdouble latitudeDegrees,
+                                    jdouble longitudeDegrees, jdouble altitudeMeters,
+                                    jfloat speedMetersPerSec, jfloat bearingDegrees,
+                                    jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
+                                    jfloat speedAccuracyMetersPerSecond,
+                                    jfloat bearingAccuracyDegrees, jlong timestamp,
+                                    jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+                                    jdouble elapsedRealtimeUncertaintyNanos) {
+    GnssLocationAidl location;
+    location.gnssLocationFlags = static_cast<int>(gnssLocationFlags);
+    location.latitudeDegrees = static_cast<double>(latitudeDegrees);
+    location.longitudeDegrees = static_cast<double>(longitudeDegrees);
+    location.altitudeMeters = static_cast<double>(altitudeMeters);
+    location.speedMetersPerSec = static_cast<double>(speedMetersPerSec);
+    location.bearingDegrees = static_cast<double>(bearingDegrees);
+    location.horizontalAccuracyMeters = static_cast<double>(horizontalAccuracyMeters);
+    location.verticalAccuracyMeters = static_cast<double>(verticalAccuracyMeters);
+    location.speedAccuracyMetersPerSecond = static_cast<double>(speedAccuracyMetersPerSecond);
+    location.bearingAccuracyDegrees = static_cast<double>(bearingAccuracyDegrees);
+    location.timestampMillis = static_cast<uint64_t>(timestamp);
+
+    location.elapsedRealtime.flags = static_cast<int>(elapsedRealtimeFlags);
+    location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
+    location.elapsedRealtime.timeUncertaintyNs =
+            static_cast<double>(elapsedRealtimeUncertaintyNanos);
+
+    return location;
+}
+
+GnssLocation_V1_0 createGnssLocation_V1_0(jint gnssLocationFlags, jdouble latitudeDegrees,
+                                          jdouble longitudeDegrees, jdouble altitudeMeters,
+                                          jfloat speedMetersPerSec, jfloat bearingDegrees,
+                                          jfloat horizontalAccuracyMeters,
+                                          jfloat verticalAccuracyMeters,
+                                          jfloat speedAccuracyMetersPerSecond,
+                                          jfloat bearingAccuracyDegrees, jlong timestamp) {
+    GnssLocation_V1_0 location;
+    location.gnssLocationFlags = static_cast<uint16_t>(gnssLocationFlags);
+    location.latitudeDegrees = static_cast<double>(latitudeDegrees);
+    location.longitudeDegrees = static_cast<double>(longitudeDegrees);
+    location.altitudeMeters = static_cast<double>(altitudeMeters);
+    location.speedMetersPerSec = static_cast<float>(speedMetersPerSec);
+    location.bearingDegrees = static_cast<float>(bearingDegrees);
+    location.horizontalAccuracyMeters = static_cast<float>(horizontalAccuracyMeters);
+    location.verticalAccuracyMeters = static_cast<float>(verticalAccuracyMeters);
+    location.speedAccuracyMetersPerSecond = static_cast<float>(speedAccuracyMetersPerSecond);
+    location.bearingAccuracyDegrees = static_cast<float>(bearingAccuracyDegrees);
+    location.timestamp = static_cast<uint64_t>(timestamp);
+
+    return location;
+}
+
+GnssLocation_V2_0 createGnssLocation_V2_0(jint gnssLocationFlags, jdouble latitudeDegrees,
+                                          jdouble longitudeDegrees, jdouble altitudeMeters,
+                                          jfloat speedMetersPerSec, jfloat bearingDegrees,
+                                          jfloat horizontalAccuracyMeters,
+                                          jfloat verticalAccuracyMeters,
+                                          jfloat speedAccuracyMetersPerSecond,
+                                          jfloat bearingAccuracyDegrees, jlong timestamp,
+                                          jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+                                          jdouble elapsedRealtimeUncertaintyNanos) {
+    GnssLocation_V2_0 location;
+    location.v1_0 = createGnssLocation_V1_0(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
+                                            altitudeMeters, speedMetersPerSec, bearingDegrees,
+                                            horizontalAccuracyMeters, verticalAccuracyMeters,
+                                            speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
+                                            timestamp);
+
+    location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
+    location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
+    location.elapsedRealtime.timeUncertaintyNs =
+            static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
+
+    return location;
+}
+
+} // anonymous namespace
+
+// Implementation of GnssHal, which unifies all versions of GNSS HALs
+
+GnssHal::GnssHal() {
+    gnssHalAidl = waitForVintfService<IGnssAidl>();
+    if (gnssHalAidl != nullptr) {
+        ALOGD("Successfully got GNSS AIDL handle. Version=%d.", gnssHalAidl->getInterfaceVersion());
+        if (gnssHalAidl->getInterfaceVersion() >= 2) {
+            return;
+        }
+    }
+
+    ALOGD("Trying IGnss_V2_1::getService()");
+    gnssHal_V2_1 = IGnss_V2_1::getService();
+    if (gnssHal_V2_1 != nullptr) {
+        gnssHal_V2_0 = gnssHal_V2_1;
+        gnssHal_V1_1 = gnssHal_V2_1;
+        gnssHal = gnssHal_V2_1;
+        return;
+    }
+
+    ALOGD("gnssHal 2.1 was null, trying 2.0");
+    gnssHal_V2_0 = IGnss_V2_0::getService();
+    if (gnssHal_V2_0 != nullptr) {
+        gnssHal_V1_1 = gnssHal_V2_0;
+        gnssHal = gnssHal_V2_0;
+        return;
+    }
+
+    ALOGD("gnssHal 2.0 was null, trying 1.1");
+    gnssHal_V1_1 = IGnss_V1_1::getService();
+    if (gnssHal_V1_1 != nullptr) {
+        gnssHal = gnssHal_V1_1;
+        return;
+    }
+
+    ALOGD("gnssHal 1.1 was null, trying 1.0");
+    gnssHal = IGnss_V1_0::getService();
+}
+
+jboolean GnssHal::isSupported() {
+    return (gnssHalAidl != nullptr || gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
+}
+
+void GnssHal::linkToDeath() {
+    // TODO: linkToDeath for AIDL HAL
+
+    if (gnssHal != nullptr) {
+        gnssHalDeathRecipient = new GnssDeathRecipient();
+        hardware::Return<bool> linked = gnssHal->linkToDeath(gnssHalDeathRecipient, /*cookie*/ 0);
+        if (!linked.isOk()) {
+            ALOGE("Transaction error in linking to GnssHAL death: %s",
+                  linked.description().c_str());
+        } else if (!linked) {
+            ALOGW("Unable to link to GnssHal death notifications");
+        } else {
+            ALOGD("Link to death notification successful");
+        }
+    }
+}
+
+jboolean GnssHal::setCallback() {
+    if (gnssHalAidl != nullptr) {
+        sp<IGnssCallbackAidl> gnssCbIfaceAidl = new GnssCallbackAidl();
+        auto status = gnssHalAidl->setCallback(gnssCbIfaceAidl);
+        if (!checkAidlStatus(status, "IGnssAidl setCallback() failed.")) {
+            return JNI_FALSE;
+        }
+    }
+    if (gnssHal != nullptr) {
+        Return<bool> result = false;
+        sp<IGnssCallback_V2_1> gnssCbIface = new GnssCallbackHidl();
+        if (gnssHal_V2_1 != nullptr) {
+            result = gnssHal_V2_1->setCallback_2_1(gnssCbIface);
+        } else if (gnssHal_V2_0 != nullptr) {
+            result = gnssHal_V2_0->setCallback_2_0(gnssCbIface);
+        } else if (gnssHal_V1_1 != nullptr) {
+            result = gnssHal_V1_1->setCallback_1_1(gnssCbIface);
+        } else {
+            result = gnssHal->setCallback(gnssCbIface);
+        }
+        if (!checkHidlReturn(result, "IGnss setCallback() failed.")) {
+            return JNI_FALSE;
+        }
+    }
+    return JNI_TRUE;
+}
+
+void GnssHal::close() {
+    if (gnssHalAidl != nullptr) {
+        auto status = gnssHalAidl->close();
+        checkAidlStatus(status, "IGnssAidl close() failed.");
+    }
+
+    if (gnssHal != nullptr) {
+        auto result = gnssHal->cleanup();
+        checkHidlReturn(result, "IGnss cleanup() failed.");
+    }
+}
+
+jboolean GnssHal::start() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->start();
+        return checkAidlStatus(status, "IGnssAidl start() failed.");
+    }
+
+    if (gnssHal == nullptr) {
+        return JNI_FALSE;
+    }
+
+    auto result = gnssHal->start();
+    return checkHidlReturn(result, "IGnss start() failed.");
+}
+
+jboolean GnssHal::stop() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->stop();
+        return checkAidlStatus(status, "IGnssAidl stop() failed.");
+    }
+
+    if (gnssHal == nullptr) {
+        return JNI_FALSE;
+    }
+
+    auto result = gnssHal->stop();
+    return checkHidlReturn(result, "IGnss stop() failed.");
+}
+
+jboolean GnssHal::startSvStatus() {
+    isSvStatusRegistered = true;
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->startSvStatus();
+        return checkAidlStatus(status, "IGnssAidl startSvStatus() failed.");
+    }
+    if (gnssHal == nullptr) {
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+jboolean GnssHal::stopSvStatus() {
+    isSvStatusRegistered = false;
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->stopSvStatus();
+        return checkAidlStatus(status, "IGnssAidl stopSvStatus() failed.");
+    }
+    if (gnssHal == nullptr) {
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+jboolean GnssHal::startNmea() {
+    isNmeaRegistered = true;
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->startNmea();
+        return checkAidlStatus(status, "IGnssAidl startNmea() failed.");
+    }
+    if (gnssHal == nullptr) {
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+jboolean GnssHal::stopNmea() {
+    isNmeaRegistered = false;
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->stopNmea();
+        return checkAidlStatus(status, "IGnssAidl stopNmea() failed.");
+    }
+    if (gnssHal == nullptr) {
+        return JNI_FALSE;
+    }
+    return JNI_TRUE;
+}
+
+jint GnssHal::readNmea(jbyteArray& nmeaArray, jint& buffer_size) {
+    // this should only be called from within a call to reportNmea
+    JNIEnv* env = getJniEnv();
+    jbyte* nmea = reinterpret_cast<jbyte*>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
+    int length = GnssCallbackHidl::sNmeaStringLength;
+    if (length > buffer_size) {
+        length = buffer_size;
+    }
+    memcpy(nmea, GnssCallbackHidl::sNmeaString, length);
+    env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
+    return (jint)length;
+}
+
+jboolean GnssHal::setPositionMode(jint mode, jint recurrence, jint min_interval,
+                                  jint preferred_accuracy, jint preferred_time,
+                                  jboolean low_power_mode) {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        IGnssAidl::PositionModeOptions options;
+        options.mode = static_cast<IGnssAidl::GnssPositionMode>(mode);
+        options.recurrence = static_cast<IGnssAidl::GnssPositionRecurrence>(recurrence);
+        options.minIntervalMs = min_interval;
+        options.preferredAccuracyMeters = preferred_accuracy;
+        options.preferredTimeMs = preferred_time;
+        options.lowPowerMode = low_power_mode;
+        auto status = gnssHalAidl->setPositionMode(options);
+        return checkAidlStatus(status, "IGnssAidl setPositionMode() failed.");
+    }
+
+    Return<bool> result = false;
+    if (gnssHal_V1_1 != nullptr) {
+        result = gnssHal_V1_1->setPositionMode_1_1(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
+                                                   static_cast<IGnss_V1_0::GnssPositionRecurrence>(
+                                                           recurrence),
+                                                   min_interval, preferred_accuracy, preferred_time,
+                                                   low_power_mode);
+    } else if (gnssHal != nullptr) {
+        result = gnssHal->setPositionMode(static_cast<IGnss_V1_0::GnssPositionMode>(mode),
+                                          static_cast<IGnss_V1_0::GnssPositionRecurrence>(
+                                                  recurrence),
+                                          min_interval, preferred_accuracy, preferred_time);
+    }
+    return checkHidlReturn(result, "IGnss setPositionMode() failed.");
+}
+
+void GnssHal::deleteAidingData(jint flags) {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->deleteAidingData(static_cast<IGnssAidl::GnssAidingData>(flags));
+        checkAidlStatus(status, "IGnssAidl deleteAidingData() failed.");
+        return;
+    }
+
+    if (gnssHal == nullptr) {
+        return;
+    }
+
+    auto result = gnssHal->deleteAidingData(static_cast<IGnss_V1_0::GnssAidingData>(flags));
+    checkHidlReturn(result, "IGnss deleteAidingData() failed.");
+}
+
+void GnssHal::injectTime(jlong time, jlong timeReference, jint uncertainty) {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        auto status = gnssHalAidl->injectTime(time, timeReference, uncertainty);
+        checkAidlStatus(status, "IGnssAidl injectTime() failed.");
+        return;
+    }
+
+    if (gnssHal == nullptr) {
+        return;
+    }
+    auto result = gnssHal->injectTime(time, timeReference, uncertainty);
+    checkHidlReturn(result, "IGnss injectTime() failed.");
+}
+
+void GnssHal::injectLocation(jint gnssLocationFlags, jdouble latitudeDegrees,
+                             jdouble longitudeDegrees, jdouble altitudeMeters,
+                             jfloat speedMetersPerSec, jfloat bearingDegrees,
+                             jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
+                             jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
+                             jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+                             jdouble elapsedRealtimeUncertaintyNanos) {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        GnssLocationAidl location =
+                createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
+                                   altitudeMeters, speedMetersPerSec, bearingDegrees,
+                                   horizontalAccuracyMeters, verticalAccuracyMeters,
+                                   speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
+                                   elapsedRealtimeFlags, elapsedRealtimeNanos,
+                                   elapsedRealtimeUncertaintyNanos);
+        auto status = gnssHalAidl->injectLocation(location);
+        checkAidlStatus(status, "IGnssAidl injectLocation() failed.");
+        return;
+    }
+
+    if (gnssHal == nullptr) {
+        return;
+    }
+    auto result =
+            gnssHal->injectLocation(latitudeDegrees, longitudeDegrees, horizontalAccuracyMeters);
+    checkHidlReturn(result, "IGnss injectLocation() failed.");
+}
+
+void GnssHal::injectBestLocation(jint gnssLocationFlags, jdouble latitudeDegrees,
+                                 jdouble longitudeDegrees, jdouble altitudeMeters,
+                                 jfloat speedMetersPerSec, jfloat bearingDegrees,
+                                 jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
+                                 jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
+                                 jlong timestamp, jint elapsedRealtimeFlags,
+                                 jlong elapsedRealtimeNanos,
+                                 jdouble elapsedRealtimeUncertaintyNanos) {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        GnssLocationAidl location =
+                createGnssLocation(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
+                                   altitudeMeters, speedMetersPerSec, bearingDegrees,
+                                   horizontalAccuracyMeters, verticalAccuracyMeters,
+                                   speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
+                                   elapsedRealtimeFlags, elapsedRealtimeNanos,
+                                   elapsedRealtimeUncertaintyNanos);
+        auto status = gnssHalAidl->injectBestLocation(location);
+        checkAidlStatus(status, "IGnssAidl injectBestLocation() failed.");
+        return;
+    }
+
+    if (gnssHal_V2_0 != nullptr) {
+        GnssLocation_V2_0 location =
+                createGnssLocation_V2_0(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
+                                        altitudeMeters, speedMetersPerSec, bearingDegrees,
+                                        horizontalAccuracyMeters, verticalAccuracyMeters,
+                                        speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
+                                        timestamp, elapsedRealtimeFlags, elapsedRealtimeNanos,
+                                        elapsedRealtimeUncertaintyNanos);
+        auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
+        checkHidlReturn(result, "IGnss injectBestLocation_2_0() failed.");
+        return;
+    }
+
+    if (gnssHal_V1_1 != nullptr) {
+        GnssLocation_V1_0 location =
+                createGnssLocation_V1_0(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
+                                        altitudeMeters, speedMetersPerSec, bearingDegrees,
+                                        horizontalAccuracyMeters, verticalAccuracyMeters,
+                                        speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
+                                        timestamp);
+        auto result = gnssHal_V1_1->injectBestLocation(location);
+        checkHidlReturn(result, "IGnss injectBestLocation() failed.");
+        return;
+    }
+
+    ALOGE("IGnss injectBestLocation() is called but gnssHal_V1_1 is not available.");
+}
+
+std::unique_ptr<AGnssInterface> GnssHal::getAGnssInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<IAGnssAidl> agnssAidl;
+        auto status = gnssHalAidl->getExtensionAGnss(&agnssAidl);
+        if (checkAidlStatus(status, "Unable to get a handle to AGnss interface.")) {
+            return std::make_unique<gnss::AGnss>(agnssAidl);
+        }
+    } else if (gnssHal_V2_0 != nullptr) {
+        auto agnss_V2_0 = gnssHal_V2_0->getExtensionAGnss_2_0();
+        if (checkHidlReturn(agnss_V2_0, "Unable to get a handle to AGnss_V2_0")) {
+            return std::make_unique<gnss::AGnss_V2_0>(agnss_V2_0);
+        }
+    } else if (gnssHal != nullptr) {
+        auto agnss_V1_0 = gnssHal->getExtensionAGnss();
+        if (checkHidlReturn(agnss_V1_0, "Unable to get a handle to AGnss_V1_0")) {
+            return std::make_unique<gnss::AGnss_V1_0>(agnss_V1_0);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<AGnssRilInterface> GnssHal::getAGnssRilInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<IAGnssRilAidl> agnssRilAidl;
+        auto status = gnssHalAidl->getExtensionAGnssRil(&agnssRilAidl);
+        if (checkAidlStatus(status, "Unable to get a handle to AGnssRil interface.")) {
+            return std::make_unique<gnss::AGnssRil>(agnssRilAidl);
+        }
+    } else if (gnssHal_V2_0 != nullptr) {
+        auto agnssRil_V2_0 = gnssHal_V2_0->getExtensionAGnssRil_2_0();
+        if (checkHidlReturn(agnssRil_V2_0, "Unable to get a handle to AGnssRil_V2_0")) {
+            return std::make_unique<gnss::AGnssRil_V2_0>(agnssRil_V2_0);
+        }
+    } else if (gnssHal != nullptr) {
+        auto agnssRil_V1_0 = gnssHal->getExtensionAGnssRil();
+        if (checkHidlReturn(agnssRil_V1_0, "Unable to get a handle to AGnssRil_V1_0")) {
+            return std::make_unique<gnss::AGnssRil_V1_0>(agnssRil_V1_0);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssNavigationMessageInterface> GnssHal::getGnssNavigationMessageInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<hardware::gnss::IGnssNavigationMessageInterface> gnssNavigationMessage;
+        auto status = gnssHalAidl->getExtensionGnssNavigationMessage(&gnssNavigationMessage);
+        if (checkAidlStatus(status,
+                            "Unable to get a handle to GnssNavigationMessage AIDL interface.")) {
+            return std::make_unique<gnss::GnssNavigationMessageAidl>(gnssNavigationMessage);
+        }
+    } else if (gnssHal != nullptr) {
+        auto gnssNavigationMessage = gnssHal->getExtensionGnssNavigationMessage();
+        if (checkHidlReturn(gnssNavigationMessage,
+                            "Unable to get a handle to GnssNavigationMessage interface.")) {
+            return std::make_unique<gnss::GnssNavigationMessageHidl>(gnssNavigationMessage);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssMeasurementInterface> GnssHal::getGnssMeasurementInterface() {
+    // Allow all causal combinations between IGnss.hal and IGnssMeasurement.hal. That means,
+    // 2.1@IGnss can be paired with {1.0, 1,1, 2.0, 2.1}@IGnssMeasurement
+    // 2.0@IGnss can be paired with {1.0, 1,1, 2.0}@IGnssMeasurement
+    // 1.1@IGnss can be paired {1.0, 1.1}@IGnssMeasurement
+    // 1.0@IGnss is paired with 1.0@IGnssMeasurement
+    if (gnssHalAidl != nullptr) {
+        sp<hardware::gnss::IGnssMeasurementInterface> gnssMeasurement;
+        auto status = gnssHalAidl->getExtensionGnssMeasurement(&gnssMeasurement);
+        if (checkAidlStatus(status, "Unable to get a handle to GnssMeasurement AIDL interface.")) {
+            return std::make_unique<android::gnss::GnssMeasurement>(gnssMeasurement);
+        }
+    }
+    if (gnssHal_V2_1 != nullptr) {
+        auto gnssMeasurement = gnssHal_V2_1->getExtensionGnssMeasurement_2_1();
+        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_1")) {
+            return std::make_unique<android::gnss::GnssMeasurement_V2_1>(gnssMeasurement);
+        }
+    }
+    if (gnssHal_V2_0 != nullptr) {
+        auto gnssMeasurement = gnssHal_V2_0->getExtensionGnssMeasurement_2_0();
+        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V2_0")) {
+            return std::make_unique<android::gnss::GnssMeasurement_V2_0>(gnssMeasurement);
+        }
+    }
+    if (gnssHal_V1_1 != nullptr) {
+        auto gnssMeasurement = gnssHal_V1_1->getExtensionGnssMeasurement_1_1();
+        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_1")) {
+            return std::make_unique<android::gnss::GnssMeasurement_V1_1>(gnssMeasurement);
+        }
+    }
+    if (gnssHal != nullptr) {
+        auto gnssMeasurement = gnssHal->getExtensionGnssMeasurement();
+        if (checkHidlReturn(gnssMeasurement, "Unable to get a handle to GnssMeasurement_V1_0")) {
+            return std::make_unique<android::gnss::GnssMeasurement_V1_0>(gnssMeasurement);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssDebugInterface> GnssHal::getGnssDebugInterface() {
+    // Allow all causal combinations between IGnss.hal and IGnssDebug.hal. That means,
+    // 2.0@IGnss can be paired with {1.0, 2.0}@IGnssDebug
+    // 1.0@IGnss is paired with 1.0@IGnssDebug
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<IGnssDebugAidl> gnssDebugAidl;
+        auto status = gnssHalAidl->getExtensionGnssDebug(&gnssDebugAidl);
+        if (checkAidlStatus(status, "Unable to get a handle to GnssDebug interface.")) {
+            return std::make_unique<gnss::GnssDebug>(gnssDebugAidl);
+        }
+    }
+    if (gnssHal_V2_0 != nullptr) {
+        auto gnssDebug_V2_0 = gnssHal_V2_0->getExtensionGnssDebug_2_0();
+        if (checkHidlReturn(gnssDebug_V2_0, "Unable to get a handle to GnssDebug_V2_0.")) {
+            return std::make_unique<gnss::GnssDebug_V2_0>(gnssDebug_V2_0);
+        }
+    }
+    if (gnssHal != nullptr) {
+        auto gnssDebug_V1_0 = gnssHal->getExtensionGnssDebug();
+        if (checkHidlReturn(gnssDebug_V1_0, "Unable to get a handle to GnssDebug_V1_0.")) {
+            return std::make_unique<gnss::GnssDebug_V1_0>(gnssDebug_V1_0);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssConfigurationInterface> GnssHal::getGnssConfigurationInterface() {
+    if (gnssHalAidl != nullptr) {
+        sp<IGnssConfigurationAidl> gnssConfigurationAidl;
+        auto status = gnssHalAidl->getExtensionGnssConfiguration(&gnssConfigurationAidl);
+        if (checkAidlStatus(status,
+                            "Unable to get a handle to GnssConfiguration AIDL interface.")) {
+            return std::make_unique<android::gnss::GnssConfiguration>(gnssConfigurationAidl);
+        }
+    } else if (gnssHal_V2_1 != nullptr) {
+        auto gnssConfiguration = gnssHal_V2_1->getExtensionGnssConfiguration_2_1();
+        if (checkHidlReturn(gnssConfiguration,
+                            "Unable to get a handle to GnssConfiguration_V2_1")) {
+            return std::make_unique<android::gnss::GnssConfiguration_V2_1>(gnssConfiguration);
+        }
+    } else if (gnssHal_V2_0 != nullptr) {
+        auto gnssConfiguration = gnssHal_V2_0->getExtensionGnssConfiguration_2_0();
+        if (checkHidlReturn(gnssConfiguration,
+                            "Unable to get a handle to GnssConfiguration_V2_0")) {
+            return std::make_unique<android::gnss::GnssConfiguration_V2_0>(gnssConfiguration);
+        }
+    } else if (gnssHal_V1_1 != nullptr) {
+        auto gnssConfiguration = gnssHal_V1_1->getExtensionGnssConfiguration_1_1();
+        if (checkHidlReturn(gnssConfiguration,
+                            "Unable to get a handle to GnssConfiguration_V1_1")) {
+            return std::make_unique<gnss::GnssConfiguration_V1_1>(gnssConfiguration);
+        }
+    } else if (gnssHal != nullptr) {
+        auto gnssConfiguration = gnssHal->getExtensionGnssConfiguration();
+        if (checkHidlReturn(gnssConfiguration,
+                            "Unable to get a handle to GnssConfiguration_V1_0")) {
+            return std::make_unique<gnss::GnssConfiguration_V1_0>(gnssConfiguration);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssGeofenceInterface> GnssHal::getGnssGeofenceInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<hardware::gnss::IGnssGeofence> gnssGeofence;
+        auto status = gnssHalAidl->getExtensionGnssGeofence(&gnssGeofence);
+        if (checkAidlStatus(status, "Unable to get a handle to GnssGeofence AIDL interface.")) {
+            return std::make_unique<gnss::GnssGeofenceAidl>(gnssGeofence);
+        }
+    } else if (gnssHal != nullptr) {
+        auto gnssGeofencing = gnssHal->getExtensionGnssGeofencing();
+        if (checkHidlReturn(gnssGeofencing, "Unable to get a handle to GnssGeofencing")) {
+            return std::make_unique<gnss::GnssGeofenceHidl>(gnssGeofencing);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssBatchingInterface> GnssHal::getGnssBatchingInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<android::hardware::gnss::IGnssBatching> gnssBatchingAidl;
+        auto status = gnssHalAidl->getExtensionGnssBatching(&gnssBatchingAidl);
+        if (checkAidlStatus(status, "Unable to get a handle to GnssBatching interface.")) {
+            return std::make_unique<gnss::GnssBatching>(gnssBatchingAidl);
+        }
+    }
+    if (gnssHal_V2_0 != nullptr) {
+        auto gnssBatching_V2_0 = gnssHal_V2_0->getExtensionGnssBatching_2_0();
+        if (checkHidlReturn(gnssBatching_V2_0, "Unable to get a handle to GnssBatching_V2_0")) {
+            return std::make_unique<gnss::GnssBatching_V2_0>(gnssBatching_V2_0);
+        }
+    }
+    if (gnssHal != nullptr) {
+        auto gnssBatching_V1_0 = gnssHal->getExtensionGnssBatching();
+        if (checkHidlReturn(gnssBatching_V1_0, "Unable to get a handle to GnssBatching")) {
+            return std::make_unique<gnss::GnssBatching_V1_0>(gnssBatching_V1_0);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<MeasurementCorrectionsInterface> GnssHal::getMeasurementCorrectionsInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<android::hardware::gnss::measurement_corrections::IMeasurementCorrectionsInterface>
+                gnssMeasurementCorrectionsAidl;
+        auto status =
+                gnssHalAidl->getExtensionMeasurementCorrections(&gnssMeasurementCorrectionsAidl);
+        if (checkAidlStatus(status,
+                            "Unable to get a handle to GnssVisibilityControl AIDL interface.")) {
+            return std::make_unique<gnss::MeasurementCorrectionsIface_Aidl>(
+                    gnssMeasurementCorrectionsAidl);
+        }
+    }
+    if (gnssHal_V2_1 != nullptr) {
+        auto gnssCorrections = gnssHal_V2_1->getExtensionMeasurementCorrections_1_1();
+        if (checkHidlReturn(gnssCorrections,
+                            "Unable to get a handle to GnssMeasurementCorrections HIDL "
+                            "interface")) {
+            return std::make_unique<gnss::MeasurementCorrectionsIface_V1_1>(gnssCorrections);
+        }
+    }
+    if (gnssHal_V2_0 != nullptr) {
+        auto gnssCorrections = gnssHal_V2_0->getExtensionMeasurementCorrections();
+        if (checkHidlReturn(gnssCorrections,
+                            "Unable to get a handle to GnssMeasurementCorrections HIDL "
+                            "interface")) {
+            return std::make_unique<gnss::MeasurementCorrectionsIface_V1_0>(gnssCorrections);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssVisibilityControlInterface> GnssHal::getGnssVisibilityControlInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<android::hardware::gnss::visibility_control::IGnssVisibilityControl>
+                gnssVisibilityControlAidl;
+        auto status = gnssHalAidl->getExtensionGnssVisibilityControl(&gnssVisibilityControlAidl);
+        if (checkAidlStatus(status,
+                            "Unable to get a handle to GnssVisibilityControl AIDL interface.")) {
+            return std::make_unique<gnss::GnssVisibilityControlAidl>(gnssVisibilityControlAidl);
+        }
+    } else if (gnssHal_V2_0 != nullptr) {
+        auto gnssVisibilityControlHidl = gnssHal_V2_0->getExtensionVisibilityControl();
+        if (checkHidlReturn(gnssVisibilityControlHidl,
+                            "Unable to get a handle to GnssVisibilityControl HIDL interface")) {
+            return std::make_unique<gnss::GnssVisibilityControlHidl>(gnssVisibilityControlHidl);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssAntennaInfoInterface> GnssHal::getGnssAntennaInfoInterface() {
+    if (gnssHalAidl != nullptr && gnssHalAidl->getInterfaceVersion() >= 2) {
+        sp<IGnssAntennaInfoAidl> gnssAntennaInfoAidl;
+        auto status = gnssHalAidl->getExtensionGnssAntennaInfo(&gnssAntennaInfoAidl);
+        if (checkAidlStatus(status, "Unable to get a handle to GnssAntennaInfo interface.")) {
+            return std::make_unique<gnss::GnssAntennaInfoAidl>(gnssAntennaInfoAidl);
+        }
+    } else if (gnssHal_V2_1 != nullptr) {
+        auto gnssAntennaInfo_V2_1 = gnssHal_V2_1->getExtensionGnssAntennaInfo();
+        if (checkHidlReturn(gnssAntennaInfo_V2_1,
+                            "Unable to get a handle to GnssAntennaInfo_V2_1")) {
+            return std::make_unique<gnss::GnssAntennaInfo_V2_1>(gnssAntennaInfo_V2_1);
+        }
+    }
+    return nullptr;
+}
+
+std::unique_ptr<GnssPsdsInterface> GnssHal::getGnssPsdsInterface() {
+    if (gnssHalAidl != nullptr) {
+        sp<IGnssPsds> gnssPsdsAidl;
+        auto status = gnssHalAidl->getExtensionPsds(&gnssPsdsAidl);
+        if (checkAidlStatus(status, "Unable to get a handle to PSDS interface.")) {
+            return std::make_unique<gnss::GnssPsdsAidl>(gnssPsdsAidl);
+        }
+    } else if (gnssHal != nullptr) {
+        auto gnssXtra = gnssHal->getExtensionXtra();
+        if (checkHidlReturn(gnssXtra, "Unable to get a handle to XTRA interface.")) {
+            return std::make_unique<gnss::GnssPsdsHidl>(gnssXtra);
+        }
+    }
+    return nullptr;
+}
+
+sp<hardware::gnss::IGnssPowerIndication> GnssHal::getGnssPowerIndicationInterface() {
+    if (gnssHalAidl != nullptr) {
+        sp<hardware::gnss::IGnssPowerIndication> gnssPowerIndication;
+        auto status = gnssHalAidl->getExtensionGnssPowerIndication(&gnssPowerIndication);
+        if (checkAidlStatus(status, "Unable to get a handle to GnssPowerIndication")) {
+            return gnssPowerIndication;
+        }
+    }
+    return nullptr;
+}
+
+sp<hardware::gnss::V1_0::IGnssNi> GnssHal::getGnssNiInterface() {
+    if (gnssHal != nullptr) {
+        auto gnssNi = gnssHal->getExtensionGnssNi();
+        if (checkHidlReturn(gnssNi, "Unable to get a handle to GnssNi")) {
+            return gnssNi;
+        }
+    }
+    return nullptr;
+}
+
+} // namespace android::gnss
diff --git a/services/core/jni/gnss/Gnss.h b/services/core/jni/gnss/Gnss.h
new file mode 100644
index 0000000..c6743d6
--- /dev/null
+++ b/services/core/jni/gnss/Gnss.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_SERVER_GNSS_GNSS_H
+#define _ANDROID_SERVER_GNSS_GNSS_H
+
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/1.0/IGnss.h>
+#include <android/hardware/gnss/1.1/IGnss.h>
+#include <android/hardware/gnss/2.0/IGnss.h>
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include <android/hardware/gnss/BnGnss.h>
+#include <log/log.h>
+
+#include "AGnss.h"
+#include "AGnssRil.h"
+#include "GnssAntennaInfo.h"
+#include "GnssBatching.h"
+#include "GnssCallback.h"
+#include "GnssConfiguration.h"
+#include "GnssDebug.h"
+#include "GnssGeofence.h"
+#include "GnssMeasurement.h"
+#include "GnssNavigationMessage.h"
+#include "GnssPsds.h"
+#include "GnssVisibilityControl.h"
+#include "MeasurementCorrections.h"
+#include "jni.h"
+
+namespace android::gnss {
+
+struct GnssDeathRecipient : virtual public hardware::hidl_death_recipient {
+    // hidl_death_recipient interface
+    virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override {
+        ALOGE("IGNSS hidl service failed, trying to recover...");
+
+        JNIEnv* env = android::AndroidRuntime::getJNIEnv();
+        env->CallVoidMethod(android::mCallbacksObj, method_reportGnssServiceDied);
+    }
+};
+
+class GnssHal {
+public:
+    GnssHal();
+    ~GnssHal() {}
+
+    jboolean isSupported();
+    jboolean setCallback();
+    jboolean start();
+    jboolean stop();
+    jboolean setPositionMode(jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
+                             jint preferred_time, jboolean low_power_mode);
+    jboolean startSvStatus();
+    jboolean stopSvStatus();
+    jboolean startNmea();
+    jboolean stopNmea();
+    jint readNmea(jbyteArray& nmeaArray, jint& buffer_size);
+    void linkToDeath();
+    void close();
+    void deleteAidingData(jint flags);
+    void injectTime(jlong time, jlong timeReference, jint uncertainty);
+    void injectLocation(jint gnssLocationFlags, jdouble latitudeDegrees, jdouble longitudeDegrees,
+                        jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
+                        jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
+                        jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
+                        jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+                        jdouble elapsedRealtimeUncertaintyNanos);
+    void injectBestLocation(jint gnssLocationFlags, jdouble latitudeDegrees,
+                            jdouble longitudeDegrees, jdouble altitudeMeters,
+                            jfloat speedMetersPerSec, jfloat bearingDegrees,
+                            jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
+                            jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
+                            jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+                            jdouble elapsedRealtimeUncertaintyNanos);
+
+    std::unique_ptr<AGnssInterface> getAGnssInterface();
+    std::unique_ptr<AGnssRilInterface> getAGnssRilInterface();
+    std::unique_ptr<GnssNavigationMessageInterface> getGnssNavigationMessageInterface();
+    std::unique_ptr<GnssMeasurementInterface> getGnssMeasurementInterface();
+    std::unique_ptr<GnssDebugInterface> getGnssDebugInterface();
+    std::unique_ptr<GnssConfigurationInterface> getGnssConfigurationInterface();
+    std::unique_ptr<GnssGeofenceInterface> getGnssGeofenceInterface();
+    std::unique_ptr<GnssBatchingInterface> getGnssBatchingInterface();
+    std::unique_ptr<MeasurementCorrectionsInterface> getMeasurementCorrectionsInterface();
+    std::unique_ptr<GnssVisibilityControlInterface> getGnssVisibilityControlInterface();
+    std::unique_ptr<GnssAntennaInfoInterface> getGnssAntennaInfoInterface();
+    std::unique_ptr<GnssPsdsInterface> getGnssPsdsInterface();
+
+    sp<hardware::gnss::IGnssPowerIndication> getGnssPowerIndicationInterface();
+    sp<hardware::gnss::V1_0::IGnssNi> getGnssNiInterface();
+
+private:
+    sp<GnssDeathRecipient> gnssHalDeathRecipient = nullptr;
+    sp<hardware::gnss::V1_0::IGnss> gnssHal = nullptr;
+    sp<hardware::gnss::V1_1::IGnss> gnssHal_V1_1 = nullptr;
+    sp<hardware::gnss::V2_0::IGnss> gnssHal_V2_0 = nullptr;
+    sp<hardware::gnss::V2_1::IGnss> gnssHal_V2_1 = nullptr;
+    sp<hardware::gnss::IGnss> gnssHalAidl = nullptr;
+};
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSS_Gnss_H
diff --git a/services/core/jni/gnss/GnssCallback.cpp b/services/core/jni/gnss/GnssCallback.cpp
new file mode 100644
index 0000000..b931e91
--- /dev/null
+++ b/services/core/jni/gnss/GnssCallback.cpp
@@ -0,0 +1,413 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GnssCallbckJni"
+
+#include "GnssCallback.h"
+
+#include <hardware_legacy/power.h>
+
+#define WAKE_LOCK_NAME "GPS"
+
+namespace android::gnss {
+
+using android::hardware::gnss::V1_0::GnssLocationFlags;
+using binder::Status;
+using hardware::hidl_vec;
+using hardware::Return;
+using hardware::Void;
+
+using GnssLocationAidl = android::hardware::gnss::GnssLocation;
+using GnssLocation_V1_0 = android::hardware::gnss::V1_0::GnssLocation;
+using GnssLocation_V2_0 = android::hardware::gnss::V2_0::GnssLocation;
+using IGnssCallbackAidl = android::hardware::gnss::IGnssCallback;
+using IGnssCallback_V1_0 = android::hardware::gnss::V1_0::IGnssCallback;
+using IGnssCallback_V2_0 = android::hardware::gnss::V2_0::IGnssCallback;
+using IGnssCallback_V2_1 = android::hardware::gnss::V2_1::IGnssCallback;
+
+jmethodID method_reportGnssServiceDied;
+
+namespace {
+
+jmethodID method_reportLocation;
+jmethodID method_reportStatus;
+jmethodID method_reportSvStatus;
+jmethodID method_reportNmea;
+jmethodID method_setTopHalCapabilities;
+jmethodID method_setGnssYearOfHardware;
+jmethodID method_setGnssHardwareModelName;
+jmethodID method_requestLocation;
+jmethodID method_requestUtcTime;
+
+// Returns true if location has lat/long information.
+inline bool hasLatLong(const GnssLocationAidl& location) {
+    return (location.gnssLocationFlags & hardware::gnss::GnssLocation::HAS_LAT_LONG) != 0;
+}
+
+// Returns true if location has lat/long information.
+inline bool hasLatLong(const GnssLocation_V1_0& location) {
+    return (static_cast<uint32_t>(location.gnssLocationFlags) & GnssLocationFlags::HAS_LAT_LONG) !=
+            0;
+}
+
+// Returns true if location has lat/long information.
+inline bool hasLatLong(const GnssLocation_V2_0& location) {
+    return hasLatLong(location.v1_0);
+}
+
+inline jboolean boolToJbool(bool value) {
+    return value ? JNI_TRUE : JNI_FALSE;
+}
+
+// Must match the value from GnssMeasurement.java
+const uint32_t SVID_FLAGS_HAS_BASEBAND_CN0 = (1 << 4);
+
+} // anonymous namespace
+
+bool isSvStatusRegistered = false;
+bool isNmeaRegistered = false;
+
+void Gnss_class_init_once(JNIEnv* env, jclass& clazz) {
+    method_reportLocation =
+            env->GetMethodID(clazz, "reportLocation", "(ZLandroid/location/Location;)V");
+    method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
+    method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "(I[I[F[F[F[F[F)V");
+    method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
+
+    method_setTopHalCapabilities = env->GetMethodID(clazz, "setTopHalCapabilities", "(I)V");
+    method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
+    method_setGnssHardwareModelName =
+            env->GetMethodID(clazz, "setGnssHardwareModelName", "(Ljava/lang/String;)V");
+
+    method_requestLocation = env->GetMethodID(clazz, "requestLocation", "(ZZ)V");
+    method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
+    method_reportGnssServiceDied = env->GetMethodID(clazz, "reportGnssServiceDied", "()V");
+}
+
+Status GnssCallbackAidl::gnssSetCapabilitiesCb(const int capabilities) {
+    ALOGD("GnssCallbackAidl::%s: %du\n", __func__, capabilities);
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssStatusCb(const GnssStatusValue status) {
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) {
+    GnssCallbackHidl::gnssSvStatusCbImpl<std::vector<GnssSvInfo>, GnssSvInfo>(svInfoList);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssLocationCb(const hardware::gnss::GnssLocation& location) {
+    GnssCallbackHidl::gnssLocationCbImpl<hardware::gnss::GnssLocation>(location);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssNmeaCb(const int64_t timestamp, const std::string& nmea) {
+    // In AIDL v1, if no listener is registered, do not report nmea to the framework.
+    if (getInterfaceVersion() <= 1) {
+        if (!isNmeaRegistered) {
+            return Status::ok();
+        }
+    }
+    JNIEnv* env = getJniEnv();
+    /*
+     * The Java code will call back to read these values.
+     * We do this to avoid creating unnecessary String objects.
+     */
+    GnssCallbackHidl::sNmeaString = nmea.c_str();
+    GnssCallbackHidl::sNmeaStringLength = nmea.size();
+
+    env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssAcquireWakelockCb() {
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssReleaseWakelockCb() {
+    release_wake_lock(WAKE_LOCK_NAME);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssSetSystemInfoCb(const GnssSystemInfo& info) {
+    ALOGD("%s: yearOfHw=%d, name=%s\n", __func__, info.yearOfHw, info.name.c_str());
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, info.yearOfHw);
+    jstring jstringName = env->NewStringUTF(info.name.c_str());
+    env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
+    if (jstringName) {
+        env->DeleteLocalRef(jstringName);
+    }
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestTimeCb() {
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+Status GnssCallbackAidl::gnssRequestLocationCb(const bool independentFromGnss,
+                                               const bool isUserEmergency) {
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss),
+                        boolToJbool(isUserEmergency));
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+// Implementation of IGnssCallbackHidl
+
+Return<void> GnssCallbackHidl::gnssNameCb(const android::hardware::hidl_string& name) {
+    ALOGD("%s: name=%s\n", __func__, name.c_str());
+
+    JNIEnv* env = getJniEnv();
+    jstring jstringName = env->NewStringUTF(name.c_str());
+    env->CallVoidMethod(mCallbacksObj, method_setGnssHardwareModelName, jstringName);
+    if (jstringName) {
+        env->DeleteLocalRef(jstringName);
+    }
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+
+    return Void();
+}
+
+const char* GnssCallbackHidl::sNmeaString = nullptr;
+size_t GnssCallbackHidl::sNmeaStringLength = 0;
+
+template <class T>
+Return<void> GnssCallbackHidl::gnssLocationCbImpl(const T& location) {
+    JNIEnv* env = getJniEnv();
+
+    jobject jLocation = translateGnssLocation(env, location);
+
+    env->CallVoidMethod(mCallbacksObj, method_reportLocation, boolToJbool(hasLatLong(location)),
+                        jLocation);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    env->DeleteLocalRef(jLocation);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssLocationCb(const GnssLocation_V1_0& location) {
+    return gnssLocationCbImpl<GnssLocation_V1_0>(location);
+}
+
+Return<void> GnssCallbackHidl::gnssLocationCb_2_0(const GnssLocation_V2_0& location) {
+    return gnssLocationCbImpl<GnssLocation_V2_0>(location);
+}
+
+Return<void> GnssCallbackHidl::gnssStatusCb(const IGnssCallback_V2_0::GnssStatusValue status) {
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+template <>
+uint32_t GnssCallbackHidl::getHasBasebandCn0DbHzFlag(
+        const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svStatus) {
+    return SVID_FLAGS_HAS_BASEBAND_CN0;
+}
+
+template <>
+uint32_t GnssCallbackHidl::getHasBasebandCn0DbHzFlag(
+        const std::vector<IGnssCallbackAidl::GnssSvInfo>& svStatus) {
+    return SVID_FLAGS_HAS_BASEBAND_CN0;
+}
+
+template <>
+double GnssCallbackHidl::getBasebandCn0DbHz(
+        const std::vector<IGnssCallbackAidl::GnssSvInfo>& svInfoList, size_t i) {
+    return svInfoList[i].basebandCN0DbHz;
+}
+
+template <>
+double GnssCallbackHidl::getBasebandCn0DbHz(
+        const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList, size_t i) {
+    return svInfoList[i].basebandCN0DbHz;
+}
+
+template <>
+uint32_t GnssCallbackHidl::getGnssSvInfoListSize(const IGnssCallback_V1_0::GnssSvStatus& svStatus) {
+    return svStatus.numSvs;
+}
+
+template <>
+uint32_t GnssCallbackHidl::getConstellationType(const IGnssCallback_V1_0::GnssSvStatus& svStatus,
+                                                size_t i) {
+    return static_cast<uint32_t>(svStatus.gnssSvList.data()[i].constellation);
+}
+
+template <>
+uint32_t GnssCallbackHidl::getConstellationType(
+        const hidl_vec<IGnssCallback_V2_1::GnssSvInfo>& svInfoList, size_t i) {
+    return static_cast<uint32_t>(svInfoList[i].v2_0.constellation);
+}
+
+template <class T_list, class T_sv_info>
+Return<void> GnssCallbackHidl::gnssSvStatusCbImpl(const T_list& svStatus) {
+    // In HIDL or AIDL v1, if no listener is registered, do not report svInfoList to the framework.
+    if (!isSvStatusRegistered) {
+        return Void();
+    }
+
+    JNIEnv* env = getJniEnv();
+
+    uint32_t listSize = getGnssSvInfoListSize(svStatus);
+
+    jintArray svidWithFlagArray = env->NewIntArray(listSize);
+    jfloatArray cn0Array = env->NewFloatArray(listSize);
+    jfloatArray elevArray = env->NewFloatArray(listSize);
+    jfloatArray azimArray = env->NewFloatArray(listSize);
+    jfloatArray carrierFreqArray = env->NewFloatArray(listSize);
+    jfloatArray basebandCn0Array = env->NewFloatArray(listSize);
+
+    jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
+    jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
+    jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
+    jfloat* azim = env->GetFloatArrayElements(azimArray, 0);
+    jfloat* carrierFreq = env->GetFloatArrayElements(carrierFreqArray, 0);
+    jfloat* basebandCn0s = env->GetFloatArrayElements(basebandCn0Array, 0);
+
+    /*
+     * Read GNSS SV info.
+     */
+    for (size_t i = 0; i < listSize; ++i) {
+        enum ShiftWidth : uint8_t { SVID_SHIFT_WIDTH = 12, CONSTELLATION_TYPE_SHIFT_WIDTH = 8 };
+
+        const T_sv_info& info = getGnssSvInfoOfIndex(svStatus, i);
+        svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
+                (getConstellationType(svStatus, i) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
+                static_cast<uint32_t>(info.svFlag);
+        cn0s[i] = info.cN0Dbhz;
+        elev[i] = info.elevationDegrees;
+        azim[i] = info.azimuthDegrees;
+        carrierFreq[i] = info.carrierFrequencyHz;
+        svidWithFlags[i] |= getHasBasebandCn0DbHzFlag(svStatus);
+        basebandCn0s[i] = getBasebandCn0DbHz(svStatus, i);
+    }
+
+    env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
+    env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
+    env->ReleaseFloatArrayElements(elevArray, elev, 0);
+    env->ReleaseFloatArrayElements(azimArray, azim, 0);
+    env->ReleaseFloatArrayElements(carrierFreqArray, carrierFreq, 0);
+    env->ReleaseFloatArrayElements(basebandCn0Array, basebandCn0s, 0);
+
+    env->CallVoidMethod(mCallbacksObj, method_reportSvStatus, static_cast<jint>(listSize),
+                        svidWithFlagArray, cn0Array, elevArray, azimArray, carrierFreqArray,
+                        basebandCn0Array);
+
+    env->DeleteLocalRef(svidWithFlagArray);
+    env->DeleteLocalRef(cn0Array);
+    env->DeleteLocalRef(elevArray);
+    env->DeleteLocalRef(azimArray);
+    env->DeleteLocalRef(carrierFreqArray);
+    env->DeleteLocalRef(basebandCn0Array);
+
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssNmeaCb(int64_t timestamp,
+                                          const ::android::hardware::hidl_string& nmea) {
+    // In HIDL, if no listener is registered, do not report nmea to the framework.
+    if (!isNmeaRegistered) {
+        return Void();
+    }
+    JNIEnv* env = getJniEnv();
+    /*
+     * The Java code will call back to read these values.
+     * We do this to avoid creating unnecessary String objects.
+     */
+    sNmeaString = nmea.c_str();
+    sNmeaStringLength = nmea.size();
+
+    env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssSetCapabilitesCb(uint32_t capabilities) {
+    ALOGD("%s: %du\n", __func__, capabilities);
+
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_setTopHalCapabilities, capabilities);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssSetCapabilitiesCb_2_0(uint32_t capabilities) {
+    return GnssCallbackHidl::gnssSetCapabilitesCb(capabilities);
+}
+
+Return<void> GnssCallbackHidl::gnssSetCapabilitiesCb_2_1(uint32_t capabilities) {
+    return GnssCallbackHidl::gnssSetCapabilitesCb(capabilities);
+}
+
+Return<void> GnssCallbackHidl::gnssAcquireWakelockCb() {
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssReleaseWakelockCb() {
+    release_wake_lock(WAKE_LOCK_NAME);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssRequestTimeCb() {
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssRequestLocationCb(const bool independentFromGnss) {
+    return GnssCallbackHidl::gnssRequestLocationCb_2_0(independentFromGnss, /* isUserEmergency= */
+                                                       false);
+}
+
+Return<void> GnssCallbackHidl::gnssRequestLocationCb_2_0(const bool independentFromGnss,
+                                                         const bool isUserEmergency) {
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_requestLocation, boolToJbool(independentFromGnss),
+                        boolToJbool(isUserEmergency));
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+Return<void> GnssCallbackHidl::gnssSetSystemInfoCb(const IGnssCallback_V2_0::GnssSystemInfo& info) {
+    ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
+
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware, info.yearOfHw);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+} // namespace android::gnss
\ No newline at end of file
diff --git a/services/core/jni/gnss/GnssCallback.h b/services/core/jni/gnss/GnssCallback.h
new file mode 100644
index 0000000..a7f96fb
--- /dev/null
+++ b/services/core/jni/gnss/GnssCallback.h
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_SERVER_GNSS_GNSSCALLBACK_H
+#define _ANDROID_SERVER_GNSS_GNSSCALLBACK_H
+
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/2.1/IGnss.h>
+#include <android/hardware/gnss/BnGnssCallback.h>
+#include <log/log.h>
+
+#include <vector>
+
+#include "Utils.h"
+#include "jni.h"
+
+namespace android::gnss {
+
+namespace {
+
+extern jmethodID method_reportLocation;
+extern jmethodID method_reportStatus;
+extern jmethodID method_reportSvStatus;
+extern jmethodID method_reportNmea;
+extern jmethodID method_setTopHalCapabilities;
+extern jmethodID method_setGnssYearOfHardware;
+extern jmethodID method_setGnssHardwareModelName;
+extern jmethodID method_requestLocation;
+extern jmethodID method_requestUtcTime;
+
+} // anonymous namespace
+
+extern bool isSvStatusRegistered;
+extern bool isNmeaRegistered;
+
+extern jmethodID method_reportGnssServiceDied;
+
+void Gnss_class_init_once(JNIEnv* env, jclass& clazz);
+
+/*
+ * GnssCallbackAidl class implements the callback methods for AIDL IGnssCallback interface.
+ */
+class GnssCallbackAidl : public hardware::gnss::BnGnssCallback {
+public:
+    binder::Status gnssSetCapabilitiesCb(const int capabilities) override;
+    binder::Status gnssStatusCb(const GnssStatusValue status) override;
+    binder::Status gnssSvStatusCb(const std::vector<GnssSvInfo>& svInfoList) override;
+    binder::Status gnssLocationCb(const hardware::gnss::GnssLocation& location) override;
+    binder::Status gnssNmeaCb(const int64_t timestamp, const std::string& nmea) override;
+    binder::Status gnssAcquireWakelockCb() override;
+    binder::Status gnssReleaseWakelockCb() override;
+    binder::Status gnssSetSystemInfoCb(const GnssSystemInfo& info) override;
+    binder::Status gnssRequestTimeCb() override;
+    binder::Status gnssRequestLocationCb(const bool independentFromGnss,
+                                         const bool isUserEmergency) override;
+};
+
+/*
+ * GnssCallbackHidl class implements the callback methods for HIDL IGnssCallback interface.
+ */
+struct GnssCallbackHidl : public hardware::gnss::V2_1::IGnssCallback {
+    hardware::Return<void> gnssLocationCb(
+            const hardware::gnss::V1_0::GnssLocation& location) override;
+    hardware::Return<void> gnssStatusCb(
+            const hardware::gnss::V1_0::IGnssCallback::GnssStatusValue status) override;
+    hardware::Return<void> gnssSvStatusCb(
+            const hardware::gnss::V1_0::IGnssCallback::GnssSvStatus& svStatus) override {
+        return gnssSvStatusCbImpl<hardware::gnss::V1_0::IGnssCallback::GnssSvStatus,
+                                  hardware::gnss::V1_0::IGnssCallback::GnssSvInfo>(svStatus);
+    }
+    hardware::Return<void> gnssNmeaCb(int64_t timestamp,
+                                      const hardware::hidl_string& nmea) override;
+    hardware::Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
+    hardware::Return<void> gnssAcquireWakelockCb() override;
+    hardware::Return<void> gnssReleaseWakelockCb() override;
+    hardware::Return<void> gnssRequestTimeCb() override;
+    hardware::Return<void> gnssRequestLocationCb(const bool independentFromGnss) override;
+
+    hardware::Return<void> gnssSetSystemInfoCb(
+            const hardware::gnss::V1_0::IGnssCallback::GnssSystemInfo& info) override;
+
+    // New in 1.1
+    hardware::Return<void> gnssNameCb(const hardware::hidl_string& name) override;
+
+    // New in 2.0
+    hardware::Return<void> gnssRequestLocationCb_2_0(const bool independentFromGnss,
+                                                     const bool isUserEmergency) override;
+    hardware::Return<void> gnssSetCapabilitiesCb_2_0(uint32_t capabilities) override;
+    hardware::Return<void> gnssLocationCb_2_0(
+            const hardware::gnss::V2_0::GnssLocation& location) override;
+    hardware::Return<void> gnssSvStatusCb_2_0(
+            const hardware::hidl_vec<hardware::gnss::V2_0::IGnssCallback::GnssSvInfo>& svInfoList)
+            override {
+        return gnssSvStatusCbImpl<
+                hardware::hidl_vec<hardware::gnss::V2_0::IGnssCallback::GnssSvInfo>,
+                hardware::gnss::V1_0::IGnssCallback::GnssSvInfo>(svInfoList);
+    }
+
+    // New in 2.1
+    hardware::Return<void> gnssSvStatusCb_2_1(
+            const hardware::hidl_vec<hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>& svInfoList)
+            override {
+        return gnssSvStatusCbImpl<
+                hardware::hidl_vec<hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>,
+                hardware::gnss::V1_0::IGnssCallback::GnssSvInfo>(svInfoList);
+    }
+    hardware::Return<void> gnssSetCapabilitiesCb_2_1(uint32_t capabilities) override;
+
+    // TODO: Reconsider allocation cost vs threadsafety on these statics
+    static const char* sNmeaString;
+    static size_t sNmeaStringLength;
+
+    template <class T>
+    static hardware::Return<void> gnssLocationCbImpl(const T& location);
+
+    template <class T_list, class T_sv_info>
+    static hardware::Return<void> gnssSvStatusCbImpl(const T_list& svStatus);
+
+private:
+    template <class T>
+    static uint32_t getHasBasebandCn0DbHzFlag(const T& svStatus) {
+        return 0;
+    }
+
+    template <class T>
+    static double getBasebandCn0DbHz(const T& svStatus, size_t i) {
+        return 0.0;
+    }
+
+    template <class T>
+    static uint32_t getGnssSvInfoListSize(const T& svInfoList) {
+        return svInfoList.size();
+    }
+
+    static const hardware::gnss::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex(
+            const std::vector<hardware::gnss::IGnssCallback::GnssSvInfo>& svInfoList, size_t i) {
+        return svInfoList[i];
+    }
+
+    static const hardware::gnss::V1_0::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex(
+            const hardware::gnss::V1_0::IGnssCallback::GnssSvStatus& svStatus, size_t i) {
+        return svStatus.gnssSvList.data()[i];
+    }
+
+    static const hardware::gnss::V1_0::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex(
+            const hardware::hidl_vec<hardware::gnss::V2_0::IGnssCallback::GnssSvInfo>& svInfoList,
+            size_t i) {
+        return svInfoList[i].v1_0;
+    }
+
+    static const hardware::gnss::V1_0::IGnssCallback::GnssSvInfo& getGnssSvInfoOfIndex(
+            const hardware::hidl_vec<hardware::gnss::V2_1::IGnssCallback::GnssSvInfo>& svInfoList,
+            size_t i) {
+        return svInfoList[i].v2_0.v1_0;
+    }
+
+    template <class T>
+    static uint32_t getConstellationType(const T& svInfoList, size_t i) {
+        return static_cast<uint32_t>(svInfoList[i].constellation);
+    }
+};
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSS_GNSSCALLBACK_H
\ No newline at end of file
diff --git a/services/core/jni/gnss/GnssDebug.cpp b/services/core/jni/gnss/GnssDebug.cpp
index da53317..263a6c6 100644
--- a/services/core/jni/gnss/GnssDebug.cpp
+++ b/services/core/jni/gnss/GnssDebug.cpp
@@ -104,4 +104,10 @@
     return satelliteDataArray[i];
 }
 
+template <>
+int64_t GnssDebugUtil::getTimeEstimateMs(
+        const android::hardware::gnss::IGnssDebug::DebugData& data) {
+    return data.time.timeEstimateMs;
+}
+
 } // namespace android::gnss
diff --git a/services/core/jni/gnss/GnssDebug.h b/services/core/jni/gnss/GnssDebug.h
index 1e1a7b4..e02c2ac 100644
--- a/services/core/jni/gnss/GnssDebug.h
+++ b/services/core/jni/gnss/GnssDebug.h
@@ -113,12 +113,6 @@
     return data.time.timeEstimate;
 }
 
-template <>
-int64_t GnssDebugUtil::getTimeEstimateMs(
-        const android::hardware::gnss::IGnssDebug::DebugData& data) {
-    return data.time.timeEstimateMs;
-}
-
 template <class T_DebugData, class T_SatelliteData>
 jstring GnssDebugUtil::parseDebugData(JNIEnv* env, std::stringstream& internalState,
                                       const T_DebugData& data) {
diff --git a/services/core/jni/gnss/GnssMeasurementCallback.cpp b/services/core/jni/gnss/GnssMeasurementCallback.cpp
index 34ca559..d37f3bd 100644
--- a/services/core/jni/gnss/GnssMeasurementCallback.cpp
+++ b/services/core/jni/gnss/GnssMeasurementCallback.cpp
@@ -73,6 +73,11 @@
 jmethodID method_satellitePvtBuilderSetClockInfo;
 jmethodID method_satellitePvtBuilderSetIonoDelayMeters;
 jmethodID method_satellitePvtBuilderSetTropoDelayMeters;
+jmethodID method_satellitePvtBuilderSetTimeOfClock;
+jmethodID method_satellitePvtBuilderSetTimeOfEphemeris;
+jmethodID method_satellitePvtBuilderSetIssueOfDataClock;
+jmethodID method_satellitePvtBuilderSetIssueOfDataEphemeris;
+jmethodID method_satellitePvtBuilderSetEphemerisSource;
 jmethodID method_positionEcef;
 jmethodID method_velocityEcef;
 jmethodID method_clockInfo;
@@ -166,6 +171,21 @@
     method_satellitePvtBuilderSetTropoDelayMeters =
             env->GetMethodID(class_satellitePvtBuilder, "setTropoDelayMeters",
                              "(D)Landroid/location/SatellitePvt$Builder;");
+    method_satellitePvtBuilderSetTimeOfClock =
+            env->GetMethodID(class_satellitePvtBuilder, "setTimeOfClockSeconds",
+                             "(J)Landroid/location/SatellitePvt$Builder;");
+    method_satellitePvtBuilderSetTimeOfEphemeris =
+            env->GetMethodID(class_satellitePvtBuilder, "setTimeOfEphemerisSeconds",
+                             "(J)Landroid/location/SatellitePvt$Builder;");
+    method_satellitePvtBuilderSetIssueOfDataClock =
+            env->GetMethodID(class_satellitePvtBuilder, "setIssueOfDataClock",
+                             "(I)Landroid/location/SatellitePvt$Builder;");
+    method_satellitePvtBuilderSetIssueOfDataEphemeris =
+            env->GetMethodID(class_satellitePvtBuilder, "setIssueOfDataEphemeris",
+                             "(I)Landroid/location/SatellitePvt$Builder;");
+    method_satellitePvtBuilderSetEphemerisSource =
+            env->GetMethodID(class_satellitePvtBuilder, "setEphemerisSource",
+                             "(I)Landroid/location/SatellitePvt$Builder;");
     method_satellitePvtBuilderBuild = env->GetMethodID(class_satellitePvtBuilder, "build",
                                                        "()Landroid/location/SatellitePvt;");
 
@@ -429,6 +449,24 @@
                                            satellitePvt.tropoDelayMeters);
         }
 
+        if (this->getInterfaceVersion() >= 2) {
+            callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+                                           method_satellitePvtBuilderSetTimeOfClock,
+                                           satellitePvt.timeOfClockSeconds);
+            callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+                                           method_satellitePvtBuilderSetTimeOfEphemeris,
+                                           satellitePvt.timeOfEphemerisSeconds);
+            callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+                                           method_satellitePvtBuilderSetIssueOfDataClock,
+                                           satellitePvt.issueOfDataClock);
+            callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+                                           method_satellitePvtBuilderSetIssueOfDataEphemeris,
+                                           satellitePvt.issueOfDataEphemeris);
+            callObjectMethodIgnoringResult(env, satellitePvtBuilderObject,
+                                           method_satellitePvtBuilderSetEphemerisSource,
+                                           static_cast<int>(satellitePvt.ephemerisSource));
+        }
+
         jobject satellitePvtObject =
                 env->CallObjectMethod(satellitePvtBuilderObject, method_satellitePvtBuilderBuild);
         env->CallVoidMethod(object.get(), method_gnssMeasurementsSetSatellitePvt,
diff --git a/services/core/jni/gnss/GnssMeasurementCallback.h b/services/core/jni/gnss/GnssMeasurementCallback.h
index 17af949..c8f1803 100644
--- a/services/core/jni/gnss/GnssMeasurementCallback.h
+++ b/services/core/jni/gnss/GnssMeasurementCallback.h
@@ -52,7 +52,7 @@
 
 class GnssMeasurementCallbackAidl : public hardware::gnss::BnGnssMeasurementCallback {
 public:
-    GnssMeasurementCallbackAidl(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
+    GnssMeasurementCallbackAidl() : mCallbacksObj(getCallbacksObj()) {}
     android::binder::Status gnssMeasurementCb(const hardware::gnss::GnssData& data) override;
 
 private:
@@ -78,7 +78,7 @@
  */
 class GnssMeasurementCallbackHidl : public hardware::gnss::V2_1::IGnssMeasurementCallback {
 public:
-    GnssMeasurementCallbackHidl(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
+    GnssMeasurementCallbackHidl() : mCallbacksObj(getCallbacksObj()) {}
     hardware::Return<void> gnssMeasurementCb_2_1(
             const hardware::gnss::V2_1::IGnssMeasurementCallback::GnssData& data) override;
     hardware::Return<void> gnssMeasurementCb_2_0(
@@ -109,23 +109,22 @@
 
 class GnssMeasurementCallback {
 public:
-    GnssMeasurementCallback(jobject& callbacksObj) : mCallbacksObj(callbacksObj) {}
+    GnssMeasurementCallback() {}
     sp<GnssMeasurementCallbackAidl> getAidl() {
         if (callbackAidl == nullptr) {
-            callbackAidl = sp<GnssMeasurementCallbackAidl>::make(mCallbacksObj);
+            callbackAidl = sp<GnssMeasurementCallbackAidl>::make();
         }
         return callbackAidl;
     }
 
     sp<GnssMeasurementCallbackHidl> getHidl() {
         if (callbackHidl == nullptr) {
-            callbackHidl = sp<GnssMeasurementCallbackHidl>::make(mCallbacksObj);
+            callbackHidl = sp<GnssMeasurementCallbackHidl>::make();
         }
         return callbackHidl;
     }
 
 private:
-    jobject& mCallbacksObj;
     sp<GnssMeasurementCallbackAidl> callbackAidl;
     sp<GnssMeasurementCallbackHidl> callbackHidl;
 };
diff --git a/services/core/jni/gnss/GnssPsds.cpp b/services/core/jni/gnss/GnssPsds.cpp
new file mode 100644
index 0000000..51a1450
--- /dev/null
+++ b/services/core/jni/gnss/GnssPsds.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+// Define LOG_TAG before <log/log.h> to overwrite the default value.
+#define LOG_TAG "GnssPsdsJni"
+
+#include "GnssPsds.h"
+
+#include "Utils.h"
+
+using android::hardware::hidl_bitfield;
+using android::hardware::gnss::PsdsType;
+using IGnssPsdsAidl = android::hardware::gnss::IGnssPsds;
+using IGnssPsdsHidl = android::hardware::gnss::V1_0::IGnssXtra;
+
+namespace android::gnss {
+
+// Implementation of GnssPsds (AIDL HAL)
+
+GnssPsdsAidl::GnssPsdsAidl(const sp<IGnssPsdsAidl>& iGnssPsds) : mIGnssPsds(iGnssPsds) {
+    assert(mIGnssPsds != nullptr);
+}
+
+jboolean GnssPsdsAidl::setCallback(const std::unique_ptr<GnssPsdsCallback>& callback) {
+    auto status = mIGnssPsds->setCallback(callback->getAidl());
+    return checkAidlStatus(status, "IGnssPsdsAidl setCallback() failed.");
+}
+
+void GnssPsdsAidl::injectPsdsData(const jbyteArray& data, const jint& length,
+                                  const jint& psdsType) {
+    JNIEnv* env = getJniEnv();
+    jbyte* bytes = reinterpret_cast<jbyte*>(env->GetPrimitiveArrayCritical(data, 0));
+    auto status = mIGnssPsds->injectPsdsData(static_cast<PsdsType>(psdsType),
+                                             std::vector<uint8_t>((const uint8_t*)bytes,
+                                                                  (const uint8_t*)bytes + length));
+    checkAidlStatus(status, "IGnssPsdsAidl injectPsdsData() failed.");
+    env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
+}
+
+// Implementation of GnssPsdsHidl
+
+GnssPsdsHidl::GnssPsdsHidl(const sp<android::hardware::gnss::V1_0::IGnssXtra>& iGnssXtra)
+      : mIGnssXtra(iGnssXtra) {
+    assert(mIGnssXtra != nullptr);
+}
+
+jboolean GnssPsdsHidl::setCallback(const std::unique_ptr<GnssPsdsCallback>& callback) {
+    auto result = mIGnssXtra->setCallback(callback->getHidl());
+    return checkHidlReturn(result, "IGnssPsdsHidl setCallback() failed.");
+}
+
+void GnssPsdsHidl::injectPsdsData(const jbyteArray& data, const jint& length, const jint&) {
+    JNIEnv* env = getJniEnv();
+    jbyte* bytes = reinterpret_cast<jbyte*>(env->GetPrimitiveArrayCritical(data, 0));
+    auto result = mIGnssXtra->injectXtraData(std::string((const char*)bytes, length));
+    checkHidlReturn(result, "IGnssXtra injectXtraData() failed.");
+    env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
+}
+
+} // namespace android::gnss
diff --git a/services/core/jni/gnss/GnssPsds.h b/services/core/jni/gnss/GnssPsds.h
new file mode 100644
index 0000000..6b65ee8
--- /dev/null
+++ b/services/core/jni/gnss/GnssPsds.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_SERVER_GNSS_GNSSPSDS_H
+#define _ANDROID_SERVER_GNSS_GNSSPSDS_H
+
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/1.0/IGnssXtra.h>
+#include <android/hardware/gnss/BnGnssPsds.h>
+#include <log/log.h>
+
+#include "GnssPsdsCallback.h"
+#include "jni.h"
+
+namespace android::gnss {
+
+class GnssPsdsInterface {
+public:
+    virtual ~GnssPsdsInterface() {}
+    virtual jboolean setCallback(const std::unique_ptr<GnssPsdsCallback>& callback);
+    virtual void injectPsdsData(const jbyteArray& data, const jint& length, const jint& psdsType);
+};
+
+class GnssPsdsAidl : public GnssPsdsInterface {
+public:
+    GnssPsdsAidl(const sp<android::hardware::gnss::IGnssPsds>& iGnssPsds);
+    jboolean setCallback(const std::unique_ptr<GnssPsdsCallback>& callback) override;
+    void injectPsdsData(const jbyteArray& data, const jint& length, const jint& psdsType) override;
+
+private:
+    const sp<android::hardware::gnss::IGnssPsds> mIGnssPsds;
+};
+
+class GnssPsdsHidl : public GnssPsdsInterface {
+public:
+    GnssPsdsHidl(const sp<android::hardware::gnss::V1_0::IGnssXtra>& iGnssXtra);
+    jboolean setCallback(const std::unique_ptr<GnssPsdsCallback>& callback) override;
+    void injectPsdsData(const jbyteArray& data, const jint& length, const jint& psdsType) override;
+
+private:
+    const sp<android::hardware::gnss::V1_0::IGnssXtra> mIGnssXtra;
+};
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSS_GNSSPSDS_H
diff --git a/services/core/jni/gnss/GnssPsdsCallback.cpp b/services/core/jni/gnss/GnssPsdsCallback.cpp
new file mode 100644
index 0000000..1dd7022
--- /dev/null
+++ b/services/core/jni/gnss/GnssPsdsCallback.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GnssPsdsCbJni"
+
+#include "GnssPsdsCallback.h"
+
+#include <vector>
+
+#include "Utils.h"
+
+namespace android::gnss {
+
+namespace {
+jmethodID method_psdsDownloadRequest;
+} // anonymous namespace
+
+using binder::Status;
+using hardware::Return;
+using hardware::Void;
+using hardware::gnss::PsdsType;
+
+void GnssPsds_class_init_once(JNIEnv* env, jclass clazz) {
+    method_psdsDownloadRequest = env->GetMethodID(clazz, "psdsDownloadRequest", "(I)V");
+}
+
+// Implementation of android::hardware::gnss::IGnssPsdsCallback
+
+Status GnssPsdsCallbackAidl::downloadRequestCb(PsdsType psdsType) {
+    ALOGD("%s. psdsType: %d", __func__, static_cast<int32_t>(psdsType));
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, psdsType);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+// Implementation of android::hardware::gnss::V1_0::IGnssPsdsCallback
+
+Return<void> GnssPsdsCallbackHidl::downloadRequestCb() {
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_psdsDownloadRequest, /* psdsType= */ 1);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Void();
+}
+
+} // namespace android::gnss
diff --git a/services/core/jni/gnss/GnssPsdsCallback.h b/services/core/jni/gnss/GnssPsdsCallback.h
new file mode 100644
index 0000000..3ac7473
--- /dev/null
+++ b/services/core/jni/gnss/GnssPsdsCallback.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_SERVER_GNSS_GNSSPSDSCALLBACK_H
+#define _ANDROID_SERVER_GNSS_GNSSPSDSCALLBACK_H
+
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/1.0/IGnssXtraCallback.h>
+#include <android/hardware/gnss/BnGnssPsdsCallback.h>
+#include <log/log.h>
+
+#include "jni.h"
+
+namespace android::gnss {
+
+namespace {
+extern jmethodID method_psdsDownloadRequest;
+} // anonymous namespace
+
+void GnssPsds_class_init_once(JNIEnv* env, jclass clazz);
+
+class GnssPsdsCallbackAidl : public hardware::gnss::BnGnssPsdsCallback {
+public:
+    GnssPsdsCallbackAidl() {}
+    binder::Status downloadRequestCb(hardware::gnss::PsdsType psdsType) override;
+};
+
+class GnssPsdsCallbackHidl : public hardware::gnss::V1_0::IGnssXtraCallback {
+public:
+    GnssPsdsCallbackHidl() {}
+    hardware::Return<void> downloadRequestCb() override;
+};
+
+class GnssPsdsCallback {
+public:
+    GnssPsdsCallback() {}
+    sp<GnssPsdsCallbackAidl> getAidl() {
+        if (callbackAidl == nullptr) {
+            callbackAidl = sp<GnssPsdsCallbackAidl>::make();
+        }
+        return callbackAidl;
+    }
+
+    sp<GnssPsdsCallbackHidl> getHidl() {
+        if (callbackHidl == nullptr) {
+            callbackHidl = sp<GnssPsdsCallbackHidl>::make();
+        }
+        return callbackHidl;
+    }
+
+private:
+    sp<GnssPsdsCallbackAidl> callbackAidl;
+    sp<GnssPsdsCallbackHidl> callbackHidl;
+};
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSS_GNSSPSDSCALLBACK_H
\ No newline at end of file
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 33e97aa..3d40f48 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -45,7 +45,8 @@
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
 import static android.app.admin.DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER;
-import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_ID;
+import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_IDS;
+import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE;
 import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE_DRAWABLE;
 import static android.app.admin.DevicePolicyManager.EXTRA_RESOURCE_TYPE_STRING;
 import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO;
@@ -86,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;
@@ -131,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;
@@ -139,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;
@@ -213,6 +215,7 @@
 import android.app.admin.SystemUpdateInfo;
 import android.app.admin.SystemUpdatePolicy;
 import android.app.admin.UnsafeStateException;
+import android.app.admin.WifiSsidPolicy;
 import android.app.backup.IBackupManager;
 import android.app.compat.CompatChanges;
 import android.app.role.RoleManager;
@@ -268,6 +271,7 @@
 import android.net.VpnManager;
 import android.net.metrics.IpConnectivityLog;
 import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
@@ -388,6 +392,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
+import java.nio.charset.StandardCharsets;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
@@ -1999,9 +2004,6 @@
             mOwners.load();
             setDeviceOwnershipSystemPropertyLocked();
             findOwnerComponentIfNecessaryLocked();
-
-            // TODO PO may not have a class name either due to b/17652534.  Address that too.
-            updateDeviceOwnerLocked();
         }
     }
 
@@ -3142,23 +3144,6 @@
         }
     }
 
-    private void updateDeviceOwnerLocked() {
-        long ident = mInjector.binderClearCallingIdentity();
-        try {
-            // TODO This is to prevent DO from getting "clear data"ed, but it should also check the
-            // user id and also protect all other DAs too.
-            final ComponentName deviceOwnerComponent = mOwners.getDeviceOwnerComponent();
-            if (deviceOwnerComponent != null) {
-                mInjector.getIActivityManager()
-                        .updateDeviceOwner(deviceOwnerComponent.getPackageName());
-            }
-        } catch (RemoteException e) {
-            // Not gonna happen.
-        } finally {
-            mInjector.binderRestoreCallingIdentity(ident);
-        }
-    }
-
     static void validateQualityConstant(int quality) {
         switch (quality) {
             case PASSWORD_QUALITY_UNSPECIFIED:
@@ -3372,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");
     }
@@ -3396,7 +3381,7 @@
 
     @Override
     void handleStopUser(int userId) {
-        updateNetworkPreferenceForUser(userId, PreferentialNetworkServiceConfig.DEFAULT);
+        updateNetworkPreferenceForUser(userId, List.of(PreferentialNetworkServiceConfig.DEFAULT));
         stopOwnerService(userId, "stop-user");
     }
 
@@ -5957,6 +5942,7 @@
      *   (1.1) The caller is the Device Owner
      *   (1.2) The caller is another app in the same user as the device owner, AND
      *         The caller is the delegated certificate installer.
+     *   (1.3) The caller is a Profile Owner and the calling user is affiliated.
      * (2) The user has a profile owner, AND:
      *   (2.1) The profile owner has been granted access to Device IDs and one of the following
      *         holds:
@@ -5982,12 +5968,14 @@
          *  If the caller is from the work profile, then it must be the PO or the delegate, and
          *  it must have the right permission to access device identifiers.
          */
-        if (hasProfileOwner(caller.getUserId())) {
+        int callerUserId = caller.getUserId();
+        if (hasProfileOwner(callerUserId)) {
             // Make sure that the caller is the profile owner or delegate.
             Preconditions.checkCallAuthorization(canInstallCertificates(caller));
-            // Verify that the managed profile is on an organization-owned device and as such
-            // the profile owner can access Device IDs.
-            if (isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId())) {
+            // Verify that the managed profile is on an organization-owned device (or is affiliated
+            // with the device owner user) and as such the profile owner can access Device IDs.
+            if (isProfileOwnerOfOrganizationOwnedDevice(callerUserId)
+                    || isUserAffiliatedWithDevice(callerUserId)) {
                 return;
             }
             throw new SecurityException(
@@ -8590,7 +8578,6 @@
 
             mOwners.setDeviceOwner(admin, ownerName, userId);
             mOwners.writeDeviceOwner();
-            updateDeviceOwnerLocked();
             setDeviceOwnershipSystemPropertyLocked();
 
             //TODO(b/180371154): when provisionFullyManagedDevice is used in tests, remove this
@@ -8624,20 +8611,23 @@
                     admin.getPackageName(), userId, "set-device-owner");
 
             Slogf.i(LOG_TAG, "Device owner set: " + admin + " on user " + userId);
-
-            if (setProfileOwnerOnCurrentUserIfNecessary
-                    && mInjector.userManagerIsHeadlessSystemUserMode()) {
-                int currentForegroundUser = getCurrentForegroundUserId();
-                Slogf.i(LOG_TAG, "setDeviceOwner(): setting " + admin
-                        + " as profile owner on user " + currentForegroundUser);
-                // Sets profile owner on current foreground user since
-                // the human user will complete the DO setup workflow from there.
-                manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin,
-                        /* managedUser= */ currentForegroundUser, /* adminExtras= */ null,
-                        /* showDisclaimer= */ false);
-            }
-            return true;
         }
+
+        if (setProfileOwnerOnCurrentUserIfNecessary
+                && mInjector.userManagerIsHeadlessSystemUserMode()) {
+            int currentForegroundUser;
+            synchronized (getLockObject()) {
+                currentForegroundUser = getCurrentForegroundUserId();
+            }
+            Slogf.i(LOG_TAG, "setDeviceOwner(): setting " + admin
+                    + " as profile owner on user " + currentForegroundUser);
+            // Sets profile owner on current foreground user since
+            // the human user will complete the DO setup workflow from there.
+            manageUserUnchecked(/* deviceOwner= */ admin, /* profileOwner= */ admin,
+                    /* managedUser= */ currentForegroundUser, /* adminExtras= */ null,
+                    /* showDisclaimer= */ false);
+        }
+        return true;
     }
 
     @Override
@@ -8951,7 +8941,6 @@
 
         mOwners.clearDeviceOwner();
         mOwners.writeDeviceOwner();
-        updateDeviceOwnerLocked();
 
         clearDeviceOwnerUserRestriction(UserHandle.of(userId));
         mInjector.securityLogSetLoggingEnabledProperty(false);
@@ -9195,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;
         }
 
@@ -9208,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()) {
@@ -9223,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.");
@@ -9233,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);
@@ -9259,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;
@@ -9271,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:
@@ -9316,7 +9317,7 @@
                 Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED);
                 intent.putExtra(Intent.EXTRA_USER, new UserHandle(userId));
                 UserHandle parentHandle = new UserHandle(parent.id);
-                mLocalService.broadcastIntentToCrossProfileManifestReceiversAsUser(intent,
+                mLocalService.broadcastIntentToManifestReceivers(intent,
                         parentHandle, /* requiresPermission= */ true);
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
                         Intent.FLAG_RECEIVER_FOREGROUND);
@@ -9492,10 +9493,11 @@
             return false;
         }
 
-        // Allow access to the device owner or delegate cert installer.
+        // Allow access to the device owner or delegate cert installer or profile owner of an
+        // affiliated user
         ComponentName deviceOwner = getDeviceOwnerComponent(true);
         if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName)
-                    || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
+                || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
             return true;
         }
         final int userId = UserHandle.getUserId(uid);
@@ -9505,7 +9507,8 @@
         final boolean isCallerProfileOwnerOrDelegate = profileOwner != null
                 && (profileOwner.getPackageName().equals(packageName)
                         || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL));
-        if (isCallerProfileOwnerOrDelegate && isProfileOwnerOfOrganizationOwnedDevice(userId)) {
+        if (isCallerProfileOwnerOrDelegate && (isProfileOwnerOfOrganizationOwnedDevice(userId)
+                || isUserAffiliatedWithDevice(userId))) {
             return true;
         }
 
@@ -10866,7 +10869,7 @@
         final int userHandle = user.getIdentifier();
         final long id = mInjector.binderClearCallingIdentity();
         try {
-            maybeInstallDeviceManagerRoleHolderInUser(userHandle);
+            maybeInstallDevicePolicyManagementRoleHolderInUser(userHandle);
 
             manageUserUnchecked(admin, profileOwner, userHandle, adminExtras,
                     /* showDisclaimer= */ true);
@@ -12255,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;
         }
     }
 
@@ -13321,37 +13287,24 @@
             return DevicePolicyManagerService.this.getDefaultCrossProfilePackages();
         }
 
-        /**
-         * Sends the {@code intent} to the packages with cross profile capabilities.
-         *
-         * <p>This means the application must have the {@code crossProfile} property and
-         * and at least one of the following permissions:
-         *
-         * <ul>
-         *     <li>{@link android.Manifest.permission.INTERACT_ACROSS_PROFILES}
-         *     <li>{@link android.Manifest.permission.INTERACT_ACROSS_USERS}
-         *     <li>{@link android.Manifest.permission.INTERACT_ACROSS_USERS_FULL} permission or the
-         *     {@link AppOpsManager.OP_INTERACT_ACROSS_PROFILES} app operation authorization.
-         * </ul>
-         *
-         * <p>Note: The intent itself is not modified but copied before use.
-         *
-         * @param intent Template for the intent sent to the packages.
-         * @param parentHandle Handle of the user that will receive the intents.
-         * @param requiresPermission If false, all packages with the {@code crossProfile} property
-         *                           will receive the intent.
-         */
         @Override
-        public void broadcastIntentToCrossProfileManifestReceiversAsUser(Intent intent,
-                UserHandle parentHandle, boolean requiresPermission) {
+        public void broadcastIntentToManifestReceivers(
+                Intent intent, UserHandle parentHandle, boolean requiresPermission) {
             Objects.requireNonNull(intent);
             Objects.requireNonNull(parentHandle);
-            final int userId = parentHandle.getIdentifier();
             Slogf.i(LOG_TAG, "Sending %s broadcast to manifest receivers.", intent.getAction());
+            broadcastIntentToCrossProfileManifestReceivers(
+                    intent, parentHandle, requiresPermission);
+            broadcastIntentToDevicePolicyManagerRoleHolder(intent, parentHandle);
+        }
+
+        private void broadcastIntentToCrossProfileManifestReceivers(
+                Intent intent, UserHandle userHandle, boolean requiresPermission) {
+            final int userId = userHandle.getIdentifier();
             try {
                 final List<ResolveInfo> receivers = mIPackageManager.queryIntentReceivers(
                         intent, /* resolvedType= */ null,
-                        STOCK_PM_FLAGS, parentHandle.getIdentifier()).getList();
+                        STOCK_PM_FLAGS, userId).getList();
                 for (ResolveInfo receiver : receivers) {
                     final String packageName = receiver.getComponentInfo().packageName;
                     if (checkCrossProfilePackagePermissions(packageName, userId,
@@ -13362,7 +13315,7 @@
                         final Intent packageIntent = new Intent(intent)
                                 .setComponent(receiver.getComponentInfo().getComponentName())
                                 .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-                        mContext.sendBroadcastAsUser(packageIntent, parentHandle);
+                        mContext.sendBroadcastAsUser(packageIntent, userHandle);
                     }
                 }
             } catch (RemoteException ex) {
@@ -13371,6 +13324,32 @@
             }
         }
 
+        private void broadcastIntentToDevicePolicyManagerRoleHolder(
+                Intent intent, UserHandle userHandle) {
+            final int userId = userHandle.getIdentifier();
+            final String packageName = getDevicePolicyManagementRoleHolderPackageName(mContext);
+            if (packageName == null) {
+                return;
+            }
+            try {
+                final Intent packageIntent = new Intent(intent)
+                        .setPackage(packageName);
+                final List<ResolveInfo> receivers = mIPackageManager.queryIntentReceivers(
+                        packageIntent,
+                        /* resolvedType= */ null,
+                        STOCK_PM_FLAGS,
+                        userId).getList();
+                if (receivers.isEmpty()) {
+                    return;
+                }
+                packageIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+                mContext.sendBroadcastAsUser(packageIntent, userHandle);
+            } catch (RemoteException ex) {
+                Slogf.w(LOG_TAG, "Cannot get list of broadcast receivers for %s because: %s.",
+                        intent.getAction(), ex);
+            }
+        }
+
         /**
          * Checks whether the package {@code packageName} has the {@code MODIFY_QUIET_MODE}
          * permission granted for the user {@code userId}.
@@ -14960,7 +14939,13 @@
         final CallerIdentity caller = getCallerIdentity();
         Preconditions.checkCallAuthorization(hasCrossUsersPermission(caller, userId));
 
-        return isUserAffiliatedWithDeviceLocked(userId);
+        return isUserAffiliatedWithDevice(userId);
+    }
+
+    private boolean isUserAffiliatedWithDevice(@UserIdInt int userId) {
+        synchronized (getLockObject()) {
+            return isUserAffiliatedWithDeviceLocked(userId);
+        }
     }
 
     private boolean isUserAffiliatedWithDeviceLocked(@UserIdInt int userId) {
@@ -16437,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) {
@@ -16445,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;
         }
     }
 
@@ -16458,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;
@@ -16480,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);
     }
 
@@ -16494,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) {
@@ -17739,7 +17763,7 @@
                     startTime,
                     callerPackage);
 
-            maybeInstallDeviceManagerRoleHolderInUser(userInfo.id);
+            maybeInstallDevicePolicyManagementRoleHolderInUser(userInfo.id);
 
             installExistingAdminPackage(userInfo.id, admin.getPackageName());
             if (!enableAdminAndSetProfileOwner(
@@ -17807,24 +17831,25 @@
     private void onCreateAndProvisionManagedProfileCompleted(
             ManagedProfileProvisioningParams provisioningParams) {}
 
-    private void maybeInstallDeviceManagerRoleHolderInUser(int targetUserId) {
-        String deviceManagerRoleHolderPackageName = getDeviceManagerRoleHolderPackageName(mContext);
-        if (deviceManagerRoleHolderPackageName == null) {
-            Slogf.d(LOG_TAG, "No device manager role holder specified.");
+    private void maybeInstallDevicePolicyManagementRoleHolderInUser(int targetUserId) {
+        String devicePolicyManagerRoleHolderPackageName =
+                getDevicePolicyManagementRoleHolderPackageName(mContext);
+        if (devicePolicyManagerRoleHolderPackageName == null) {
+            Slogf.d(LOG_TAG, "No device policy management role holder specified.");
             return;
         }
         try {
             if (mIPackageManager.isPackageAvailable(
-                    deviceManagerRoleHolderPackageName, targetUserId)) {
-                Slogf.d(LOG_TAG, "The device manager role holder "
-                        + deviceManagerRoleHolderPackageName + " is already installed in "
+                    devicePolicyManagerRoleHolderPackageName, targetUserId)) {
+                Slogf.d(LOG_TAG, "The device policy management role holder "
+                        + devicePolicyManagerRoleHolderPackageName + " is already installed in "
                         + "user " + targetUserId);
                 return;
             }
-            Slogf.d(LOG_TAG, "Installing the device manager role holder "
-                    + deviceManagerRoleHolderPackageName + " in user " + targetUserId);
+            Slogf.d(LOG_TAG, "Installing the device policy management role holder "
+                    + devicePolicyManagerRoleHolderPackageName + " in user " + targetUserId);
             mIPackageManager.installExistingPackageAsUser(
-                    deviceManagerRoleHolderPackageName,
+                    devicePolicyManagerRoleHolderPackageName,
                     targetUserId,
                     PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
                     PackageManager.INSTALL_REASON_POLICY,
@@ -17834,10 +17859,10 @@
         }
     }
 
-    private String getDeviceManagerRoleHolderPackageName(Context context) {
+    private String getDevicePolicyManagementRoleHolderPackageName(Context context) {
         RoleManager roleManager = context.getSystemService(RoleManager.class);
         List<String> roleHolders =
-                roleManager.getRoleHolders(RoleManager.ROLE_DEVICE_MANAGER);
+                roleManager.getRoleHolders(RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
         if (roleHolders.isEmpty()) {
             return null;
         }
@@ -18070,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);
 
@@ -18107,8 +18134,9 @@
             }
 
             disallowAddUser();
-            setAdminCanGrantSensorsPermissionForUserUnchecked(deviceOwnerUserId,
-                    provisioningParams.canDeviceOwnerGrantSensorsPermissions());
+            setAdminCanGrantSensorsPermissionForUserUnchecked(
+                    deviceOwnerUserId, provisioningParams.canDeviceOwnerGrantSensorsPermissions());
+            setDemoDeviceStateUnchecked(deviceOwnerUserId, provisioningParams.isDemoDevice());
             onProvisionFullyManagedDeviceCompleted(provisioningParams);
             sendProvisioningCompletedBroadcast(
                     deviceOwnerUserId,
@@ -18307,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()) {
 
@@ -18324,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,
@@ -18524,9 +18549,21 @@
         );
     }
 
-    private void validateCurrentWifiMeetsAdminRequirements() {
+    private void notifyMinimumRequiredWifiSecurityLevelChanged(int level) {
         mInjector.binderWithCleanCallingIdentity(
-                () -> mInjector.getWifiManager().validateCurrentWifiMeetsAdminRequirements());
+                () -> mInjector.getWifiManager()
+                        .notifyMinimumRequiredWifiSecurityLevelChanged(level));
+    }
+
+    private void notifyWifiSsidPolicyChanged(int policyType, List<String> ssids) {
+        List<WifiSsid> wifiSsidList = new ArrayList<>();
+        for (String ssid : ssids) {
+            wifiSsidList.add(
+                    WifiSsid.fromBytes(ssid.getBytes(StandardCharsets.UTF_8)));
+        }
+        WifiSsidPolicy policy = new WifiSsidPolicy(policyType, new ArraySet<>(wifiSsidList));
+        mInjector.binderWithCleanCallingIdentity(
+                () -> mInjector.getWifiManager().notifyWifiSsidPolicyChanged(policy));
     }
 
     @Override
@@ -18546,7 +18583,7 @@
                 valueChanged = true;
             }
         }
-        if (valueChanged) validateCurrentWifiMeetsAdminRequirements();
+        if (valueChanged) notifyMinimumRequiredWifiSecurityLevelChanged(level);
     }
 
     @Override
@@ -18578,7 +18615,9 @@
             }
             if (changed) saveSettingsLocked(caller.getUserId());
         }
-        if (changed) validateCurrentWifiMeetsAdminRequirements();
+        if (changed && !ssids.isEmpty()) {
+            notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_ALLOWLIST, ssids);
+        }
     }
 
     @Override
@@ -18617,7 +18656,9 @@
             }
             if (changed) saveSettingsLocked(caller.getUserId());
         }
-        if (changed) validateCurrentWifiMeetsAdminRequirements();
+        if (changed) {
+            notifyWifiSsidPolicyChanged(WifiSsidPolicy.WIFI_SSID_POLICY_TYPE_DENYLIST, ssids);
+        }
     }
 
     @Override
@@ -18714,10 +18755,10 @@
         sendResourceUpdatedBroadcast(EXTRA_RESOURCE_TYPE_STRING, stringIds);
     }
 
-    private void sendResourceUpdatedBroadcast(String resourceType, String[] resourceIds) {
+    private void sendResourceUpdatedBroadcast(int resourceType, String[] resourceIds) {
         final Intent intent = new Intent(ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
-        intent.putExtra(EXTRA_RESOURCE_ID, resourceIds);
-        intent.putExtra(resourceType, /* value= */ true);
+        intent.putExtra(EXTRA_RESOURCE_IDS, resourceIds);
+        intent.putExtra(EXTRA_RESOURCE_TYPE, resourceType);
         intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
index 598f9e8..f3b164c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OverlayPackagesProvider.java
@@ -94,7 +94,7 @@
 
         String getActiveApexPackageNameContainingPackage(String packageName);
 
-        String getDeviceManagerRoleHolderPackageName(Context context);
+        String getDevicePolicyManagementRoleHolderPackageName(Context context);
     }
 
     private static final class DefaultInjector implements Injector {
@@ -110,11 +110,11 @@
         }
 
         @Override
-        public String getDeviceManagerRoleHolderPackageName(Context context) {
+        public String getDevicePolicyManagementRoleHolderPackageName(Context context) {
             return Binder.withCleanCallingIdentity(() -> {
                 RoleManager roleManager = context.getSystemService(RoleManager.class);
                 List<String> roleHolders =
-                        roleManager.getRoleHolders(RoleManager.ROLE_DEVICE_MANAGER);
+                        roleManager.getRoleHolders(RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
                 if (roleHolders.isEmpty()) {
                     return null;
                 }
@@ -166,7 +166,7 @@
     private Set<String> getDeviceManagerRoleHolders() {
         HashSet<String> result = new HashSet<>();
         String deviceManagerRoleHolderPackageName =
-                mInjector.getDeviceManagerRoleHolderPackageName(mContext);
+                mInjector.getDevicePolicyManagementRoleHolderPackageName(mContext);
         if (deviceManagerRoleHolderPackageName != null) {
             result.add(deviceManagerRoleHolderPackageName);
         }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e895d37..fa2850a 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;
@@ -214,8 +215,6 @@
 
 import dalvik.system.VMRuntime;
 
-import com.google.android.startop.iorap.IorapForwardingService;
-
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -386,8 +385,8 @@
             "com.android.server.DeviceIdleController";
     private static final String BLOB_STORE_MANAGER_SERVICE_CLASS =
             "com.android.server.blob.BlobStoreManagerService";
-    private static final String APP_SEARCH_MANAGER_SERVICE_CLASS =
-            "com.android.server.appsearch.AppSearchManagerService";
+    private static final String APPSEARCH_MODULE_LIFECYCLE_CLASS =
+            "com.android.server.appsearch.AppSearchModule$Lifecycle";
     private static final String ISOLATED_COMPILATION_SERVICE_CLASS =
             "com.android.server.compos.IsolatedCompilationService";
     private static final String ROLLBACK_MANAGER_SERVICE_CLASS =
@@ -415,13 +414,15 @@
     private static final String UWB_APEX_SERVICE_JAR_PATH =
             "/apex/com.android.uwb/javalib/service-uwb.jar";
     private static final String UWB_SERVICE_CLASS = "com.android.server.uwb.UwbService";
-    private static final String SAFETY_CENTER_SERVICE_CLASS =
-            "com.android.safetycenter.SafetyCenterService";
+    private static final String BLUETOOTH_APEX_SERVICE_JAR_PATH =
+            "/apex/com.android.bluetooth/javalib/service-bluetooth.jar";
     private static final String BLUETOOTH_SERVICE_CLASS =
             "com.android.server.bluetooth.BluetoothService";
+    private static final String SAFETY_CENTER_SERVICE_CLASS =
+            "com.android.safetycenter.SafetyCenterService";
 
-    private static final String SUPPLEMENTALPROCESS_SERVICE_CLASS =
-            "com.android.server.supplementalprocess.SupplementalProcessManagerService$Lifecycle";
+    private static final String SDK_SANDBOX_MANAGER_SERVICE_CLASS =
+            "com.android.server.sdksandbox.SdkSandboxManagerService$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();
@@ -1626,7 +1630,8 @@
                 Slog.i(TAG, "No Bluetooth Service (Bluetooth Hardware Not Present)");
             } else {
                 t.traceBegin("StartBluetoothService");
-                mSystemServiceManager.startService(BLUETOOTH_SERVICE_CLASS);
+                mSystemServiceManager.startServiceFromJar(BLUETOOTH_SERVICE_CLASS,
+                    BLUETOOTH_APEX_SERVICE_JAR_PATH);
                 t.traceEnd();
             }
 
@@ -1642,10 +1647,6 @@
             mSystemServiceManager.startService(PinnerService.class);
             t.traceEnd();
 
-            t.traceBegin("IorapForwardingService");
-            mSystemServiceManager.startService(IorapForwardingService.class);
-            t.traceEnd();
-
             if (Build.IS_DEBUGGABLE && ProfcollectForwardingService.enabled()) {
                 t.traceBegin("ProfcollectForwardingService");
                 mSystemServiceManager.startService(ProfcollectForwardingService.class);
@@ -2602,9 +2603,9 @@
         mSystemServiceManager.startService(IncidentCompanionService.class);
         t.traceEnd();
 
-        // Supplemental Process
-        t.traceBegin("StartSupplementalProcessManagerService");
-        mSystemServiceManager.startService(SUPPLEMENTALPROCESS_SERVICE_CLASS);
+        // SdkSandboxManagerService
+        t.traceBegin("StarSdkSandboxManagerService");
+        mSystemServiceManager.startService(SDK_SANDBOX_MANAGER_SERVICE_CLASS);
         t.traceEnd();
 
         if (safeMode) {
@@ -2764,8 +2765,8 @@
         mSystemServiceManager.startService(SAFETY_CENTER_SERVICE_CLASS);
         t.traceEnd();
 
-        t.traceBegin("AppSearchManagerService");
-        mSystemServiceManager.startService(APP_SEARCH_MANAGER_SERVICE_CLASS);
+        t.traceBegin("AppSearchModule");
+        mSystemServiceManager.startService(APPSEARCH_MODULE_LIFECYCLE_CLASS);
         t.traceEnd();
 
         if (SystemProperties.getBoolean("ro.config.isolated_compilation_enabled", false)) {
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 2d082e1..ca67bcb 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -50,6 +50,7 @@
 import android.util.EventLog;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -136,10 +137,12 @@
     private final Object mUsbMidiLock = new Object();
 
     // Number of times a USB MIDI 1.0 device has opened, based on the device name.
+    @GuardedBy("mUsbMidiLock")
     private final HashMap<String, Integer> mUsbMidiLegacyDeviceOpenCount =
             new HashMap<String, Integer>();
 
     // Whether a USB MIDI device has opened, based on the device name.
+    @GuardedBy("mUsbMidiLock")
     private final HashSet<String> mUsbMidiUniversalDeviceInUse = new HashSet<String>();
 
     // UID of BluetoothMidiService
@@ -768,7 +771,6 @@
         synchronized (mDevicesByInfo) {
             for (Device device : mDevicesByInfo.values()) {
                 if (device.isUidAllowed(uid)) {
-                    deviceInfos.add(device.getDeviceInfo());
                     // UMP devices have protocols that are not PROTOCOL_UNKNOWN
                     if (transport == MidiManager.TRANSPORT_UNIVERSAL_MIDI_PACKETS) {
                         if (device.getDeviceInfo().getDefaultProtocol()
@@ -1247,7 +1249,7 @@
         pw.decreaseIndent();
     }
 
-    // hold mUsbMidiLock before calling this
+    @GuardedBy("mUsbMidiLock")
     private boolean isUsbMidiDeviceInUseLocked(MidiDeviceInfo info) {
         String name = info.getProperties().getString(MidiDeviceInfo.PROPERTY_NAME);
         if (name.length() < MIDI_LEGACY_STRING.length()) {
@@ -1266,7 +1268,7 @@
         return false;
     }
 
-    // hold mUsbMidiLock before calling this
+    @GuardedBy("mUsbMidiLock")
     void addUsbMidiDeviceLocked(MidiDeviceInfo info) {
         String name = info.getProperties().getString(MidiDeviceInfo.PROPERTY_NAME);
         if (name.length() < MIDI_LEGACY_STRING.length()) {
@@ -1283,7 +1285,7 @@
         }
     }
 
-    // hold mUsbMidiLock before calling this
+    @GuardedBy("mUsbMidiLock")
     void removeUsbMidiDeviceLocked(MidiDeviceInfo info) {
         String name = info.getProperties().getString(MidiDeviceInfo.PROPERTY_NAME);
         if (name.length() < MIDI_LEGACY_STRING.length()) {
diff --git a/services/proguard.flags b/services/proguard.flags
index 0e081f1..425da6c 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -40,9 +40,15 @@
 # Global entities normally kept through explicit Manifest entries
 # TODO(b/210510433): Revisit and consider generating from frameworks/base/core/res/AndroidManifest.xml,
 # by including that manifest with the library rule that triggers optimization.
--keep,allowoptimization,allowaccessmodification class * extends android.app.backup.BackupAgent
--keep,allowoptimization,allowaccessmodification class * extends android.content.BroadcastReceiver
--keep,allowoptimization,allowaccessmodification class * extends android.content.ContentProvider
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.app.Activity
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.app.Service
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.app.backup.BackupAgent
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.content.BroadcastReceiver
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.content.ContentProvider
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.preference.Preference
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.view.View {
+  public <init>(...);
+}
 
 # Various classes subclassed in or referenced via JNI in ethernet-service
 -keep public class android.net.** { *; }
@@ -67,6 +73,7 @@
 -keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.GnssConfiguration$HalInterfaceVersion { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.GnssPowerStats { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.hal.GnssNative { *; }
+-keep,allowoptimization,allowaccessmodification class com.android.server.pm.PackageManagerShellCommandDataLoader { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.sensors.SensorManagerInternal$ProximityActiveListener { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.sensors.SensorService { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareImpl$AudioSessionProvider$AudioSession { *; }
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/startop/Android.bp b/services/startop/Android.bp
deleted file mode 100644
index c56c463..0000000
--- a/services/startop/Android.bp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    //   SPDX-license-identifier-MIT
-    //   SPDX-license-identifier-Unicode-DFS
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library_static {
-    name: "services.startop",
-    defaults: ["platform_service_defaults"],
-
-    static_libs: [
-        // frameworks/base/startop/iorap
-        "services.startop.iorap",
-    ],
-}
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/inprocesstests/AndroidTest.xml b/services/tests/inprocesstests/AndroidTest.xml
index b541512..f5fea1b 100644
--- a/services/tests/inprocesstests/AndroidTest.xml
+++ b/services/tests/inprocesstests/AndroidTest.xml
@@ -18,6 +18,8 @@
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-instrumentation" />
 
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true"/>
         <option name="test-file-name" value="FrameworksInProcessTests.apk"/>
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 3e60af3..670c159 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -52,7 +52,7 @@
         "service-blobstore",
         "service-jobscheduler",
         "service-permission.impl",
-        "service-supplementalprocess.impl",
+        "service-sdksandbox.impl",
         "services.companion",
         "services.core",
         "services.devicepolicy",
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/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
index 26b5218..4a40b5f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -1000,7 +1000,7 @@
             final String dummyPackageName = "com.android.test";
             final String dummyClassName = ".Foo";
             app.setHostingRecord(HostingRecord.byAppZygote(new ComponentName(
-                    dummyPackageName, dummyClassName), "", definingUid));
+                    dummyPackageName, dummyClassName), "", definingUid, ""));
         }
         app.mServices.setConnectionGroup(connectionGroup);
         app.mState.setReportedProcState(procState);
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index e6bb0ce..0535513 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -345,6 +345,7 @@
 
     @After
     public void tearDown() {
+        mBgRestrictionController.tearDown();
         mBgRestrictionController.getBackgroundHandlerThread().quitSafely();
     }
 
@@ -561,6 +562,7 @@
         DeviceConfigSession<Float> bgCurrentDrainRestrictedBucketThreshold = null;
         DeviceConfigSession<Float> bgCurrentDrainBgRestrictedThreshold = null;
         DeviceConfigSession<Boolean> bgPromptFgsWithNotiToBgRestricted = null;
+        DeviceConfigSession<Long> bgNotificationMinInterval = null;
 
         mBgRestrictionController.addAppBackgroundRestrictionListener(listener);
 
@@ -615,6 +617,13 @@
                             R.bool.config_bg_prompt_fgs_with_noti_to_bg_restricted));
             bgPromptFgsWithNotiToBgRestricted.set(true);
 
+            bgNotificationMinInterval = new DeviceConfigSession<>(
+                    DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+                    ConstantsObserver.KEY_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL,
+                    DeviceConfig::getLong,
+                    ConstantsObserver.DEFAULT_BG_ABUSIVE_NOTIFICATION_MINIMAL_INTERVAL_MS);
+            bgNotificationMinInterval.set(windowMs);
+
             mCurrentTimeMillis = 10_000L;
             doReturn(mCurrentTimeMillis - windowMs).when(stats).getStatsStartTimestamp();
             doReturn(mCurrentTimeMillis).when(stats).getStatsEndTimestamp();
@@ -754,6 +763,7 @@
             // Sleep a while and set a higher drain
             Thread.sleep(windowMs);
             clearInvocations(mInjector.getAppStandbyInternal());
+            clearInvocations(mInjector.getNotificationManager());
             clearInvocations(mBgRestrictionController);
 
             // We're not going to prompt the user if the abusive app has a FGS with notification.
@@ -794,6 +804,7 @@
             mAppFGSTracker.onForegroundServiceNotificationUpdated(
                     testPkgName, testUid, -notificationId);
             clearInvocations(mInjector.getAppStandbyInternal());
+            clearInvocations(mInjector.getNotificationManager());
             clearInvocations(mBgRestrictionController);
 
             runTestBgCurrentDrainMonitorOnce(listener, stats, uids,
@@ -832,6 +843,7 @@
             // Now we'll prompt the user even it has a FGS with notification.
             bgPromptFgsWithNotiToBgRestricted.set(true);
             clearInvocations(mInjector.getAppStandbyInternal());
+            clearInvocations(mInjector.getNotificationManager());
             clearInvocations(mBgRestrictionController);
 
             runTestBgCurrentDrainMonitorOnce(listener, stats, uids,
@@ -899,6 +911,7 @@
             closeIfNotNull(bgCurrentDrainRestrictedBucketThreshold);
             closeIfNotNull(bgCurrentDrainBgRestrictedThreshold);
             closeIfNotNull(bgPromptFgsWithNotiToBgRestricted);
+            closeIfNotNull(bgNotificationMinInterval);
         }
     }
 
@@ -1921,6 +1934,7 @@
                     .checkUidPermission(uid, perm);
             mInjector.getAppPermissionTracker().onPermissionsChanged(uid);
         }
+        waitForIdleHandler(mBgRestrictionController.getBackgroundHandler());
         runExemptionTestOnce(
                 packageName, uid, pid, serviceType, sleepMs, stopAfterSleep,
                 perm, mediaControllers, topStateChanges, resetFGSTracker, false,
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/FakeServiceConnector.java b/services/tests/mockingservicestests/src/com/android/server/app/FakeServiceConnector.java
index 0ae509e..182430d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/FakeServiceConnector.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/FakeServiceConnector.java
@@ -17,6 +17,7 @@
 package com.android.server.app;
 
 
+import android.annotation.Nullable;
 import android.os.IInterface;
 
 import com.android.internal.infra.AndroidFuture;
@@ -30,9 +31,10 @@
  * Tests provide a service instance via {@link #FakeServiceConnector(IInterface)} that will be
  * connected to and used to fulfill service jobs.
  */
-final class FakeServiceConnector<T extends IInterface> implements
-        ServiceConnector<T> {
+final class FakeServiceConnector<T extends IInterface> implements ServiceConnector<T> {
     private final T mService;
+    @Nullable
+    private ServiceLifecycleCallbacks mServiceLifecycleCallbacks;
     private boolean mIsConnected;
     private int mConnectCount = 0;
 
@@ -96,9 +98,17 @@
 
     @Override
     public void unbind() {
+        if (mServiceLifecycleCallbacks != null) {
+            mServiceLifecycleCallbacks.onDisconnected(mService);
+        }
         mIsConnected = false;
     }
 
+    @Override
+    public void setServiceLifecycleCallbacks(@Nullable ServiceLifecycleCallbacks<T> callbacks) {
+        mServiceLifecycleCallbacks = callbacks;
+    }
+
     private void markPossibleConnection() {
         if (mIsConnected) {
             return;
@@ -106,6 +116,21 @@
 
         mConnectCount += 1;
         mIsConnected = true;
+
+        if (mServiceLifecycleCallbacks != null) {
+            mServiceLifecycleCallbacks.onConnected(mService);
+        }
+    }
+
+    public void killServiceProcess() {
+        if (!mIsConnected) {
+            return;
+        }
+        mIsConnected = false;
+
+        if (mServiceLifecycleCallbacks != null) {
+            mServiceLifecycleCallbacks.onBinderDied();
+        }
     }
 
     /**
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
index d2358a0..023608c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -1167,7 +1167,14 @@
         startUser(gameManagerService, USER_ID_1);
         gameManagerService.setGameMode(
                 mPackageName, GameManager.GAME_MODE_PERFORMANCE, USER_ID_1);
-        GameState gameState = new GameState(isLoading, GameState.MODE_NONE);
+        int testMode = GameState.MODE_NONE;
+        int testLabel = 99;
+        int testQuality = 123;
+        GameState gameState = new GameState(isLoading, testMode, testLabel, testQuality);
+        assertEquals(isLoading, gameState.isLoading());
+        assertEquals(testMode, gameState.getMode());
+        assertEquals(testLabel, gameState.getLabel());
+        assertEquals(testQuality, gameState.getQuality());
         gameManagerService.setGameState(mPackageName, gameState, USER_ID_1);
         mTestLooper.dispatchAll();
         verify(mMockPowerManager, times(1)).setPowerMode(Mode.GAME_LOADING, isLoading);
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 ed232e5..575e351 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -46,7 +46,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 +76,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 +93,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Objects;
+import java.util.function.Consumer;
 
 
 /**
@@ -114,7 +121,16 @@
             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;
@@ -126,6 +142,8 @@
     private WindowManagerInternal mMockWindowManagerInternal;
     @Mock
     private IActivityManager mMockActivityManager;
+    @Mock
+    private ScreenshotHelper mMockScreenshotHelper;
     private MockContext mMockContext;
     private FakeGameClassifier mFakeGameClassifier;
     private FakeGameService mFakeGameService;
@@ -192,7 +210,8 @@
                 mMockWindowManagerService,
                 mMockWindowManagerInternal,
                 mFakeGameServiceConnector,
-                mFakeGameSessionServiceConnector);
+                mFakeGameSessionServiceConnector,
+                mMockScreenshotHelper);
     }
 
     @After
@@ -425,6 +444,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 +466,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();
@@ -713,6 +734,35 @@
     }
 
     @Test
+    public void gameSessionServiceDies_severalActiveGameSessions_destroysGameSessions() {
+        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));
+
+        startTask(11, GAME_A_MAIN_ACTIVITY);
+        mFakeGameService.requestCreateGameSession(11);
+
+        FakeGameSession gameSession11 = new FakeGameSession();
+        SurfacePackage mockSurfacePackage11 = Mockito.mock(SurfacePackage.class);
+        mFakeGameSessionService.removePendingFutureForTaskId(11)
+                .complete(new CreateGameSessionResult(gameSession11, mockSurfacePackage11));
+
+        mFakeGameSessionServiceConnector.killServiceProcess();
+
+        assertThat(gameSession10.mIsDestroyed).isTrue();
+        assertThat(gameSession11.mIsDestroyed).isTrue();
+        assertThat(mFakeGameServiceConnector.getIsConnected()).isTrue();
+        assertThat(mFakeGameSessionServiceConnector.getIsConnected()).isFalse();
+    }
+
+    @Test
     public void stop_severalActiveGameSessions_destroysGameSessionsAndUnbinds() throws Exception {
         mGameServiceProviderInstance.start();
 
@@ -770,27 +820,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
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/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index a0ac506..9a4f8e2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -16,11 +16,6 @@
 
 package com.android.server.job.controllers;
 
-import static android.app.job.JobInfo.PRIORITY_DEFAULT;
-import static android.app.job.JobInfo.PRIORITY_HIGH;
-import static android.app.job.JobInfo.PRIORITY_LOW;
-import static android.app.job.JobInfo.PRIORITY_MIN;
-
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -275,14 +270,14 @@
     }
 
     private void setCharging() {
-        when(mJobSchedulerService.isBatteryCharging()).thenReturn(true);
+        doReturn(true).when(mJobSchedulerService).isBatteryCharging();
         synchronized (mQuotaController.mLock) {
             mQuotaController.onBatteryStateChangedLocked();
         }
     }
 
     private void setDischarging() {
-        when(mJobSchedulerService.isBatteryCharging()).thenReturn(false);
+        doReturn(false).when(mJobSchedulerService).isBatteryCharging();
         synchronized (mQuotaController.mLock) {
             mQuotaController.onBatteryStateChangedLocked();
         }
@@ -415,14 +410,6 @@
         }
     }
 
-    private void setDeviceConfigFloat(String key, float val) {
-        mDeviceConfigPropertiesBuilder.setFloat(key, val);
-        synchronized (mQuotaController.mLock) {
-            mQuotaController.prepareForUpdatedConstantsLocked();
-            mQcConstants.processConstantLocked(mDeviceConfigPropertiesBuilder.build(), key);
-        }
-    }
-
     private void waitForNonDelayedMessagesProcessed() {
         mQuotaController.getHandler().runWithScissors(() -> {}, 15_000);
     }
@@ -861,7 +848,7 @@
                         SOURCE_USER_ID, SOURCE_PACKAGE, inputStats);
                 assertEquals(expectedStats, inputStats);
                 assertTrue(mQuotaController.isWithinQuotaLocked(
-                        SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX, PRIORITY_DEFAULT));
+                        SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX));
             }
             assertTrue("Job not ready: " + jobStatus, jobStatus.isReady());
         }
@@ -885,7 +872,7 @@
             assertEquals(expectedStats, inputStats);
             assertFalse(
                     mQuotaController.isWithinQuotaLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX));
         }
 
         // Quota should be exceeded due to activity in active timer.
@@ -910,7 +897,7 @@
             assertEquals(expectedStats, inputStats);
             assertFalse(
                     mQuotaController.isWithinQuotaLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX));
             assertFalse("Job unexpectedly ready: " + jobStatus, jobStatus.isReady());
         }
     }
@@ -1508,7 +1495,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 30 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
     }
 
@@ -1541,7 +1528,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         setStandbyBucket(FREQUENT_INDEX);
@@ -1551,7 +1538,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         setStandbyBucket(WORKING_INDEX);
@@ -1561,7 +1548,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(7 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         // ACTIVE window = allowed time, so jobs can essentially run non-stop until they reach the
@@ -1573,7 +1560,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
     }
 
@@ -1597,7 +1584,7 @@
             // Max time will phase out, so should use bucket limit.
             assertEquals(10 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
@@ -1613,7 +1600,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(10 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
@@ -1630,7 +1617,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(3 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
     }
 
@@ -1663,7 +1650,7 @@
             // window time.
             assertEquals(10 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
@@ -1690,107 +1677,7 @@
             // Max time only has one minute phase out. Bucket time has 2 minute phase out.
             assertEquals(9 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
-        }
-    }
-
-    /**
-     * Test getTimeUntilQuotaConsumedLocked when the determination is based on the job's priority.
-     */
-    @Test
-    public void testGetTimeUntilQuotaConsumedLocked_Priority() {
-        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-        // Close to RARE boundary.
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (24 * HOUR_IN_MILLIS - 30 * SECOND_IN_MILLIS),
-                        150 * SECOND_IN_MILLIS, 5), false);
-        // Far away from FREQUENT boundary.
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (7 * HOUR_IN_MILLIS), 2 * MINUTE_IN_MILLIS, 5), false);
-        // Overlap WORKING_SET boundary.
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (2 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS),
-                        2 * MINUTE_IN_MILLIS, 5), false);
-        // Close to ACTIVE boundary.
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (9 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
-
-        setStandbyBucket(RARE_INDEX);
-        synchronized (mQuotaController.mLock) {
-            assertEquals(30 * SECOND_IN_MILLIS,
-                    mQuotaController.getRemainingExecutionTimeLocked(
                             SOURCE_USER_ID, SOURCE_PACKAGE));
-            assertEquals(3 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH));
-            assertEquals(3 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
-            assertEquals(0,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW));
-            assertEquals(0,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN));
-        }
-
-        setStandbyBucket(FREQUENT_INDEX);
-        synchronized (mQuotaController.mLock) {
-            assertEquals(3 * MINUTE_IN_MILLIS,
-                    mQuotaController.getRemainingExecutionTimeLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE));
-            assertEquals(3 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH));
-            assertEquals(3 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
-            assertEquals(30 * SECOND_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW));
-            assertEquals(0,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN));
-        }
-
-        setStandbyBucket(WORKING_INDEX);
-        synchronized (mQuotaController.mLock) {
-            assertEquals(6 * MINUTE_IN_MILLIS,
-                    mQuotaController.getRemainingExecutionTimeLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE));
-            assertEquals(7 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH));
-            assertEquals(7 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
-            assertEquals(4 * MINUTE_IN_MILLIS + 30 * SECOND_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW));
-            assertEquals(2 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN));
-        }
-
-        // ACTIVE window = allowed time, so jobs can essentially run non-stop until they reach the
-        // max execution time.
-        setStandbyBucket(ACTIVE_INDEX);
-        synchronized (mQuotaController.mLock) {
-            assertEquals(7 * MINUTE_IN_MILLIS,
-                    mQuotaController.getRemainingExecutionTimeLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE));
-            assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_HIGH));
-            assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
-            assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_LOW));
-            assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 7 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_MIN));
         }
     }
 
@@ -1820,7 +1707,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 10 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
     }
 
@@ -1842,7 +1729,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(10 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
@@ -1854,7 +1741,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(10 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
@@ -1867,7 +1754,7 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(10 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
 
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
@@ -1882,15 +1769,15 @@
                             SOURCE_USER_ID, SOURCE_PACKAGE));
             assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 30 * MINUTE_IN_MILLIS,
                     mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE, PRIORITY_DEFAULT));
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
         }
     }
 
     @Test
     public void testIsWithinQuotaLocked_NeverApp() {
         synchronized (mQuotaController.mLock) {
-            assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test.never", NEVER_INDEX, PRIORITY_DEFAULT));
+            assertFalse(
+                    mQuotaController.isWithinQuotaLocked(0, "com.android.test.never", NEVER_INDEX));
         }
     }
 
@@ -1898,8 +1785,7 @@
     public void testIsWithinQuotaLocked_Charging() {
         setCharging();
         synchronized (mQuotaController.mLock) {
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", RARE_INDEX, PRIORITY_DEFAULT));
+            assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX));
         }
     }
 
@@ -1913,8 +1799,7 @@
                 createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test", 5);
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT));
+            assertTrue(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX));
         }
     }
 
@@ -1931,7 +1816,7 @@
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test.spam", jobCount);
             assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test.spam", WORKING_INDEX, PRIORITY_DEFAULT));
+                    0, "com.android.test.spam", WORKING_INDEX));
         }
 
         mQuotaController.saveTimingSession(0, "com.android.test.frequent",
@@ -1941,7 +1826,7 @@
                 createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 500), false);
         synchronized (mQuotaController.mLock) {
             assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test.frequent", FREQUENT_INDEX, PRIORITY_DEFAULT));
+                    0, "com.android.test.frequent", FREQUENT_INDEX));
         }
     }
 
@@ -1957,8 +1842,7 @@
                 createTimingSession(now - (5 * MINUTE_IN_MILLIS), 4 * MINUTE_IN_MILLIS, 5), false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test", 5);
-            assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT));
+            assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX));
         }
     }
 
@@ -1974,8 +1858,7 @@
                 false);
         synchronized (mQuotaController.mLock) {
             mQuotaController.incrementJobCountLocked(0, "com.android.test", jobCount);
-            assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT));
+            assertFalse(mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX));
         }
     }
 
@@ -2128,66 +2011,22 @@
 
                 assertEquals("Rare has incorrect quota status with " + (i + 1) + " sessions",
                         i < 2,
-                        mQuotaController.isWithinQuotaLocked(
-                                0, "com.android.test", RARE_INDEX, PRIORITY_DEFAULT));
+                        mQuotaController.isWithinQuotaLocked(0, "com.android.test", RARE_INDEX));
                 assertEquals("Frequent has incorrect quota status with " + (i + 1) + " sessions",
                         i < 3,
                         mQuotaController.isWithinQuotaLocked(
-                                0, "com.android.test", FREQUENT_INDEX, PRIORITY_DEFAULT));
+                                0, "com.android.test", FREQUENT_INDEX));
                 assertEquals("Working has incorrect quota status with " + (i + 1) + " sessions",
                         i < 4,
-                        mQuotaController.isWithinQuotaLocked(
-                                0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT));
+                        mQuotaController.isWithinQuotaLocked(0, "com.android.test", WORKING_INDEX));
                 assertEquals("Active has incorrect quota status with " + (i + 1) + " sessions",
                         i < 5,
-                        mQuotaController.isWithinQuotaLocked(
-                                0, "com.android.test", ACTIVE_INDEX, PRIORITY_DEFAULT));
+                        mQuotaController.isWithinQuotaLocked(0, "com.android.test", ACTIVE_INDEX));
             }
         }
     }
 
     @Test
-    public void testIsWithinQuotaLocked_Priority() {
-        setDischarging();
-        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-        mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
-        mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
-        mQuotaController.saveTimingSession(0, "com.android.test",
-                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
-        synchronized (mQuotaController.mLock) {
-            mQuotaController.incrementJobCountLocked(0, "com.android.test", 5);
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", FREQUENT_INDEX, PRIORITY_HIGH));
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", FREQUENT_INDEX, PRIORITY_DEFAULT));
-            assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", FREQUENT_INDEX, PRIORITY_LOW));
-            assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", FREQUENT_INDEX, PRIORITY_MIN));
-
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", WORKING_INDEX, PRIORITY_HIGH));
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", WORKING_INDEX, PRIORITY_DEFAULT));
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", WORKING_INDEX, PRIORITY_LOW));
-            assertFalse(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", WORKING_INDEX, PRIORITY_MIN));
-
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", ACTIVE_INDEX, PRIORITY_HIGH));
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", ACTIVE_INDEX, PRIORITY_DEFAULT));
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", ACTIVE_INDEX, PRIORITY_LOW));
-            assertTrue(mQuotaController.isWithinQuotaLocked(
-                    0, "com.android.test", ACTIVE_INDEX, PRIORITY_MIN));
-        }
-    }
-
-    @Test
     public void testIsWithinEJQuotaLocked_NeverApp() {
         JobStatus js = createExpeditedJobStatus("testIsWithinEJQuotaLocked_NeverApp", 1);
         setStandbyBucket(NEVER_INDEX, js);
@@ -2737,8 +2576,7 @@
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - 25 * HOUR_IN_MILLIS, 5 * MINUTE_IN_MILLIS, 1), false);
         synchronized (mQuotaController.mLock) {
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, standbyBucket);
+            mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
         }
         verify(mAlarmManager, timeout(1000).times(0)).setWindow(
                 anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
@@ -2790,128 +2628,6 @@
                 anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
     }
 
-    @Test
-    public void testMaybeScheduleStartAlarmLocked_Priority() {
-        // saveTimingSession calls maybeScheduleCleanupAlarmLocked which interferes with these tests
-        // because it schedules an alarm too. Prevent it from doing so.
-        spyOn(mQuotaController);
-        doNothing().when(mQuotaController).maybeScheduleCleanupAlarmLocked();
-
-        setDeviceConfigInt(QcConstants.KEY_MAX_SESSION_COUNT_RARE, 5);
-
-        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (24 * HOUR_IN_MILLIS), MINUTE_IN_MILLIS, 1), false);
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (7 * HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1), false);
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (HOUR_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1), false);
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (5 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 1), false);
-
-        InOrder inOrder = inOrder(mAlarmManager);
-
-        JobStatus jobDef = createJobStatus("testMaybeScheduleStartAlarmLocked_Priority",
-                SOURCE_PACKAGE, CALLING_UID,
-                new JobInfo.Builder(1, new ComponentName(mContext, "TestQuotaJobService"))
-                        .setPriority(PRIORITY_DEFAULT)
-                        .build());
-        JobStatus jobLow = createJobStatus("testMaybeScheduleStartAlarmLocked_Priority",
-                SOURCE_PACKAGE, CALLING_UID,
-                new JobInfo.Builder(2, new ComponentName(mContext, "TestQuotaJobService"))
-                        .setPriority(PRIORITY_LOW)
-                        .build());
-        JobStatus jobMin = createJobStatus("testMaybeScheduleStartAlarmLocked_Priority",
-                SOURCE_PACKAGE, CALLING_UID,
-                new JobInfo.Builder(3, new ComponentName(mContext, "TestQuotaJobService"))
-                        .setPriority(PRIORITY_MIN)
-                        .build());
-
-        setStandbyBucket(RARE_INDEX, jobDef, jobLow, jobMin);
-        synchronized (mQuotaController.mLock) {
-            mQuotaController.maybeStartTrackingJobLocked(jobMin, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX);
-            // Min job requires 5 mins of surplus.
-            long expectedAlarmTime = now + 23 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS;
-            inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow(
-                    anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStartTrackingJobLocked(jobLow, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX);
-            // Low job requires 2.5 mins of surplus.
-            expectedAlarmTime = now + 17 * HOUR_IN_MILLIS + 90 * SECOND_IN_MILLIS;
-            inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow(
-                    anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStartTrackingJobLocked(jobDef, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, RARE_INDEX);
-            // Default+ jobs require IN_QUOTA_BUFFER_MS.
-            expectedAlarmTime = now + mQcConstants.IN_QUOTA_BUFFER_MS;
-            inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow(
-                    anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStopTrackingJobLocked(jobMin, null, false);
-            mQuotaController.maybeStopTrackingJobLocked(jobLow, null, false);
-            mQuotaController.maybeStopTrackingJobLocked(jobDef, null, false);
-
-            setStandbyBucket(FREQUENT_INDEX, jobDef, jobLow, jobMin);
-
-            mQuotaController.maybeStartTrackingJobLocked(jobMin, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX);
-            // Min job requires 5 mins of surplus.
-            expectedAlarmTime = now + 7 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS;
-            inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow(
-                    anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStartTrackingJobLocked(jobLow, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX);
-            // Low job requires 2.5 mins of surplus.
-            expectedAlarmTime = now + HOUR_IN_MILLIS + 90 * SECOND_IN_MILLIS;
-            inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow(
-                    anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStartTrackingJobLocked(jobDef, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, FREQUENT_INDEX);
-            // Default+ jobs already have enough quota.
-            inOrder.verify(mAlarmManager, timeout(1000).times(0)).setWindow(
-                    anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStopTrackingJobLocked(jobMin, null, false);
-            mQuotaController.maybeStopTrackingJobLocked(jobLow, null, false);
-            mQuotaController.maybeStopTrackingJobLocked(jobDef, null, false);
-
-            setStandbyBucket(WORKING_INDEX, jobDef, jobLow, jobMin);
-
-            mQuotaController.maybeStartTrackingJobLocked(jobMin, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX);
-            // Min job requires 5 mins of surplus.
-            expectedAlarmTime = now + HOUR_IN_MILLIS + MINUTE_IN_MILLIS;
-            inOrder.verify(mAlarmManager, timeout(1000).times(1)).setWindow(
-                    anyInt(), eq(expectedAlarmTime), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStartTrackingJobLocked(jobLow, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX);
-            // Low job has enough surplus.
-            inOrder.verify(mAlarmManager, timeout(1000).times(0)).setWindow(
-                    anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-
-            mQuotaController.maybeStartTrackingJobLocked(jobDef, null);
-            mQuotaController.maybeScheduleStartAlarmLocked(
-                    SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX);
-            // Default+ jobs already have enough quota.
-            inOrder.verify(mAlarmManager, timeout(1000).times(0)).setWindow(
-                    anyInt(), anyLong(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
-        }
-    }
-
     /** Tests that the start alarm is properly rescheduled if the app's bucket is changed. */
     @Test
     public void testMaybeScheduleStartAlarmLocked_BucketChange() {
@@ -3212,8 +2928,6 @@
         setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
                 11 * MINUTE_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 2 * MINUTE_IN_MILLIS);
-        setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, .7f);
-        setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, .2f);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, 99 * MINUTE_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, 15 * MINUTE_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, 30 * MINUTE_IN_MILLIS);
@@ -3269,8 +2983,6 @@
         assertEquals(11 * MINUTE_IN_MILLIS,
                 mQuotaController.getAllowedTimePerPeriodMs()[RESTRICTED_INDEX]);
         assertEquals(2 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
-        assertEquals(.7f, mQuotaController.getAllowedTimeSurplusPriorityLow(), 1e-6);
-        assertEquals(.2f, mQuotaController.getAllowedTimeSurplusPriorityMin(), 1e-6);
         assertEquals(99 * MINUTE_IN_MILLIS,
                 mQuotaController.getBucketWindowSizes()[EXEMPTED_INDEX]);
         assertEquals(15 * MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[ACTIVE_INDEX]);
@@ -3327,8 +3039,6 @@
         setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
                 -MINUTE_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, -MINUTE_IN_MILLIS);
-        setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, -.1f);
-        setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, -.01f);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, -MINUTE_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, -MINUTE_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, -MINUTE_IN_MILLIS);
@@ -3379,8 +3089,6 @@
         assertEquals(MINUTE_IN_MILLIS,
                 mQuotaController.getAllowedTimePerPeriodMs()[RESTRICTED_INDEX]);
         assertEquals(0, mQuotaController.getInQuotaBufferMs());
-        assertEquals(0f, mQuotaController.getAllowedTimeSurplusPriorityLow(), 1e-6);
-        assertEquals(0f, mQuotaController.getAllowedTimeSurplusPriorityMin(), 1e-6);
         assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[EXEMPTED_INDEX]);
         assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[ACTIVE_INDEX]);
         assertEquals(MINUTE_IN_MILLIS, mQuotaController.getBucketWindowSizes()[WORKING_INDEX]);
@@ -3451,8 +3159,6 @@
         setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
                 25 * HOUR_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_IN_QUOTA_BUFFER_MS, 25 * HOUR_IN_MILLIS);
-        setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_LOW, 1f);
-        setDeviceConfigFloat(QcConstants.KEY_ALLOWED_TIME_SURPLUS_PRIORITY_MIN, .95f);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, 25 * HOUR_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_ACTIVE_MS, 25 * HOUR_IN_MILLIS);
         setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_WORKING_MS, 25 * HOUR_IN_MILLIS);
@@ -3492,8 +3198,6 @@
         assertEquals(24 * HOUR_IN_MILLIS,
                 mQuotaController.getAllowedTimePerPeriodMs()[RESTRICTED_INDEX]);
         assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
-        assertEquals(.9f, mQuotaController.getAllowedTimeSurplusPriorityLow(), 1e-6);
-        assertEquals(.9f, mQuotaController.getAllowedTimeSurplusPriorityMin(), 1e-6);
         assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[EXEMPTED_INDEX]);
         assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[ACTIVE_INDEX]);
         assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getBucketWindowSizes()[WORKING_INDEX]);
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index 4e4854c..d8f409d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -213,7 +213,7 @@
     public void testProperties() {
         assertThat(mManager.getName()).isEqualTo(NAME);
         assertThat(mManager.getProperties()).isEqualTo(PROPERTIES);
-        assertThat(mManager.getIdentity()).isEqualTo(IDENTITY);
+        assertThat(mManager.getProviderIdentity()).isEqualTo(IDENTITY);
         assertThat(mManager.hasProvider()).isTrue();
 
         ProviderProperties newProperties = new ProviderProperties.Builder()
@@ -230,7 +230,7 @@
         CallerIdentity newIdentity = CallerIdentity.forTest(OTHER_USER, 1, "otherpackage",
                 "otherattribution");
         mProvider.setIdentity(newIdentity);
-        assertThat(mManager.getIdentity()).isEqualTo(newIdentity);
+        assertThat(mManager.getProviderIdentity()).isEqualTo(newIdentity);
 
         mManager.setRealProvider(null);
         assertThat(mManager.hasProvider()).isFalse();
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 6510cd1..cb9f003 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -70,7 +70,7 @@
 import com.android.server.pm.pkg.parsing.ParsingPackageUtils
 import com.android.server.pm.resolution.ComponentResolver
 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
-import com.android.server.supplementalprocess.SupplementalProcessManagerLocal
+import com.android.server.sdksandbox.SdkSandboxManagerLocal
 import com.android.server.testutils.TestHandler
 import com.android.server.testutils.mock
 import com.android.server.testutils.nullable
@@ -577,7 +577,7 @@
                 1L, systemPartitions[0].privAppFolder,
                 withPackage = { pkg: PackageImpl ->
                     val applicationInfo: ApplicationInfo = createBasicApplicationInfo(pkg)
-                    mockQueryServices(SupplementalProcessManagerLocal.SERVICE_INTERFACE,
+                    mockQueryServices(SdkSandboxManagerLocal.SERVICE_INTERFACE,
                             createBasicServiceInfo(
                                     pkg, applicationInfo, "SupplementalProcessService"))
                     pkg
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..1319903 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")
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/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index a6c81a0..152f3b3 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -25,7 +25,6 @@
         "test-apps/JobTestApp/src/**/*.java",
 
         "test-apps/SuspendTestApp/src/**/*.java",
-        ":service-bluetooth-tests-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
     ],
     static_libs: [
         "frameworks-base-testutils",
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 53cab9e..a6194df 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -98,6 +98,8 @@
     <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK"/>
     <uses-permission
         android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/>
+    <uses-permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY" />
+    <uses-permission android:name="android.permission.READ_NEARBY_STREAMING_POLICY" />
 
     <uses-permission android:name="android.permission.PACKAGE_VERIFICATION_AGENT" />
 
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 953b536..1f016fb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -154,6 +154,7 @@
                 mMockWindowMagnificationMgr);
         when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
                 mMockFullScreenMagnificationController);
+        when(mMockMagnificationController.supportWindowMagnification()).thenReturn(true);
         when(mMockWindowManagerService.getAccessibilityController()).thenReturn(
                 mMockA11yController);
         when(mMockA11yController.isAccessibilityTracingEnabled()).thenReturn(false);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index 3ce2ed8..f3a0b7f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -1158,7 +1158,7 @@
         MagnificationCallbacks callbacks = getMagnificationCallbacks(DISPLAY_0);
         callbacks.onImeWindowVisibilityChanged(true);
         mMessageCapturingHandler.sendAllMessages();
-        verify(mRequestObserver).onImeWindowVisibilityChanged(eq(true));
+        verify(mRequestObserver).onImeWindowVisibilityChanged(eq(DISPLAY_0), eq(true));
     }
 
     private void setScaleToMagnifying() {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index ec59090..cc6d761 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -41,6 +41,7 @@
 
 import android.accessibilityservice.MagnificationConfig;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -100,6 +101,8 @@
     @Mock
     private Context mContext;
     @Mock
+    PackageManager mPackageManager;
+    @Mock
     private FullScreenMagnificationController mScreenMagnificationController;
     private MagnificationScaleProvider mScaleProvider;
     @Captor
@@ -136,6 +139,7 @@
         mMockResolver = new MockContentResolver();
         mMockResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mMockResolver);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
         Settings.Secure.putFloatForUser(mMockResolver,
                 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, DEFAULT_SCALE,
                 CURRENT_USER_ID);
@@ -748,7 +752,7 @@
         MagnificationController spyController = spy(mMagnificationController);
         spyController.onWindowMagnificationActivationState(TEST_DISPLAY, true);
 
-        spyController.onImeWindowVisibilityChanged(true);
+        spyController.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
 
         verify(spyController).logMagnificationModeWithIme(
                 eq(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
@@ -759,7 +763,7 @@
         MagnificationController spyController = spy(mMagnificationController);
         spyController.onFullScreenMagnificationActivationState(TEST_DISPLAY, true);
 
-        spyController.onImeWindowVisibilityChanged(true);
+        spyController.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
 
         verify(spyController).logMagnificationModeWithIme(
                 eq(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN));
@@ -768,7 +772,7 @@
     @Test
     public void imeWindowStateShown_noMagnifying_noLogAnyMode() {
         MagnificationController spyController = spy(mMagnificationController);
-        spyController.onImeWindowVisibilityChanged(true);
+        spyController.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
 
         verify(spyController, never()).logMagnificationModeWithIme(anyInt());
     }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
index 3822dc3..4b77764 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationConnectionWrapperTest.java
@@ -94,6 +94,14 @@
     }
 
     @Test
+    public void moveWindowMagnifierToPosition() throws RemoteException {
+        mConnectionWrapper.moveWindowMagnifierToPosition(TEST_DISPLAY, 100, 150,
+                mAnimationCallback);
+        verify(mConnection).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
+                eq(100f), eq(150f), any(IRemoteMagnificationAnimationCallback.class));
+    }
+
+    @Test
     public void showMagnificationButton() throws RemoteException {
         mConnectionWrapper.showMagnificationButton(TEST_DISPLAY,
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index 0742c09..978000a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -21,6 +21,8 @@
 
 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.ArgumentMatchers.notNull;
 import static org.mockito.Mockito.doAnswer;
@@ -54,6 +56,8 @@
 import android.view.accessibility.IWindowMagnificationConnectionCallback;
 import android.view.accessibility.MagnificationAnimationCallback;
 
+import androidx.test.core.app.ApplicationProvider;
+
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityTraceManager;
@@ -99,12 +103,7 @@
                 mMockCallback, mMockTrace, new MagnificationScaleProvider(mContext));
 
         when(mContext.getContentResolver()).thenReturn(mResolver);
-        doAnswer((InvocationOnMock invocation) -> {
-            final boolean connect = (Boolean) invocation.getArguments()[0];
-            mWindowMagnificationManager.setConnection(
-                    connect ? mMockConnection.getConnection() : null);
-            return null;
-        }).when(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(anyBoolean());
+        stubSetConnection(false);
 
         mResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         Settings.Secure.putFloatForUser(mResolver,
@@ -112,6 +111,25 @@
                 CURRENT_USER_ID);
     }
 
+    private void stubSetConnection(boolean needDelay) {
+        doAnswer((InvocationOnMock invocation) -> {
+            final boolean connect = (Boolean) invocation.getArguments()[0];
+            // Simulates setConnection() called by another process.
+            if (needDelay) {
+                final Context context = ApplicationProvider.getApplicationContext();
+                context.getMainThreadHandler().postDelayed(
+                        () -> {
+                            mWindowMagnificationManager.setConnection(
+                                    connect ? mMockConnection.getConnection() : null);
+                        }, 10);
+            } else {
+                mWindowMagnificationManager.setConnection(
+                        connect ? mMockConnection.getConnection() : null);
+            }
+            return true;
+        }).when(mMockStatusBarManagerInternal).requestWindowMagnificationConnection(anyBoolean());
+    }
+
     @Test
     public void setConnection_connectionIsNull_wrapperIsNullAndLinkToDeath() {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
@@ -275,32 +293,33 @@
     }
 
     @Test
-    public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnification()
+    public void onRectangleOnScreenRequested_trackingDisabledByOnDrag_withoutMovingMagnifier()
             throws RemoteException {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
         final Region outRegion = new Region();
         mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
         final Rect requestedRect = outRegion.getBounds();
         requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
-        mMockConnection.getConnectionCallback().onDrag(TEST_DISPLAY);
+        mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
 
         mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
                 requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
 
-        verify(mMockConnection.getConnection(), never()).enableWindowMagnification(eq(TEST_DISPLAY),
-                eq(3f), eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
-                eq(0f), eq(0f), notNull());
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
     }
 
 
     @Test
-    public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnification()
+    public void onRectangleOnScreenRequested_trackingDisabledByScroll_withoutMovingMagnifier()
             throws RemoteException {
         final float distanceX = 10f;
         final float distanceY = 10f;
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
         final Region outRegion = new Region();
         mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
         final Rect requestedRect = outRegion.getBounds();
@@ -310,16 +329,16 @@
         mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
                 requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
 
-        verify(mMockConnection.getConnection(), never()).enableWindowMagnification(eq(TEST_DISPLAY),
-                eq(3f), eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
-                eq(0f), eq(0f), notNull());
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
     }
 
     @Test
-    public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnification()
+    public void onRectangleOnScreenRequested_requestRectangleInBound_withoutMovingMagnifier()
             throws RemoteException {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
         final Region outRegion = new Region();
         mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
         final Rect requestedRect = outRegion.getBounds();
@@ -328,12 +347,11 @@
         mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
                 requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
 
-        verify(mMockConnection.getConnection(), never()).enableWindowMagnification(eq(TEST_DISPLAY),
-                eq(3f), eq(500f), eq(500f), eq(0f), eq(0f), notNull());
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
     }
-
     @Test
-    public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnification()
+    public void onRectangleOnScreenRequested_imeVisibilityDefaultInvisible_withoutMovingMagnifier()
             throws RemoteException {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
@@ -345,20 +363,56 @@
         mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
                 requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
 
-        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY), eq(3f),
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingEnabledByDefault_movingMagnifier()
+            throws RemoteException {
+        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+
+        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
                 eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
-                eq(0f), eq(0f), notNull());
+                any(IRemoteMagnificationAnimationCallback.class));
     }
 
     @Test
-    public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnification()
+    public void onRectangleOnScreenRequested_imeInvisible_withoutMovingMagnifier()
             throws RemoteException {
-        final PointF initialPoint = new PointF(50f, 50f);
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
-        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f,
-                initialPoint.x, initialPoint.y);
-        mMockConnection.getConnectionCallback().onDrag(TEST_DISPLAY);
-        mWindowMagnificationManager.onImeWindowVisibilityChanged(true);
+        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        final Region outRegion = new Region();
+        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
+        final Rect requestedRect = outRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, false);
+
+        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection(), never())
+                .moveWindowMagnifierToPosition(anyInt(), anyFloat(), anyFloat(), any());
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingEnabledByDragAndReset_movingMagnifier()
+            throws RemoteException {
+        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        mMockConnection.getConnectionCallback().onMove(TEST_DISPLAY);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
         final Region outRegion = new Region();
         mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, outRegion);
         final Rect requestedRect = outRegion.getBounds();
@@ -367,16 +421,16 @@
         mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
                 requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
 
-        verify(mMockConnection.getConnection()).enableWindowMagnification(eq(TEST_DISPLAY),
-                eq(3f), eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
-                eq(0f), eq(0f), notNull());
+        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
+                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
+                any(IRemoteMagnificationAnimationCallback.class));
     }
 
     @Test
-    public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnification()
-            throws RemoteException {
+    public void onRectangleOnScreenRequested_followTypingIsDisabled_withoutMovingMagnifier() {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
         final Region beforeRegion = new Region();
         mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
         final Rect requestedRect = beforeRegion.getBounds();
@@ -392,6 +446,48 @@
     }
 
     @Test
+    public void onRectangleOnScreenRequested_trackingDisabled_withoutMovingMagnifier() {
+        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
+        final Region beforeRegion = new Region();
+        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+        final Rect requestedRect = beforeRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+
+        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        final Region afterRegion = new Region();
+        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, afterRegion);
+        assertEquals(afterRegion, beforeRegion);
+    }
+
+    @Test
+    public void onRectangleOnScreenRequested_trackingDisabledAndEnabledMagnifier_movingMagnifier()
+            throws RemoteException {
+        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3.0f, 50f, 50f);
+        mWindowMagnificationManager.onImeWindowVisibilityChanged(TEST_DISPLAY, true);
+        mWindowMagnificationManager.setTrackingTypingFocusEnabled(TEST_DISPLAY, false);
+        final Region beforeRegion = new Region();
+        mWindowMagnificationManager.getMagnificationSourceBounds(TEST_DISPLAY, beforeRegion);
+        final Rect requestedRect = beforeRegion.getBounds();
+        requestedRect.offsetTo(requestedRect.right + 10, requestedRect.bottom + 10);
+        mWindowMagnificationManager.disableWindowMagnification(TEST_DISPLAY, false);
+        // Enabling a window magnifier again will turn on the tracking typing focus functionality.
+        mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, NaN, NaN, NaN);
+
+        mWindowMagnificationManager.onRectangleOnScreenRequested(TEST_DISPLAY,
+                requestedRect.left, requestedRect.top, requestedRect.right, requestedRect.bottom);
+
+        verify(mMockConnection.getConnection()).moveWindowMagnifierToPosition(eq(TEST_DISPLAY),
+                eq(requestedRect.exactCenterX()), eq(requestedRect.exactCenterY()),
+                any(IRemoteMagnificationAnimationCallback.class));
+    }
+
+    @Test
     public void moveWindowMagnifier_enabled_invokeConnectionMethod() throws RemoteException {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 2f, NaN, NaN);
@@ -464,7 +560,7 @@
     public void
             requestConnectionToNull_disableAllMagnifiersAndRequestWindowMagnificationConnection()
             throws RemoteException {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        assertTrue(mWindowMagnificationManager.requestConnection(true));
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, NaN, NaN);
 
         assertTrue(mWindowMagnificationManager.requestConnection(false));
@@ -499,7 +595,7 @@
 
     @Test
     public void requestConnectionToNull_expectedGetterResults() {
-        mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
+        mWindowMagnificationManager.requestConnection(true);
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1);
 
         mWindowMagnificationManager.requestConnection(false);
@@ -513,6 +609,20 @@
     }
 
     @Test
+    public void enableWindowMagnification_connecting_invokeConnectionMethodAfterConnected()
+            throws RemoteException {
+        stubSetConnection(true);
+        mWindowMagnificationManager.requestConnection(true);
+
+        assertTrue(mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f, 1, 1));
+
+        // Invoke enableWindowMagnification if the connection is connected.
+        verify(mMockConnection.getConnection()).enableWindowMagnification(
+                eq(TEST_DISPLAY), eq(3f),
+                eq(1f), eq(1f), eq(0f), eq(0f), notNull());
+    }
+
+    @Test
     public void resetAllMagnification_enabledBySameId_windowMagnifiersDisabled() {
         mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
         mWindowMagnificationManager.enableWindowMagnification(TEST_DISPLAY, 3f,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index b255a35..25cf8a8 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -219,7 +219,7 @@
     public void testMultiAuth_singleSensor_fingerprintSensorStartsAfterDialogAnimationCompletes()
             throws Exception {
         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
-        testMultiAuth_fingerprintSensorStartsAfter(false /* fingerprintStartsAfterDelay */);
+        testMultiAuth_fingerprintSensorStartsAfterUINotifies();
     }
 
     @Test
@@ -227,10 +227,10 @@
             throws Exception {
         setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
         setupFace(1 /* id */, false, mock(IBiometricAuthenticator.class));
-        testMultiAuth_fingerprintSensorStartsAfter(true /* fingerprintStartsAfterDelay */);
+        testMultiAuth_fingerprintSensorStartsAfterUINotifies();
     }
 
-    public void testMultiAuth_fingerprintSensorStartsAfter(boolean fingerprintStartsAfterDelay)
+    public void testMultiAuth_fingerprintSensorStartsAfterUINotifies()
             throws Exception {
         final long operationId = 123;
         final int userId = 10;
@@ -274,12 +274,6 @@
 
         // Notify AuthSession that the UI is shown. Then, fingerprint sensor should be started.
         session.onDialogAnimatedIn();
-        if (fingerprintStartsAfterDelay) {
-            assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
-            assertEquals(BiometricSensor.STATE_COOKIE_RETURNED,
-                    session.mPreAuthInfo.eligibleSensors.get(fingerprintSensorId).getSensorState());
-            session.onStartFingerprint();
-        }
         assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState());
         assertEquals(BiometricSensor.STATE_AUTHENTICATING,
                 session.mPreAuthInfo.eligibleSensors.get(fingerprintSensorId).getSensorState());
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index b94b690..2ad5eae 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.biometrics;
 
+import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
 
@@ -85,14 +86,11 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Random;
-import java.util.concurrent.atomic.AtomicLong;
 
 @Presubmit
 @SmallTest
 public class BiometricServiceTest {
 
-    private static final String TAG = "BiometricServiceTest";
-
     private static final String TEST_PACKAGE_NAME = "test_package";
     private static final long TEST_REQUEST_ID = 44;
 
@@ -153,7 +151,7 @@
                 .thenReturn(mock(BiometricStrengthController.class));
         when(mInjector.getTrustManager()).thenReturn(mTrustManager);
         when(mInjector.getDevicePolicyManager(any())).thenReturn(mDevicePolicyManager);
-        when(mInjector.getRequestGenerator()).thenReturn(new AtomicLong(TEST_REQUEST_ID - 1));
+        when(mInjector.getRequestGenerator()).thenReturn(() -> TEST_REQUEST_ID);
 
         when(mResources.getString(R.string.biometric_error_hw_unavailable))
                 .thenReturn(ERROR_HW_UNAVAILABLE);
@@ -178,22 +176,22 @@
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 true /* requireConfirmation */, null /* authenticators */);
         waitForIdle();
-        verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mCurrentAuthSession),
+        verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mAuthSession),
                 anyInt());
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FACE,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
                 0 /* vendorCode */);
         waitForIdle();
 
-        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
 
-        mBiometricService.mCurrentAuthSession.binderDied();
+        mBiometricService.mAuthSession.binderDied();
         waitForIdle();
 
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
     }
@@ -205,31 +203,31 @@
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 true /* requireConfirmation */, null /* authenticators */);
         waitForIdle();
-        verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mCurrentAuthSession),
+        verify(mReceiver1.asBinder()).linkToDeath(eq(mBiometricService.mAuthSession),
                 anyInt());
 
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
-        mBiometricService.mCurrentAuthSession.binderDied();
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
+        mBiometricService.mAuthSession.binderDied();
         waitForIdle();
 
-        assertNotNull(mBiometricService.mCurrentAuthSession);
+        assertNotNull(mBiometricService.mAuthSession);
         verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
         assertEquals(STATE_CLIENT_DIED_CANCELLING,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
 
-        verify(mBiometricService.mCurrentAuthSession.mPreAuthInfo.eligibleSensors.get(0).impl)
+        verify(mBiometricService.mAuthSession.mPreAuthInfo.eligibleSensors.get(0).impl)
                 .cancelAuthenticationFromService(any(), any(), anyLong());
 
         // Simulate ERROR_CANCELED received from HAL
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FACE,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
                 0 /* vendorCode */);
         waitForIdle();
         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
     }
 
     @Test
@@ -265,12 +263,12 @@
                 Authenticators.DEVICE_CREDENTIAL);
         waitForIdle();
 
-        assertNotNull(mBiometricService.mCurrentAuthSession);
+        assertNotNull(mBiometricService.mAuthSession);
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         // StatusBar showBiometricDialog invoked
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
                 eq(true) /* credentialAllowed */,
@@ -304,21 +302,21 @@
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
         mBiometricService.mImpl.registerAuthenticator(0 /* id */,
-                BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
                 null /* authenticators */);
         waitForIdle();
         verify(mReceiver1).onError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS),
                 eq(0 /* vendorCode */));
     }
 
     @Test
     public void testAuthenticate_notStrongEnough_returnsHardwareNotPresent() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
 
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
                 Authenticators.BIOMETRIC_STRONG);
@@ -335,7 +333,7 @@
         // is able to proceed.
 
         final int[] modalities = new int[] {
-                BiometricAuthenticator.TYPE_FINGERPRINT,
+                TYPE_FINGERPRINT,
                 BiometricAuthenticator.TYPE_FACE,
         };
 
@@ -356,7 +354,7 @@
 
         // StatusBar showBiometricDialog invoked with face, which was set up to be STRONG
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[] {SENSOR_ID_FACE}),
                 eq(false) /* credentialAllowed */,
@@ -377,14 +375,14 @@
         mBiometricService = new BiometricService(mContext, mInjector);
         mBiometricService.onStart();
         mBiometricService.mImpl.registerAuthenticator(0 /* id */,
-                BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
                 null /* authenticators */);
         waitForIdle();
         verify(mReceiver1).onError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE),
                 eq(0 /* vendorCode */));
     }
@@ -415,13 +413,13 @@
         waitForIdle();
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
         final byte[] HAT = generateRandomHAT();
-        mBiometricService.mBiometricSensorReceiver.onAuthenticationSucceeded(
+        mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
                 SENSOR_ID_FACE,
                 HAT);
         waitForIdle();
         // Confirmation is required
         assertEquals(STATE_AUTH_PENDING_CONFIRM,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
 
         // Enrolled, not disabled in settings, user doesn't require confirmation in settings
         resetReceivers();
@@ -431,25 +429,25 @@
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
                 null /* authenticators */);
         waitForIdle();
-        mBiometricService.mBiometricSensorReceiver.onAuthenticationSucceeded(
+        mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
                 SENSOR_ID_FACE,
                 HAT);
         waitForIdle();
         // Confirmation not required, waiting for dialog to dismiss
         assertEquals(STATE_AUTHENTICATED_PENDING_SYSUI,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
 
     }
 
     @Test
     public void testAuthenticate_happyPathWithoutConfirmation_strongBiometric() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         testAuthenticate_happyPathWithoutConfirmation(true /* isStrongBiometric */);
     }
 
     @Test
     public void testAuthenticate_happyPathWithoutConfirmation_weakBiometric() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
         testAuthenticate_happyPathWithoutConfirmation(false /* isStrongBiometric */);
     }
 
@@ -461,7 +459,7 @@
         waitForIdle();
 
         // Creates a pending auth session with the correct initial states
-        assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
 
         // Invokes <Modality>Service#prepareForAuthentication
         ArgumentCaptor<Integer> cookieCaptor = ArgumentCaptor.forClass(Integer.class);
@@ -477,19 +475,19 @@
                 cookieCaptor.capture() /* cookie */,
                 anyBoolean() /* allowBackgroundAuthentication */);
 
-        // onReadyForAuthentication, mCurrentAuthSession state OK
-        mBiometricService.mImpl.onReadyForAuthentication(cookieCaptor.getValue());
+        // onReadyForAuthentication, mAuthSession state OK
+        mBiometricService.mImpl.onReadyForAuthentication(TEST_REQUEST_ID, cookieCaptor.getValue());
         waitForIdle();
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
 
         // startPreparedClient invoked
-        mBiometricService.mCurrentAuthSession.onDialogAnimatedIn();
+        mBiometricService.mAuthSession.onDialogAnimatedIn();
         verify(mBiometricService.mSensors.get(0).impl)
                 .startPreparedClient(cookieCaptor.getValue());
 
         // StatusBar showBiometricDialog invoked
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 any(),
                 eq(false) /* credentialAllowed */,
@@ -502,18 +500,18 @@
 
         // Hardware authenticated
         final byte[] HAT = generateRandomHAT();
-        mBiometricService.mBiometricSensorReceiver.onAuthenticationSucceeded(
+        mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
                 SENSOR_ID_FINGERPRINT,
                 HAT);
         waitForIdle();
         // Waiting for SystemUI to send dismissed callback
         assertEquals(STATE_AUTHENTICATED_PENDING_SYSUI,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         // Notify SystemUI hardware authenticated
-        verify(mBiometricService.mStatusBarService).onBiometricAuthenticated();
+        verify(mBiometricService.mStatusBarService).onBiometricAuthenticated(TYPE_FINGERPRINT);
 
         // SystemUI sends callback with dismissed reason
-        mBiometricService.mSysuiReceiver.onDialogDismissed(
+        mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
                 BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED,
                 null /* credentialAttestation */);
         waitForIdle();
@@ -527,7 +525,7 @@
         verify(mReceiver1).onAuthenticationSucceeded(
                 BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC);
         // Current session becomes null
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
     }
 
     @Test
@@ -542,11 +540,11 @@
         waitForIdle();
 
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         assertEquals(Authenticators.DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.mPromptInfo.getAuthenticators());
+                mBiometricService.mAuthSession.mPromptInfo.getAuthenticators());
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
                 eq(true) /* credentialAllowed */,
@@ -578,16 +576,16 @@
         // Test authentication succeeded goes to PENDING_CONFIRMATION and that the HAT is not
         // sent to KeyStore yet
         final byte[] HAT = generateRandomHAT();
-        mBiometricService.mBiometricSensorReceiver.onAuthenticationSucceeded(
+        mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
                 SENSOR_ID_FACE,
                 HAT);
         waitForIdle();
         // Waiting for SystemUI to send confirmation callback
-        assertEquals(STATE_AUTH_PENDING_CONFIRM, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_PENDING_CONFIRM, mBiometricService.mAuthSession.getState());
         verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
 
         // SystemUI sends confirm, HAT is sent to keystore and client is notified.
-        mBiometricService.mSysuiReceiver.onDialogDismissed(
+        mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
                 BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED,
                 null /* credentialAttestation */);
         waitForIdle();
@@ -624,33 +622,34 @@
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onAuthenticationFailed(SENSOR_ID_FACE);
+        mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationFailed(SENSOR_ID_FACE);
         waitForIdle();
 
         verify(mBiometricService.mStatusBarService).onBiometricError(
-                eq(BiometricAuthenticator.TYPE_NONE),
+                eq(BiometricAuthenticator.TYPE_FACE),
                 eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
                 eq(0 /* vendorCode */));
         verify(mReceiver1).onAuthenticationFailed();
-        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
     }
 
     @Test
     public void testRejectFingerprint_whenAuthenticating_notifiesAndKeepsAuthenticating()
             throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onAuthenticationFailed(SENSOR_ID_FINGERPRINT);
+        mBiometricService.mAuthSession.mSensorReceiver
+                .onAuthenticationFailed(SENSOR_ID_FINGERPRINT);
         waitForIdle();
 
         verify(mBiometricService.mStatusBarService).onBiometricError(
-                eq(BiometricAuthenticator.TYPE_NONE),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_PAUSED_REJECTED),
                 eq(0 /* vendorCode */));
         verify(mReceiver1).onAuthenticationFailed();
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
     }
 
     @Test
@@ -678,14 +677,14 @@
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FACE,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
                 0 /* vendorCode */);
         waitForIdle();
 
-        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
         verify(mBiometricService.mStatusBarService).onBiometricError(
                 eq(BiometricAuthenticator.TYPE_FACE),
                 eq(BiometricConstants.BIOMETRIC_ERROR_TIMEOUT),
@@ -694,15 +693,15 @@
         verify(mReceiver1, never()).onAuthenticationFailed();
 
         // No auth session. Pressing try again will create one.
-        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_PAUSED, mBiometricService.mAuthSession.getState());
 
         // Pressing "Try again" on SystemUI
-        mBiometricService.mSysuiReceiver.onTryAgainPressed();
+        mBiometricService.mAuthSession.mSysuiReceiver.onTryAgainPressed();
         waitForIdle();
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
 
         // AuthSession is now resuming
-        assertEquals(STATE_AUTH_PAUSED_RESUMING, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_PAUSED_RESUMING, mBiometricService.mAuthSession.getState());
 
         // Test resuming when hardware becomes ready. SystemUI should not be requested to
         // show another dialog since it's already showing.
@@ -728,14 +727,14 @@
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FACE,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
                 0 /* vendorCode */);
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FACE,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
                 0 /* vendorCode */);
         waitForIdle();
@@ -748,7 +747,7 @@
         // Dialog is hidden immediately
         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
         // Auth session is over
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
     }
 
     @Test
@@ -757,61 +756,61 @@
         // For errors that show in SystemUI, BiometricService stays in STATE_ERROR_PENDING_SYSUI
         // until SystemUI notifies us that the dialog is dismissed at which point the current
         // session is done.
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FINGERPRINT,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
                 0 /* vendorCode */);
         waitForIdle();
 
         // Sends error to SystemUI and does not notify client yet
-        assertEquals(STATE_ERROR_PENDING_SYSUI, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_ERROR_PENDING_SYSUI, mBiometricService.mAuthSession.getState());
         verify(mBiometricService.mStatusBarService).onBiometricError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
                 eq(0 /* vendorCode */));
         verify(mBiometricService.mStatusBarService, never()).hideAuthenticationDialog();
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
 
         // SystemUI animation completed, client is notified, auth session is over
-        mBiometricService.mSysuiReceiver.onDialogDismissed(
+        mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
                 BiometricPrompt.DISMISSED_REASON_ERROR, null /* credentialAttestation */);
         waitForIdle();
         verify(mReceiver1).onError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
                 eq(0 /* vendorCode */));
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
     }
 
     @Test
     public void testErrorFromHal_whilePreparingAuthentication_credentialAllowed() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */,
                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
         waitForIdle();
 
-        assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
-        mBiometricService.mBiometricSensorReceiver.onError(
+        assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FINGERPRINT,
-                getCookieForPendingSession(mBiometricService.mCurrentAuthSession),
+                getCookieForPendingSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
                 0 /* vendorCode */);
         waitForIdle();
 
         // We should be showing device credential now
-        assertNotNull(mBiometricService.mCurrentAuthSession);
+        assertNotNull(mBiometricService.mAuthSession);
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         assertEquals(Authenticators.DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.mPromptInfo.getAuthenticators());
+                mBiometricService.mAuthSession.mPromptInfo.getAuthenticators());
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
                 eq(true) /* credentialAllowed */,
@@ -826,23 +825,23 @@
     @Test
     public void testErrorFromHal_whilePreparingAuthentication_credentialNotAllowed()
             throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
         waitForIdle();
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FINGERPRINT,
-                getCookieForPendingSession(mBiometricService.mCurrentAuthSession),
+                getCookieForPendingSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
                 0 /* vendorCode */);
         waitForIdle();
 
         // Error is sent to client
-        verify(mReceiver1).onError(eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+        verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_LOCKOUT),
                 eq(0) /* vendorCode */);
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
     }
 
     @Test
@@ -861,7 +860,7 @@
 
     private void testBiometricAuth_whenLockout(@LockoutTracker.LockoutMode int lockoutMode,
             int biometricPromptError) throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
                 .thenReturn(lockoutMode);
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
@@ -869,16 +868,15 @@
         waitForIdle();
 
         // Modality and error are sent
-        verify(mReceiver1).onError(eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+        verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
                 eq(biometricPromptError), eq(0) /* vendorCode */);
     }
 
     @Test
     public void testBiometricOrCredentialAuth_whenBiometricLockout_showsCredential()
             throws Exception {
-        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
-                .thenReturn(true);
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
                 .thenReturn(LockoutTracker.LOCKOUT_PERMANENT);
         invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
@@ -887,13 +885,13 @@
         waitForIdle();
 
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
-        assertNotNull(mBiometricService.mCurrentAuthSession);
+        assertNotNull(mBiometricService.mAuthSession);
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         assertEquals(Authenticators.DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.mPromptInfo.getAuthenticators());
+                mBiometricService.mAuthSession.mPromptInfo.getAuthenticators());
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
                 eq(true) /* credentialAllowed */,
@@ -959,73 +957,73 @@
     @Test
     public void testErrorFromHal_whileShowingDeviceCredential_doesntNotifySystemUI()
             throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */,
                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
 
-        mBiometricService.mSysuiReceiver.onDeviceCredentialPressed();
+        mBiometricService.mAuthSession.mSysuiReceiver.onDeviceCredentialPressed();
         waitForIdle();
 
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FINGERPRINT,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
                 0 /* vendorCode */);
         waitForIdle();
 
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         verify(mReceiver1, never()).onError(anyInt(), anyInt(), anyInt());
     }
 
     @Test
     public void testLockout_whileAuthenticating_credentialAllowed() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */,
                 Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_WEAK);
 
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FINGERPRINT,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
                 0 /* vendorCode */);
         waitForIdle();
 
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         verify(mBiometricService.mStatusBarService).onBiometricError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_LOCKOUT),
                 eq(0 /* vendorCode */));
     }
 
     @Test
     public void testLockout_whenAuthenticating_credentialNotAllowed() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FINGERPRINT,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS,
                 0 /* vendorCode */);
         waitForIdle();
 
         assertEquals(STATE_ERROR_PENDING_SYSUI,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         verify(mBiometricService.mStatusBarService).onBiometricError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_PROCESS),
                 eq(0 /* vendorCode */));
     }
@@ -1033,20 +1031,20 @@
     @Test
     public void testDismissedReasonUserCancel_whileAuthenticating_cancelsHalAuthentication()
             throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mSysuiReceiver.onDialogDismissed(
+        mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
                 BiometricPrompt.DISMISSED_REASON_USER_CANCEL, null /* credentialAttestation */);
         waitForIdle();
         verify(mReceiver1).onError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
                 eq(0 /* vendorCode */));
         verify(mBiometricService.mSensors.get(0).impl).cancelAuthenticationFromService(
                 any(), any(), anyLong());
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
     }
 
     @Test
@@ -1055,12 +1053,12 @@
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FACE,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
                 0 /* vendorCode */);
-        mBiometricService.mSysuiReceiver.onDialogDismissed(
+        mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
                 BiometricPrompt.DISMISSED_REASON_NEGATIVE, null /* credentialAttestation */);
         waitForIdle();
 
@@ -1069,18 +1067,17 @@
     }
 
     @Test
-    public void testDismissedReasonUserCancel_whilePaused_invokesHalCancel() throws
-            Exception {
+    public void testDismissedReasonUserCancel_whilePaused_invokesHalCancel() throws Exception {
         setupAuthForOnly(BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FACE,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
                 0 /* vendorCode */);
-        mBiometricService.mSysuiReceiver.onDialogDismissed(
+        mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
                 BiometricPrompt.DISMISSED_REASON_USER_CANCEL, null /* credentialAttestation */);
         waitForIdle();
 
@@ -1094,10 +1091,10 @@
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 true /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onAuthenticationSucceeded(
+        mBiometricService.mAuthSession.mSensorReceiver.onAuthenticationSucceeded(
                 SENSOR_ID_FACE,
                 new byte[69] /* HAT */);
-        mBiometricService.mSysuiReceiver.onDialogDismissed(
+        mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
                 BiometricPrompt.DISMISSED_REASON_USER_CANCEL, null /* credentialAttestation */);
         waitForIdle();
 
@@ -1108,19 +1105,19 @@
                 eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
                 eq(0 /* vendorCode */));
         verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
-        assertNull(mBiometricService.mCurrentAuthSession);
+        assertNull(mBiometricService.mAuthSession);
     }
 
     @Test
     public void testAcquire_whenAuthenticating_sentToSystemUI() throws Exception {
         when(mContext.getResources().getString(anyInt())).thenReturn("test string");
 
-        final int modality = BiometricAuthenticator.TYPE_FINGERPRINT;
+        final int modality = TYPE_FINGERPRINT;
         setupAuthForOnly(modality, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mBiometricSensorReceiver.onAcquired(
+        mBiometricService.mAuthSession.mSensorReceiver.onAcquired(
                 SENSOR_ID_FINGERPRINT,
                 FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY,
                 0 /* vendorCode */);
@@ -1130,29 +1127,29 @@
         // string is retrieved for now, but it's also very unlikely to break anyway.
         verify(mBiometricService.mStatusBarService)
                 .onBiometricHelp(eq(modality), anyString());
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
     }
 
     @Test
     public void testCancel_whenAuthenticating() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, null /* authenticators */);
 
-        mBiometricService.mImpl.cancelAuthentication(mBiometricService.mCurrentAuthSession.mToken,
+        mBiometricService.mImpl.cancelAuthentication(mBiometricService.mAuthSession.mToken,
                 TEST_PACKAGE_NAME, TEST_REQUEST_ID);
         waitForIdle();
 
         // Pretend that the HAL has responded to cancel with ERROR_CANCELED
-        mBiometricService.mBiometricSensorReceiver.onError(
+        mBiometricService.mAuthSession.mSensorReceiver.onError(
                 SENSOR_ID_FINGERPRINT,
-                getCookieForCurrentSession(mBiometricService.mCurrentAuthSession),
+                getCookieForCurrentSession(mBiometricService.mAuthSession),
                 BiometricConstants.BIOMETRIC_ERROR_CANCELED,
                 0 /* vendorCode */);
         waitForIdle();
 
         // Hides system dialog and invokes the onError callback
-        verify(mReceiver1).onError(eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+        verify(mReceiver1).onError(eq(TYPE_FINGERPRINT),
                 eq(BiometricConstants.BIOMETRIC_ERROR_CANCELED),
                 eq(0 /* vendorCode */));
         verify(mBiometricService.mStatusBarService).hideAuthenticationDialog();
@@ -1161,7 +1158,7 @@
     @Test
     public void testCanAuthenticate_whenDeviceHasRequestedBiometricStrength() throws Exception {
         // When only biometric is requested, and sensor is strong enough
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
 
         assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
                 invokeCanAuthenticate(mBiometricService, Authenticators.BIOMETRIC_STRONG));
@@ -1170,7 +1167,7 @@
     @Test
     public void testCanAuthenticate_whenDeviceDoesNotHaveRequestedBiometricStrength()
             throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_WEAK);
 
         // When only biometric is requested, and sensor is not strong enough
         when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
@@ -1208,9 +1205,8 @@
     @Test
     public void testCanAuthenticate_whenNoBiometricsEnrolled() throws Exception {
         // With credential set up, test the following.
-        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
-                .thenReturn(true);
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
+        when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 false /* enrolled */);
 
         // When only biometric is requested
@@ -1277,7 +1273,7 @@
     private void testCanAuthenticate_whenLockedOut(@LockoutTracker.LockoutMode int lockoutMode)
             throws Exception {
         // When only biometric is requested, and sensor is strong enough
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
 
         when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt()))
                 .thenReturn(lockoutMode);
@@ -1311,7 +1307,7 @@
         for (int i = 0; i < testCases.length; i++) {
             final BiometricSensor sensor =
                     new BiometricSensor(mContext, 0 /* id */,
-                            BiometricAuthenticator.TYPE_FINGERPRINT,
+                            TYPE_FINGERPRINT,
                             testCases[i][0],
                             mock(IBiometricAuthenticator.class)) {
                         @Override
@@ -1341,7 +1337,7 @@
                 .thenReturn(true);
         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
         mBiometricService.mImpl.registerAuthenticator(0 /* testId */,
-                BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         verify(mBiometricService.mBiometricStrengthController).updateStrengths();
@@ -1360,7 +1356,7 @@
                 .thenReturn(true);
         when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
         mBiometricService.mImpl.registerAuthenticator(testId /* id */,
-                BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
+                TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
                 mFingerprintAuthenticator);
 
         // Downgrade the authenticator
@@ -1378,7 +1374,7 @@
                 false /* requireConfirmation */, authenticators);
         waitForIdle();
         verify(mReceiver1).onError(
-                eq(BiometricAuthenticator.TYPE_FINGERPRINT),
+                eq(TYPE_FINGERPRINT),
                 eq(BiometricPrompt.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED),
                 eq(0) /* vendorCode */);
 
@@ -1392,7 +1388,7 @@
                 authenticators);
         waitForIdle();
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[] {testId}),
                 eq(false) /* credentialAllowed */,
@@ -1414,9 +1410,9 @@
                 false /* requireConfirmation */,
                 authenticators);
         waitForIdle();
-        assertTrue(Utils.isCredentialRequested(mBiometricService.mCurrentAuthSession.mPromptInfo));
+        assertTrue(Utils.isCredentialRequested(mBiometricService.mAuthSession.mPromptInfo));
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[0]) /* sensorIds */,
                 eq(true) /* credentialAllowed */,
@@ -1442,7 +1438,7 @@
                 false /* requireConfirmation */, authenticators);
         waitForIdle();
         verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
-                eq(mBiometricService.mCurrentAuthSession.mPromptInfo),
+                eq(mBiometricService.mAuthSession.mPromptInfo),
                 any(IBiometricSysuiReceiver.class),
                 AdditionalMatchers.aryEq(new int[] {testId}) /* sensorIds */,
                 eq(false) /* credentialAllowed */,
@@ -1495,29 +1491,29 @@
     @Test
     public void testWorkAuthentication_fingerprintWorksIfNotDisabledByDevicePolicyManager()
             throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         when(mDevicePolicyManager
                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
                 .thenReturn(~DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
         invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
                 Authenticators.BIOMETRIC_STRONG);
         waitForIdle();
-        assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
         startPendingAuthSession(mBiometricService);
         waitForIdle();
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
     }
 
     @Test
     public void testAuthentication_normalAppIgnoresDevicePolicy() throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
         when(mDevicePolicyManager
                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
         invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
                 false /* requireConfirmation */, Authenticators.BIOMETRIC_STRONG);
         waitForIdle();
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
     }
 
     @Test
@@ -1530,18 +1526,17 @@
         invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver1,
                 Authenticators.BIOMETRIC_STRONG);
         waitForIdle();
-        assertEquals(STATE_AUTH_CALLED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_CALLED, mBiometricService.mAuthSession.getState());
         startPendingAuthSession(mBiometricService);
         waitForIdle();
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
     }
 
     @Test
     public void testWorkAuthentication_fingerprintFailsIfDisabledByDevicePolicyManager()
             throws Exception {
-        setupAuthForOnly(BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
-        when(mTrustManager.isDeviceSecure(anyInt(), anyInt()))
-                .thenReturn(true);
+        setupAuthForOnly(TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG);
+        when(mTrustManager.isDeviceSecure(anyInt(), anyInt())).thenReturn(true);
         when(mDevicePolicyManager
                 .getKeyguardDisabledFeatures(any() /* admin */, anyInt() /* userHandle */))
                 .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT);
@@ -1555,9 +1550,9 @@
         invokeAuthenticateForWorkApp(mBiometricService.mImpl, mReceiver2,
                 Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL);
         waitForIdle();
-        assertNotNull(mBiometricService.mCurrentAuthSession);
+        assertNotNull(mBiometricService.mAuthSession);
         assertEquals(STATE_SHOWING_DEVICE_CREDENTIAL,
-                mBiometricService.mCurrentAuthSession.getState());
+                mBiometricService.mAuthSession.getState());
         verify(mReceiver2, never()).onError(anyInt(), anyInt(), anyInt());
     }
 
@@ -1580,7 +1575,7 @@
 
         when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true);
 
-        if ((modality & BiometricAuthenticator.TYPE_FINGERPRINT) != 0) {
+        if ((modality & TYPE_FINGERPRINT) != 0) {
             when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
                     .thenReturn(enrolled);
             when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
@@ -1614,7 +1609,7 @@
             final int modality = modalities[i];
             final int strength = strengths[i];
 
-            if ((modality & BiometricAuthenticator.TYPE_FINGERPRINT) != 0) {
+            if ((modality & TYPE_FINGERPRINT) != 0) {
                 when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any()))
                         .thenReturn(true);
                 when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true);
@@ -1654,8 +1649,9 @@
         startPendingAuthSession(mBiometricService);
         waitForIdle();
 
-        assertNotNull(mBiometricService.mCurrentAuthSession);
-        assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
+        assertNotNull(mBiometricService.mAuthSession);
+        assertEquals(TEST_REQUEST_ID, mBiometricService.mAuthSession.getRequestId());
+        assertEquals(STATE_AUTH_STARTED, mBiometricService.mAuthSession.getState());
 
         return requestId;
     }
@@ -1663,14 +1659,14 @@
     private static void startPendingAuthSession(BiometricService service) throws Exception {
         // Get the cookie so we can pretend the hardware is ready to authenticate
         // Currently we only support single modality per auth
-        final PreAuthInfo preAuthInfo = service.mCurrentAuthSession.mPreAuthInfo;
+        final PreAuthInfo preAuthInfo = service.mAuthSession.mPreAuthInfo;
         assertEquals(preAuthInfo.eligibleSensors.size(), 1);
         assertEquals(preAuthInfo.numSensorsWaitingForCookie(), 1);
 
         final int cookie = preAuthInfo.eligibleSensors.get(0).getCookie();
         assertNotEquals(cookie, 0);
 
-        service.mImpl.onReadyForAuthentication(cookie);
+        service.mImpl.onReadyForAuthentication(TEST_REQUEST_ID, cookie);
     }
 
     private static long invokeAuthenticate(IBiometricService.Stub service,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
index 64be569..eab96c0 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java
@@ -40,12 +40,14 @@
 import com.android.server.biometrics.log.BiometricLogger;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
 @Presubmit
 @RunWith(AndroidTestingRunner.class)
@@ -62,6 +64,9 @@
         }
     }
 
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
     @Mock
     private InterruptableMonitor<FakeHal> mClientMonitor;
     @Mock
@@ -76,7 +81,6 @@
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
         mHandler = new Handler(TestableLooper.get(this).getLooper());
         mOperation = new BiometricSchedulerOperation(mClientMonitor, mClientCallback);
     }
@@ -311,10 +315,12 @@
     private void cancelWatchdog(boolean start) {
         when(mClientMonitor.getFreshDaemon()).thenReturn(mHal);
 
-        mOperation.start(mock(ClientMonitorCallback.class));
+        final ClientMonitorCallback opStartCallback = mock(ClientMonitorCallback.class);
+        mOperation.start(opStartCallback);
         if (start) {
             verify(mClientMonitor).start(mStartCallback.capture());
             mStartCallback.getValue().onClientStarted(mClientMonitor);
+            verify(opStartCallback).onClientStarted(eq(mClientMonitor));
         }
         mOperation.cancel(mHandler, mock(ClientMonitorCallback.class));
 
@@ -325,6 +331,7 @@
 
         assertThat(mOperation.isFinished()).isTrue();
         assertThat(mOperation.isCanceling()).isFalse();
+        verify(opStartCallback).onClientFinished(eq(mClientMonitor), eq(false));
         verify(mClientMonitor).destroy();
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
index bfb0be7..f40b31a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
@@ -29,12 +29,8 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.withSettings;
 
-import android.content.Context;
 import android.hardware.biometrics.BiometricConstants;
-import android.os.Handler;
-import android.os.Looper;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
@@ -43,9 +39,11 @@
 import com.android.server.biometrics.sensors.fingerprint.Udfps;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
 import java.util.LinkedList;
 
@@ -53,39 +51,38 @@
 @SmallTest
 public class CoexCoordinatorTest {
 
-    private static final String TAG = "CoexCoordinatorTest";
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
 
-    private CoexCoordinator mCoexCoordinator;
-    private Handler mHandler;
-
-    @Mock
-    private Context mContext;
     @Mock
     private CoexCoordinator.Callback mCallback;
     @Mock
     private CoexCoordinator.ErrorCallback mErrorCallback;
+    @Mock
+    private AuthenticationClient mFaceClient;
+    @Mock
+    private AuthenticationClient mFingerprintClient;
+    @Mock(extraInterfaces = {Udfps.class})
+    private AuthenticationClient mUdfpsClient;
+
+    private CoexCoordinator mCoexCoordinator;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mHandler = new Handler(Looper.getMainLooper());
-
         mCoexCoordinator = CoexCoordinator.getInstance();
         mCoexCoordinator.setAdvancedLogicEnabled(true);
         mCoexCoordinator.setFaceHapticDisabledWhenNonBypass(true);
+        mCoexCoordinator.reset();
     }
 
     @Test
     public void testBiometricPrompt_authSuccess() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
 
-        AuthenticationClient<?> client = mock(AuthenticationClient.class);
-        when(client.isBiometricPrompt()).thenReturn(true);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
 
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, client, mCallback);
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
+                mFaceClient, mCallback);
         verify(mCallback).sendHapticFeedback();
         verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
         verify(mCallback).handleLifecycleAfterAuth();
@@ -93,15 +90,12 @@
 
     @Test
     public void testBiometricPrompt_authReject_whenNotLockedOut() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
 
-        AuthenticationClient<?> client = mock(AuthenticationClient.class);
-        when(client.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
 
         mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                client, LockoutTracker.LOCKOUT_NONE, mCallback);
+                mFaceClient, LockoutTracker.LOCKOUT_NONE, mCallback);
         verify(mCallback).sendHapticFeedback();
         verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
         verify(mCallback).handleLifecycleAfterAuth();
@@ -109,30 +103,97 @@
 
     @Test
     public void testBiometricPrompt_authReject_whenLockedOut() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
 
-        AuthenticationClient<?> client = mock(AuthenticationClient.class);
-        when(client.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
 
         mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
-                client, LockoutTracker.LOCKOUT_TIMED, mCallback);
+                mFaceClient, LockoutTracker.LOCKOUT_TIMED, mCallback);
         verify(mCallback).sendHapticFeedback();
         verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
         verify(mCallback).handleLifecycleAfterAuth();
     }
 
     @Test
+    public void testBiometricPrompt_coex_success() {
+        testBiometricPrompt_coex_success(false /* twice */);
+    }
+
+    @Test
+    public void testBiometricPrompt_coex_successWithoutDouble() {
+        testBiometricPrompt_coex_success(true /* twice */);
+    }
+
+    private void testBiometricPrompt_coex_success(boolean twice) {
+        initFaceAndFingerprintForBiometricPrompt();
+        when(mFaceClient.wasAuthSuccessful()).thenReturn(true);
+        when(mUdfpsClient.wasAuthSuccessful()).thenReturn(twice, true);
+
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
+
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
+                mFaceClient, mCallback);
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
+                mUdfpsClient, mCallback);
+
+        if (twice) {
+            verify(mCallback, never()).sendHapticFeedback();
+        } else {
+            verify(mCallback).sendHapticFeedback();
+        }
+    }
+
+    @Test
+    public void testBiometricPrompt_coex_reject() {
+        initFaceAndFingerprintForBiometricPrompt();
+
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
+
+        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
+                mFaceClient, LockoutTracker.LOCKOUT_NONE, mCallback);
+
+        verify(mCallback, never()).sendHapticFeedback();
+
+        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
+                    mUdfpsClient, LockoutTracker.LOCKOUT_NONE, mCallback);
+
+        verify(mCallback).sendHapticFeedback();
+    }
+
+    @Test
+    public void testBiometricPrompt_coex_errorNoHaptics() {
+        initFaceAndFingerprintForBiometricPrompt();
+
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
+
+        mCoexCoordinator.onAuthenticationError(mFaceClient,
+                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
+        mCoexCoordinator.onAuthenticationError(mUdfpsClient,
+                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
+
+        verify(mErrorCallback, never()).sendHapticFeedback();
+    }
+
+    private void initFaceAndFingerprintForBiometricPrompt() {
+        when(mFaceClient.isKeyguard()).thenReturn(false);
+        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
+        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
+        when(mUdfpsClient.isKeyguard()).thenReturn(false);
+        when(mUdfpsClient.isBiometricPrompt()).thenReturn(true);
+        when(mUdfpsClient.wasAuthAttempted()).thenReturn(true);
+    }
+
+    @Test
     public void testKeyguard_faceAuthOnly_success() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
 
-        AuthenticationClient<?> client = mock(AuthenticationClient.class);
-        when(client.isKeyguard()).thenReturn(true);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
 
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, client, mCallback);
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
+                mFaceClient, mCallback);
         verify(mCallback).sendHapticFeedback();
         verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
         verify(mCallback).handleLifecycleAfterAuth();
@@ -140,21 +201,16 @@
 
     @Test
     public void testKeyguard_faceAuth_udfpsNotTouching_faceSuccess() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
+        when(mUdfpsClient.isKeyguard()).thenReturn(true);
+        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
 
-        AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
-                withSettings().extraInterfaces(Udfps.class));
-        when(udfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) udfpsClient).isPointerDown()).thenReturn(false);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
 
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, faceClient,
-                mCallback);
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
+                mFaceClient, mCallback);
         // Haptics tested in #testKeyguard_bypass_haptics. Let's leave this commented out (instead
         // of removed) to keep this context.
         // verify(mCallback).sendHapticFeedback();
@@ -192,25 +248,19 @@
 
     private void testKeyguard_bypass_haptics(boolean bypassEnabled, boolean faceAccepted,
             boolean shouldReceiveHaptics) {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
+        when(mUdfpsClient.isKeyguard()).thenReturn(true);
+        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-        when(faceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
-
-        AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
-                withSettings().extraInterfaces(Udfps.class));
-        when(udfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) udfpsClient).isPointerDown()).thenReturn(false);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
 
         if (faceAccepted) {
-            mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, faceClient,
+            mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mFaceClient,
                     mCallback);
         } else {
-            mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, faceClient,
+            mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
                     LockoutTracker.LOCKOUT_NONE, mCallback);
         }
 
@@ -244,24 +294,18 @@
 
     private void testKeyguard_faceAuth_udfpsTouching_faceSuccess(boolean thenUdfpsAccepted,
             long udfpsRejectedAfterMs) {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mUdfpsClient.isKeyguard()).thenReturn(true);
+        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
+        when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-
-        AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
-                withSettings().extraInterfaces(Udfps.class));
-        when(udfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) udfpsClient).isPointerDown()).thenReturn(true);
-        when (udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
 
         // For easier reading
         final CoexCoordinator.Callback faceCallback = mCallback;
 
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, faceClient,
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mFaceClient,
                 faceCallback);
         verify(faceCallback, never()).sendHapticFeedback();
         verify(faceCallback, never()).sendAuthenticationResult(anyBoolean());
@@ -272,9 +316,9 @@
         // Reset the mock
         CoexCoordinator.Callback udfpsCallback = mock(CoexCoordinator.Callback.class);
         assertEquals(1, mCoexCoordinator.mSuccessfulAuths.size());
-        assertEquals(faceClient, mCoexCoordinator.mSuccessfulAuths.get(0).mAuthenticationClient);
+        assertEquals(mFaceClient, mCoexCoordinator.mSuccessfulAuths.get(0).mAuthenticationClient);
         if (thenUdfpsAccepted) {
-            mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, udfpsClient,
+            mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mUdfpsClient,
                     udfpsCallback);
             verify(udfpsCallback).sendHapticFeedback();
             verify(udfpsCallback).sendAuthenticationResult(true /* addAuthTokenIfStrong */);
@@ -284,7 +328,7 @@
 
             assertTrue(mCoexCoordinator.mSuccessfulAuths.isEmpty());
         } else {
-            mCoexCoordinator.onAuthenticationRejected(udfpsRejectedAfterMs, udfpsClient,
+            mCoexCoordinator.onAuthenticationRejected(udfpsRejectedAfterMs, mUdfpsClient,
                     LockoutTracker.LOCKOUT_NONE, udfpsCallback);
             if (udfpsRejectedAfterMs <= CoexCoordinator.SUCCESSFUL_AUTH_VALID_DURATION_MS) {
                 verify(udfpsCallback, never()).sendHapticFeedback();
@@ -310,56 +354,44 @@
 
     @Test
     public void testKeyguard_udfpsAuthSuccess_whileFaceScanning() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mUdfpsClient.isKeyguard()).thenReturn(true);
+        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-        when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
 
-        AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
-                withSettings().extraInterfaces(Udfps.class));
-        when(udfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) udfpsClient).isPointerDown()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, udfpsClient,
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mUdfpsClient,
                 mCallback);
         verify(mCallback).sendHapticFeedback();
         verify(mCallback).sendAuthenticationResult(eq(true));
-        verify(faceClient).cancel();
+        verify(mFaceClient).cancel();
         verify(mCallback).handleLifecycleAfterAuth();
     }
 
     @Test
     public void testKeyguard_faceRejectedWhenUdfpsTouching_thenUdfpsRejected() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mUdfpsClient.isKeyguard()).thenReturn(true);
+        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-        when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
 
-        AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
-                withSettings().extraInterfaces(Udfps.class));
-        when(udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(udfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) udfpsClient).isPointerDown()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, faceClient,
+        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
                 LockoutTracker.LOCKOUT_NONE, mCallback);
         verify(mCallback, never()).sendHapticFeedback();
         verify(mCallback).handleLifecycleAfterAuth();
 
         // BiometricScheduler removes the face authentication client after rejection
-        mCoexCoordinator.removeAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
+        mCoexCoordinator.removeAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
 
         // Then UDFPS rejected
         CoexCoordinator.Callback udfpsCallback = mock(CoexCoordinator.Callback.class);
-        mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, udfpsClient,
+        mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, mUdfpsClient,
                 LockoutTracker.LOCKOUT_NONE, udfpsCallback);
         verify(udfpsCallback).sendHapticFeedback();
         verify(udfpsCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
@@ -368,26 +400,20 @@
 
     @Test
     public void testKeyguard_udfpsRejected_thenFaceRejected_noKeyguardBypass() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(false); // TODO: also test "true" case
+        when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mUdfpsClient.isKeyguard()).thenReturn(true);
+        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-        when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(faceClient.isKeyguardBypassEnabled()).thenReturn(false); // TODO: also test "true" case
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
 
-        AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
-                withSettings().extraInterfaces(Udfps.class));
-        when(udfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(udfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) udfpsClient).isPointerDown()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, udfpsClient,
-                LockoutTracker.LOCKOUT_NONE, mCallback);
+        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
+                mUdfpsClient, LockoutTracker.LOCKOUT_NONE, mCallback);
         // Auth was attempted
-        when(udfpsClient.getState())
+        when(mUdfpsClient.getState())
                 .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED);
         verify(mCallback, never()).sendHapticFeedback();
         verify(mCallback).handleLifecycleAfterAuth();
@@ -395,7 +421,7 @@
         // Then face rejected. Note that scheduler leaves UDFPS in the CoexCoordinator since
         // unlike face, its lifecycle becomes "paused" instead of "finished".
         CoexCoordinator.Callback faceCallback = mock(CoexCoordinator.Callback.class);
-        mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, faceClient,
+        mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, mFaceClient,
                 LockoutTracker.LOCKOUT_NONE, faceCallback);
         verify(faceCallback).sendHapticFeedback();
         verify(faceCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
@@ -404,20 +430,16 @@
 
     @Test
     public void testKeyguard_capacitiveAccepted_whenFaceScanning() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mFingerprintClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mFingerprintClient.isKeyguard()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-        when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, mFingerprintClient);
 
-        AuthenticationClient<?> fpClient = mock(AuthenticationClient.class);
-        when(fpClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(fpClient.isKeyguard()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, fpClient);
-
-        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, fpClient, mCallback);
+        mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
+                mFingerprintClient, mCallback);
         verify(mCallback).sendHapticFeedback();
         verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
         verify(mCallback).handleLifecycleAfterAuth();
@@ -425,21 +447,16 @@
 
     @Test
     public void testKeyguard_capacitiveRejected_whenFaceScanning() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mFingerprintClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        when(mFingerprintClient.isKeyguard()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-        when(faceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, mFingerprintClient);
 
-        AuthenticationClient<?> fpClient = mock(AuthenticationClient.class);
-        when(fpClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-        when(fpClient.isKeyguard()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, fpClient);
-
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, fpClient,
-                LockoutTracker.LOCKOUT_NONE, mCallback);
+        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
+                mFingerprintClient, LockoutTracker.LOCKOUT_NONE, mCallback);
         verify(mCallback).sendHapticFeedback();
         verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
         verify(mCallback).handleLifecycleAfterAuth();
@@ -447,14 +464,11 @@
 
     @Test
     public void testNonKeyguard_rejectAndNotLockedOut() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(false);
+        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(false);
-        when(faceClient.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, faceClient,
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
                 LockoutTracker.LOCKOUT_NONE, mCallback);
 
         verify(mCallback).sendHapticFeedback();
@@ -464,14 +478,11 @@
 
     @Test
     public void testNonKeyguard_rejectLockedOut() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(false);
+        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(false);
-        when(faceClient.isBiometricPrompt()).thenReturn(true);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, faceClient,
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
                 LockoutTracker.LOCKOUT_TIMED, mCallback);
 
         verify(mCallback).sendHapticFeedback();
@@ -496,16 +507,13 @@
 
     @Test
     public void testBiometricPrompt_FaceError() {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isBiometricPrompt()).thenReturn(true);
+        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
 
-        AuthenticationClient<?> client = mock(AuthenticationClient.class);
-        when(client.isBiometricPrompt()).thenReturn(true);
-        when(client.wasAuthAttempted()).thenReturn(true);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
 
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
-
-        mCoexCoordinator.onAuthenticationError(client, BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
-                mErrorCallback);
+        mCoexCoordinator.onAuthenticationError(mFaceClient,
+                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
         verify(mErrorCallback).sendHapticFeedback();
     }
 
@@ -520,18 +528,15 @@
     }
 
     private void testKeyguard_faceAuthOnly(boolean bypassEnabled) {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
+        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
+        when(mFaceClient.wasUserDetected()).thenReturn(true);
 
-        AuthenticationClient<?> client = mock(AuthenticationClient.class);
-        when(client.isKeyguard()).thenReturn(true);
-        when(client.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
-        when(client.wasAuthAttempted()).thenReturn(true);
-        when(client.wasUserDetected()).thenReturn(true);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
 
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, client);
-
-        mCoexCoordinator.onAuthenticationError(client, BiometricConstants.BIOMETRIC_ERROR_TIMEOUT,
-                mErrorCallback);
+        mCoexCoordinator.onAuthenticationError(mFaceClient,
+                BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
         verify(mErrorCallback).sendHapticFeedback();
     }
 
@@ -546,23 +551,17 @@
     }
 
     private void testKeyguard_coex_faceError(boolean bypassEnabled) {
-        mCoexCoordinator.reset();
+        when(mFaceClient.isKeyguard()).thenReturn(true);
+        when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
+        when(mFaceClient.wasAuthAttempted()).thenReturn(true);
+        when(mFaceClient.wasUserDetected()).thenReturn(true);
+        when(mUdfpsClient.isKeyguard()).thenReturn(true);
+        when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
 
-        AuthenticationClient<?> faceClient = mock(AuthenticationClient.class);
-        when(faceClient.isKeyguard()).thenReturn(true);
-        when(faceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
-        when(faceClient.wasAuthAttempted()).thenReturn(true);
-        when(faceClient.wasUserDetected()).thenReturn(true);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
+        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
 
-        AuthenticationClient<?> udfpsClient = mock(AuthenticationClient.class,
-                withSettings().extraInterfaces(Udfps.class));
-        when(udfpsClient.isKeyguard()).thenReturn(true);
-        when(((Udfps) udfpsClient).isPointerDown()).thenReturn(false);
-
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, faceClient);
-        mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, udfpsClient);
-
-        mCoexCoordinator.onAuthenticationError(faceClient,
+        mCoexCoordinator.onAuthenticationError(mFaceClient,
                 BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
 
         if (bypassEnabled) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClientTest.java
new file mode 100644
index 0000000..76a5acc
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClientTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.face.aidl;
+
+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.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.biometrics.BiometricAuthenticator;
+import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.face.ISession;
+import android.hardware.face.Face;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricLogger;
+import com.android.server.biometrics.sensors.BiometricUtils;
+import com.android.server.biometrics.sensors.ClientMonitorCallback;
+import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Presubmit
+@SmallTest
+public class FaceRemovalClientTest {
+
+    private static final int USER_ID = 12;
+
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
+    @Mock
+    private ISession mHal;
+    @Mock
+    private IBinder mToken;
+    @Mock
+    private ClientMonitorCallbackConverter mClientMonitorCallbackConverter;
+    @Mock
+    private BiometricLogger mBiometricLogger;
+    @Mock
+    private BiometricContext mBiometricContext;
+    @Mock
+    private ClientMonitorCallback mCallback;
+    @Mock
+    private Sensor.HalSessionCallback mHalSessionCallback;
+    @Mock
+    private BiometricUtils<Face> mUtils;
+    @Mock
+    private BiometricAuthenticator.Identifier mIdentifier;
+    private Map<Integer, Long> mAuthenticatorIds = new HashMap<Integer, Long>();
+
+    @Before
+    public void setup() {
+        when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
+                i -> i.getArgument(0));
+    }
+
+    @Test
+    public void testFaceRemovalClient() throws RemoteException {
+        final int authenticatorId = 1;
+        int[] authenticatorIds = new int[]{authenticatorId};
+        final FaceRemovalClient client = createClient(1, authenticatorIds);
+        when(mIdentifier.getBiometricId()).thenReturn(authenticatorId);
+        client.start(mCallback);
+        verify(mHal).removeEnrollments(authenticatorIds);
+        client.onRemoved(mIdentifier, 0 /* remaining */);
+        verify(mClientMonitorCallbackConverter).onRemoved(
+                eq(mIdentifier) /* identifier */, eq(0) /* remaining */);
+        verify(mCallback).onClientFinished(client, true);
+    }
+
+    @Test
+    public void clientSendsErrorWhenHALFailsToRemoveEnrollment() throws RemoteException {
+        final FaceRemovalClient client = createClient(1, new int[0]);
+        client.start(mCallback);
+        client.onRemoved(null, 0 /* remaining */);
+        verify(mClientMonitorCallbackConverter).onError(eq(5) /* sensorId */, anyInt(),
+                eq(BiometricConstants.BIOMETRIC_ERROR_UNABLE_TO_REMOVE), eq(0) /* vendorCode*/);
+        verify(mCallback).onClientFinished(client, false);
+    }
+
+    private FaceRemovalClient createClient(int version, int[] biometricIds) throws RemoteException {
+        when(mHal.getInterfaceVersion()).thenReturn(version);
+        final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
+        return new FaceRemovalClient(mContext, () -> aidl, mToken,
+                mClientMonitorCallbackConverter, biometricIds, USER_ID,
+                "own-it", mUtils /* utils */, 5 /* sensorId */, mBiometricLogger, mBiometricContext,
+                mAuthenticatorIds);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 9aac81c..7b921ab 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -58,6 +58,7 @@
 import android.os.IPowerManager;
 import android.os.IThermalService;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.WorkSource;
 import android.platform.test.annotations.Presubmit;
@@ -136,6 +137,7 @@
         LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock);
 
         mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+        doReturn(mContext).when(mContext).createContextAsUser(eq(Process.myUserHandle()), anyInt());
         doNothing().when(mContext).enforceCallingOrSelfPermission(
                 eq(Manifest.permission.CREATE_VIRTUAL_DEVICE), anyString());
         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
index 3160272..f0c907d 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
+import android.companion.virtual.VirtualDeviceParams;
 import android.companion.virtual.audio.IAudioSessionCallback;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -72,7 +73,8 @@
                 /* allowedUsers= */ new ArraySet<>(),
                 /* allowedActivities= */ new ArraySet<>(),
                 /* blockedActivities= */ new ArraySet<>(),
-                /* activityListener= */null,
+                VirtualDeviceParams.ACTIVITY_POLICY_DEFAULT_ALLOWED,
+                /* activityListener= */ null,
                 /* activityBlockedCallback= */ null);
     }
 
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 2398e36..1ebcbe1 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -1137,9 +1137,6 @@
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
 
         // Verify internal calls.
-        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
-                eq(admin1.getPackageName()));
-
         verify(getServices().userManager, times(1)).setUserRestriction(
                 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                 eq(true), eq(UserHandle.SYSTEM));
@@ -1205,9 +1202,6 @@
         assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
 
         // Verify internal calls.
-        verify(getServices().iactivityManager).updateDeviceOwner(
-                eq(admin1.getPackageName()));
-
         verify(mContext.spiedContext).sendBroadcastAsUser(
                 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
                 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
@@ -1392,11 +1386,6 @@
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
         assertThat(dpm.setDeviceOwner(admin1, "owner-name", UserHandle.USER_SYSTEM)).isTrue();
-
-        // Verify internal calls.
-        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
-                eq(admin1.getPackageName()));
-
         assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
 
         dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
@@ -1501,11 +1490,6 @@
         setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
         dpm.setActiveAdmin(admin1, /* replace =*/ false);
         assertThat(dpm.setDeviceOwner(admin1, "owner-name", UserHandle.USER_SYSTEM)).isTrue();
-
-        // Verify internal calls.
-        verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
-                eq(admin1.getPackageName()));
-
         assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1);
 
         // Now call clear from the secondary user, which should throw.
@@ -4173,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
@@ -4214,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()
@@ -4243,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()
@@ -4273,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);
@@ -4308,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/devicepolicy/OverlayPackagesProviderTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
index 533fb2d..4f6fc3d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/OverlayPackagesProviderTest.java
@@ -309,7 +309,7 @@
 
     @Test
     public void testGetNonRequiredApps_managedProfile_roleHolder_works() {
-        when(mInjector.getDeviceManagerRoleHolderPackageName(any()))
+        when(mInjector.getDevicePolicyManagementRoleHolderPackageName(any()))
                 .thenReturn(ROLE_HOLDER_PACKAGE_NAME);
         setSystemAppsWithLauncher("package1", "package2", ROLE_HOLDER_PACKAGE_NAME);
 
@@ -319,7 +319,7 @@
 
     @Test
     public void testGetNonRequiredApps_managedDevice_roleHolder_works() {
-        when(mInjector.getDeviceManagerRoleHolderPackageName(any()))
+        when(mInjector.getDevicePolicyManagementRoleHolderPackageName(any()))
                 .thenReturn(ROLE_HOLDER_PACKAGE_NAME);
         setSystemAppsWithLauncher("package1", "package2", ROLE_HOLDER_PACKAGE_NAME);
 
diff --git a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
index fefc425..86b6da0 100644
--- a/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -28,7 +28,9 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.verify;
@@ -70,6 +72,8 @@
 @RunWith(AndroidJUnit4.class)
 public class LogicalDisplayMapperTest {
     private static int sUniqueTestDisplayId = 0;
+    private static final int DEVICE_STATE_CLOSED = 0;
+    private static final int DEVICE_STATE_OPEN = 2;
 
     private DisplayDeviceRepository mDisplayDeviceRepo;
     private LogicalDisplayMapper mLogicalDisplayMapper;
@@ -113,6 +117,7 @@
 
         mPowerManager = new PowerManager(mContextMock, mIPowerManagerMock, mIThermalServiceMock,
                 null);
+
         when(mContextMock.getSystemServiceName(PowerManager.class))
                 .thenReturn(Context.POWER_SERVICE);
         when(mContextMock.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
@@ -120,6 +125,12 @@
         when(mResourcesMock.getBoolean(
                 com.android.internal.R.bool.config_supportsConcurrentInternalDisplays))
                 .thenReturn(true);
+        when(mResourcesMock.getIntArray(
+                com.android.internal.R.array.config_deviceStatesOnWhichToWakeUp))
+                .thenReturn(new int[]{1, 2});
+        when(mResourcesMock.getIntArray(
+                com.android.internal.R.array.config_deviceStatesOnWhichToSleep))
+                .thenReturn(new int[]{0});
 
         mLooper = new TestLooper();
         mHandler = new Handler(mLooper.getLooper());
@@ -312,6 +323,49 @@
                 mLogicalDisplayMapper.getDisplayGroupIdFromDisplayIdLocked(id(display3)));
     }
 
+    @Test
+    public void testDeviceShouldBeWoken() {
+        assertTrue(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_OPEN,
+                DEVICE_STATE_CLOSED,
+                /* isInteractive= */false,
+                /* isBootCompleted= */true));
+    }
+
+    @Test
+    public void testDeviceShouldNotBeWoken() {
+        assertFalse(mLogicalDisplayMapper.shouldDeviceBeWoken(DEVICE_STATE_CLOSED,
+                DEVICE_STATE_OPEN,
+                /* isInteractive= */false,
+                /* isBootCompleted= */true));
+    }
+
+    @Test
+    public void testDeviceShouldBePutToSleep() {
+        assertTrue(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED,
+                DEVICE_STATE_OPEN,
+                /* isOverrideActive= */false,
+                /* isInteractive= */true,
+                /* isBootCompleted= */true));
+    }
+
+    @Test
+    public void testDeviceShouldNotBePutToSleep() {
+        assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_OPEN,
+                DEVICE_STATE_CLOSED,
+                /* isOverrideActive= */false,
+                /* isInteractive= */true,
+                /* isBootCompleted= */true));
+    }
+
+    @Test
+    public void testDeviceShouldNotBePutToSleepDifferentBaseState() {
+        assertFalse(mLogicalDisplayMapper.shouldDeviceBePutToSleep(DEVICE_STATE_CLOSED,
+                DEVICE_STATE_OPEN,
+                /* isOverrideActive= */true,
+                /* isInteractive= */true,
+                /* isBootCompleted= */true));
+    }
+
     /////////////////
     // Helper Methods
     /////////////////
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/integrity/parser/RuleBinaryParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
index ab21ab0..03363a1 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleBinaryParserTest.java
@@ -71,9 +71,11 @@
 
     private static final String PACKAGE_NAME = getBits(AtomicFormula.PACKAGE_NAME, KEY_BITS);
     private static final String APP_CERTIFICATE = getBits(AtomicFormula.APP_CERTIFICATE, KEY_BITS);
+    private static final String APP_CERTIFICATE_LINEAGE =
+            getBits(AtomicFormula.APP_CERTIFICATE_LINEAGE, KEY_BITS);
     private static final String VERSION_CODE = getBits(AtomicFormula.VERSION_CODE, KEY_BITS);
     private static final String PRE_INSTALLED = getBits(AtomicFormula.PRE_INSTALLED, KEY_BITS);
-    private static final int INVALID_KEY_VALUE = 8;
+    private static final int INVALID_KEY_VALUE = 9;
     private static final String INVALID_KEY = getBits(INVALID_KEY_VALUE, KEY_BITS);
 
     private static final String EQ = getBits(AtomicFormula.EQ, OPERATOR_BITS);
@@ -337,6 +339,40 @@
     }
 
     @Test
+    public void testBinaryString_validAtomicFormulaWithCertificateLineage() throws Exception {
+        String appCertificate = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
+        String ruleBits =
+                START_BIT
+                        + ATOMIC_FORMULA_START_BITS
+                        + APP_CERTIFICATE_LINEAGE
+                        + EQ
+                        + IS_HASHED
+                        + getBits(appCertificate.length(), VALUE_SIZE_BITS)
+                        + getValueBits(appCertificate)
+                        + DENY
+                        + END_BIT;
+        byte[] ruleBytes = getBytes(ruleBits);
+        ByteBuffer rule =
+                ByteBuffer.allocate(DEFAULT_FORMAT_VERSION_BYTES.length + ruleBytes.length);
+        rule.put(DEFAULT_FORMAT_VERSION_BYTES);
+        rule.put(ruleBytes);
+
+        RuleParser binaryParser = new RuleBinaryParser();
+        Rule expectedRule =
+                new Rule(
+                        new AtomicFormula.StringAtomicFormula(
+                                AtomicFormula.APP_CERTIFICATE_LINEAGE,
+                                IntegrityUtils.getHexDigest(
+                                        appCertificate.getBytes(StandardCharsets.UTF_8)),
+                                /* isHashedValue= */ true),
+                        Rule.DENY);
+
+        List<Rule> rules = binaryParser.parse(rule.array());
+
+        assertThat(rules).isEqualTo(Collections.singletonList(expectedRule));
+    }
+
+    @Test
     public void testBinaryString_validAtomicFormula_integerValue_noIndexing() throws Exception {
         int versionCode = 1;
         String ruleBits =
diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
index c771000..bd35be4 100644
--- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerBackupRestoreTest.java
@@ -41,7 +41,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
 import android.os.Binder;
+import android.os.HandlerThread;
 import android.os.LocaleList;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SimpleClock;
 import android.util.SparseArray;
@@ -78,6 +80,7 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class LocaleManagerBackupRestoreTest {
+    private static final String TAG = "LocaleManagerBackupRestoreTest";
     private static final String DEFAULT_PACKAGE_NAME = "com.android.myapp";
     private static final String DEFAULT_LOCALE_TAGS = "en-XC,ar-XB";
     private static final String TEST_LOCALES_XML_TAG = "locales";
@@ -104,6 +107,7 @@
     private PackageManager mMockPackageManager;
     @Mock
     private LocaleManagerService mMockLocaleManagerService;
+
     BroadcastReceiver mUserMonitor;
     PackageMonitor mPackageMonitor;
 
@@ -128,15 +132,22 @@
         mMockPackageManagerInternal = mock(PackageManagerInternal.class);
         mMockPackageManager = mock(PackageManager.class);
         mMockLocaleManagerService = mock(LocaleManagerService.class);
+        SystemAppUpdateTracker systemAppUpdateTracker = mock(SystemAppUpdateTracker.class);
 
         doReturn(mMockPackageManager).when(mMockContext).getPackageManager();
 
+        HandlerThread broadcastHandlerThread = new HandlerThread(TAG,
+                Process.THREAD_PRIORITY_BACKGROUND);
+        broadcastHandlerThread.start();
+
         mBackupHelper = spy(new ShadowLocaleManagerBackupHelper(mMockContext,
-                mMockLocaleManagerService, mMockPackageManagerInternal, mClock, STAGE_DATA));
+                mMockLocaleManagerService, mMockPackageManagerInternal, mClock, STAGE_DATA,
+                broadcastHandlerThread));
         doNothing().when(mBackupHelper).notifyBackupManager();
 
         mUserMonitor = mBackupHelper.getUserMonitor();
-        mPackageMonitor = mBackupHelper.getPackageMonitor();
+        mPackageMonitor = new LocaleManagerServicePackageMonitor(mBackupHelper,
+            systemAppUpdateTracker);
         setCurrentTimeMillis(DEFAULT_CREATION_TIME_MILLIS);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
index ca5b0cb..0b3ef45 100644
--- a/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/LocaleManagerServiceTest.java
@@ -46,6 +46,7 @@
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.internal.content.PackageMonitor;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal.PackageConfig;
 
@@ -86,6 +87,8 @@
     private ActivityTaskManagerInternal mMockActivityTaskManager;
     @Mock
     private ActivityManagerInternal mMockActivityManager;
+    @Mock
+    PackageMonitor mMockPackageMonitor;
 
     @Before
     public void setUp() throws Exception {
@@ -93,6 +96,7 @@
         mMockActivityTaskManager = mock(ActivityTaskManagerInternal.class);
         mMockActivityManager = mock(ActivityManagerInternal.class);
         mMockPackageManagerInternal = mock(PackageManagerInternal.class);
+        mMockPackageMonitor = mock(PackageMonitor.class);
 
         // For unit tests, set the default installer info
         PackageManager mockPackageManager = mock(PackageManager.class);
@@ -113,7 +117,8 @@
 
         mMockBackupHelper = mock(ShadowLocaleManagerBackupHelper.class);
         mLocaleManagerService = new LocaleManagerService(mMockContext, mMockActivityTaskManager,
-                mMockActivityManager, mMockPackageManagerInternal, mMockBackupHelper);
+                mMockActivityManager, mMockPackageManagerInternal,
+                mMockBackupHelper, mMockPackageMonitor);
     }
 
     @Test(expected = SecurityException.class)
diff --git a/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java b/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java
index b0fc636..ad9be0d 100644
--- a/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java
+++ b/services/tests/servicestests/src/com/android/server/locales/ShadowLocaleManagerBackupHelper.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.pm.PackageManagerInternal;
+import android.os.HandlerThread;
 import android.util.SparseArray;
 
 import java.time.Clock;
@@ -31,7 +32,8 @@
     ShadowLocaleManagerBackupHelper(Context context,
             LocaleManagerService localeManagerService,
             PackageManagerInternal pmInternal, Clock clock,
-            SparseArray<LocaleManagerBackupHelper.StagedData> stagedData) {
-        super(context, localeManagerService, pmInternal, clock, stagedData);
+            SparseArray<LocaleManagerBackupHelper.StagedData> stagedData,
+            HandlerThread broadcastHandlerThread) {
+        super(context, localeManagerService, pmInternal, clock, stagedData, broadcastHandlerThread);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
new file mode 100644
index 0000000..db602ca
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
@@ -0,0 +1,300 @@
+/*
+ * 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.locales;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+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.verifyZeroInteractions;
+
+import android.app.ActivityManagerInternal;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.InstallSourceInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.os.Binder;
+import android.os.Environment;
+import android.os.LocaleList;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.AtomicFile;
+import android.util.TypedXmlPullParser;
+import android.util.Xml;
+
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.XmlUtils;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Unit tests for {@link SystemAppUpdateTracker}.
+ */
+public class SystemAppUpdateTrackerTest {
+    private static final String DEFAULT_PACKAGE_NAME_1 = "com.android.myapp1";
+    private static final String DEFAULT_PACKAGE_NAME_2 = "com.android.myapp2";
+    private static final String DEFAULT_LOCALE_TAGS = "en-XC,ar-XB";
+    private static final LocaleList DEFAULT_LOCALES =
+            LocaleList.forLanguageTags(DEFAULT_LOCALE_TAGS);
+    private static final String PACKAGE_XML_TAG = "package";
+    private static final String ATTR_NAME = "name";
+    private static final String SYSTEM_APPS_XML_TAG = "system_apps";
+    private static final int DEFAULT_USER_ID = 0;
+
+    private AtomicFile mStoragefile;
+    private static final String DEFAULT_INSTALLER_PACKAGE_NAME = "com.android.myapp.installer";
+    private static final InstallSourceInfo DEFAULT_INSTALL_SOURCE_INFO = new InstallSourceInfo(
+            /* initiatingPackageName = */ null, /* initiatingPackageSigningInfo = */ null,
+            /* originatingPackageName = */ null,
+            /* installingPackageName = */ DEFAULT_INSTALLER_PACKAGE_NAME,
+            /* packageSource = */ PackageInstaller.PACKAGE_SOURCE_UNSPECIFIED);
+
+    @Mock
+    private Context mMockContext;
+    @Mock
+    PackageManager mMockPackageManager;
+    @Mock
+    private PackageManagerInternal mMockPackageManagerInternal;
+    @Mock
+    private ActivityTaskManagerInternal mMockActivityTaskManager;
+    @Mock
+    private ActivityManagerInternal mMockActivityManager;
+
+    PackageMonitor mPackageMonitor;
+    private LocaleManagerService mLocaleManagerService;
+
+    // Object under test.
+    private SystemAppUpdateTracker mSystemAppUpdateTracker;
+
+    @Before
+    public void setUp() throws Exception {
+        mMockContext = mock(Context.class);
+        mMockActivityTaskManager = mock(ActivityTaskManagerInternal.class);
+        mMockActivityManager = mock(ActivityManagerInternal.class);
+        mMockPackageManagerInternal = mock(PackageManagerInternal.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, mockLocaleManagerBackupHelper,
+                /* mPackageMonitor= */ null);
+
+        doReturn(DEFAULT_USER_ID).when(mMockActivityManager)
+                .handleIncomingUser(anyInt(), anyInt(), eq(DEFAULT_USER_ID), anyBoolean(), anyInt(),
+                        anyString(), anyString());
+
+        mMockPackageManager = mock(PackageManager.class);
+        doReturn(DEFAULT_INSTALL_SOURCE_INFO).when(mMockPackageManager)
+                .getInstallSourceInfo(anyString());
+        doReturn(mMockPackageManager).when(mMockContext).getPackageManager();
+
+        mStoragefile = new AtomicFile(new File(
+                Environment.getExternalStorageDirectory(), "systemUpdateUnitTests.xml"));
+
+        mSystemAppUpdateTracker = new SystemAppUpdateTracker(mMockContext,
+            mLocaleManagerService, mStoragefile);
+
+        mPackageMonitor = new LocaleManagerServicePackageMonitor(
+                mockLocaleManagerBackupHelper, mSystemAppUpdateTracker);
+    }
+
+    @After
+    public void tearDown() {
+        mStoragefile.delete();
+    }
+
+    @Test
+    public void testInit_loadsCorrectly() throws Exception {
+        doReturn(createApplicationInfoForApp(DEFAULT_PACKAGE_NAME_1,
+            /* isUpdatedSystemApp = */ true))
+            .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
+
+        // Updates the app once so that it writes to the file.
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+                Binder.getCallingUid());
+        // Clear the in-memory data of updated apps
+        mSystemAppUpdateTracker.getUpdatedApps().clear();
+        // Invoke init to verify if it correctly populates in-memory set.
+        mSystemAppUpdateTracker.init();
+
+        assertEquals(Set.of(DEFAULT_PACKAGE_NAME_1), mSystemAppUpdateTracker.getUpdatedApps());
+    }
+
+    @Test
+    public void testOnPackageUpdatedFinished_systemAppFirstUpdate_writesToFile() throws Exception {
+        doReturn(createApplicationInfoForApp(DEFAULT_PACKAGE_NAME_1,
+            /* isUpdatedSystemApp = */ true))
+            .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
+        doReturn(new ActivityTaskManagerInternal.PackageConfig(/* nightMode = */ 0,
+                DEFAULT_LOCALES)).when(mMockActivityTaskManager)
+                .getApplicationConfig(anyString(), anyInt());
+
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+                Binder.getCallingUid());
+
+        assertBroadcastSentToInstaller(DEFAULT_PACKAGE_NAME_1, DEFAULT_LOCALES);
+        Set<String> expectedAppList = Set.of(DEFAULT_PACKAGE_NAME_1);
+        assertEquals(expectedAppList, mSystemAppUpdateTracker.getUpdatedApps());
+        verifyStorageFileContents(expectedAppList);
+    }
+
+    @Test
+    public void testOnPackageUpdatedFinished_systemAppSecondUpdate_doesNothing() throws Exception {
+        doReturn(createApplicationInfoForApp(DEFAULT_PACKAGE_NAME_1,
+            /* isUpdatedSystemApp = */ true))
+            .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
+        doReturn(new ActivityTaskManagerInternal.PackageConfig(/* nightMode = */ 0,
+                DEFAULT_LOCALES)).when(mMockActivityTaskManager)
+                .getApplicationConfig(anyString(), anyInt());
+
+        // first update
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+                Binder.getCallingUid());
+
+        assertBroadcastSentToInstaller(DEFAULT_PACKAGE_NAME_1, DEFAULT_LOCALES);
+        Set<String> expectedAppList = Set.of(DEFAULT_PACKAGE_NAME_1);
+        assertEquals(expectedAppList, mSystemAppUpdateTracker.getUpdatedApps());
+        verifyStorageFileContents(expectedAppList);
+
+        // second update
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+                Binder.getCallingUid());
+        // getApplicationLocales should be invoked only once on the first update.
+        verify(mMockActivityTaskManager, times(1))
+                .getApplicationConfig(anyString(), anyInt());
+        // Broadcast should be sent only once on first update.
+        verify(mMockContext, times(1)).sendBroadcastAsUser(any(), any());
+        // Verify that the content remains the same.
+        verifyStorageFileContents(expectedAppList);
+    }
+
+    @Test
+    public void testOnPackageUpdatedFinished_notSystemApp_doesNothing() throws Exception {
+        doReturn(createApplicationInfoForApp(DEFAULT_PACKAGE_NAME_2,
+            /* isUpdatedSystemApp = */false))
+            .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_2), any());
+
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_2,
+                Binder.getCallingUid());
+
+        assertTrue(!mSystemAppUpdateTracker.getUpdatedApps().contains(DEFAULT_PACKAGE_NAME_2));
+        // getApplicationLocales should be never be invoked if not a system app.
+        verifyZeroInteractions(mMockActivityTaskManager);
+        // Broadcast should be never sent if not a system app.
+        verify(mMockContext, never()).sendBroadcastAsUser(any(), any());
+        // It shouldn't write to the file if not a system app.
+        assertTrue(!mStoragefile.getBaseFile().isFile());
+    }
+
+    @Test
+    public void testOnPackageUpdatedFinished_noInstaller_doesNothing() throws Exception {
+        doReturn(createApplicationInfoForApp(DEFAULT_PACKAGE_NAME_1,
+            /* isUpdatedSystemApp = */ true))
+            .when(mMockPackageManager).getApplicationInfo(eq(DEFAULT_PACKAGE_NAME_1), any());
+        doReturn(null).when(mMockPackageManager).getInstallSourceInfo(anyString());
+
+        mPackageMonitor.onPackageUpdateFinished(DEFAULT_PACKAGE_NAME_1,
+                Binder.getCallingUid());
+
+        // getApplicationLocales should be never be invoked if not installer is not present.
+        verifyZeroInteractions(mMockActivityTaskManager);
+        // Broadcast should be never sent if installer is not present.
+        verify(mMockContext, never()).sendBroadcastAsUser(any(), any());
+        // It shouldn't write to file if no installer present.
+        assertTrue(!mStoragefile.getBaseFile().isFile());
+    }
+
+    private void verifyStorageFileContents(Set<String> expectedAppList)
+            throws IOException, XmlPullParserException {
+        assertTrue(mStoragefile.getBaseFile().isFile());
+        try (InputStream storageInputStream = mStoragefile.openRead()) {
+            assertEquals(expectedAppList, readFromXml(storageInputStream));
+        } catch (IOException | XmlPullParserException e) {
+            throw e;
+        }
+    }
+
+    private Set<String> readFromXml(InputStream storageInputStream)
+            throws XmlPullParserException, IOException {
+        Set<String> outputList = new HashSet<>();
+        final TypedXmlPullParser parser = Xml.newFastPullParser();
+        parser.setInput(storageInputStream, StandardCharsets.UTF_8.name());
+        XmlUtils.beginDocument(parser, SYSTEM_APPS_XML_TAG);
+        int depth = parser.getDepth();
+        while (XmlUtils.nextElementWithin(parser, depth)) {
+            if (parser.getName().equals(PACKAGE_XML_TAG)) {
+                String packageName = parser.getAttributeValue(/* namespace= */ null,
+                        ATTR_NAME);
+                if (!TextUtils.isEmpty(packageName)) {
+                    outputList.add(packageName);
+                }
+            }
+        }
+        return outputList;
+    }
+
+    /**
+     * Verifies the broadcast sent to the installer of the updated app.
+     */
+    private void assertBroadcastSentToInstaller(String packageName, LocaleList locales) {
+        ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
+        verify(mMockContext).sendBroadcastAsUser(captor.capture(), any(UserHandle.class));
+        for (Intent intent : captor.getAllValues()) {
+            assertTrue(Intent.ACTION_APPLICATION_LOCALE_CHANGED.equals(intent.getAction()));
+            assertTrue(DEFAULT_INSTALLER_PACKAGE_NAME.equals(intent.getPackage()));
+            assertTrue(packageName.equals(intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME)));
+            assertTrue(locales.equals(intent.getParcelableExtra(Intent.EXTRA_LOCALE_LIST)));
+        }
+    }
+
+    private ApplicationInfo createApplicationInfoForApp(String packageName,
+            boolean isUpdatedSystemApp) {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.packageName = packageName;
+        if (isUpdatedSystemApp) {
+            applicationInfo.flags = ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+        }
+        return applicationInfo;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
index acb20ed..6de7fdd 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
@@ -229,8 +229,8 @@
     }
 
     private void verifyAlarm(long when, String tag, AlarmManager.OnAlarmListener alarm) {
-        verify(mAlarmManager).set(
-                eq(AlarmManager.ELAPSED_REALTIME),
+        verify(mAlarmManager).setExact(
+                eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
                 eq(when),
                 eq(tag),
                 eq(alarm),
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index 5d3da43..c7a903b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -489,6 +489,20 @@
         assertThat(e).hasMessageThat().contains("Failed to collect certificates from ");
     }
 
+    @Test
+    public void testGetActivePackageNameForApexModuleName() throws Exception {
+        final String moduleName = "com.android.module_name";
+
+        ApexInfo[] apexInfo = createApexInfoForTestPkg(true, false);
+        apexInfo[0].moduleName = moduleName;
+        when(mApexService.getAllPackages()).thenReturn(apexInfo);
+        mApexManager.scanApexPackagesTraced(mPackageParser2,
+                ParallelPackageParser.makeExecutorService());
+
+        assertThat(mApexManager.getActivePackageNameForApexModuleName(moduleName))
+                .isEqualTo(TEST_APEX_PKG);
+    }
+
     private ApexInfo createApexInfoForTestPkg(boolean isActive, boolean isFactory, int version) {
         File apexFile = extractResource(TEST_APEX_PKG,  TEST_APEX_FILE_NAME);
         ApexInfo apexInfo = new ApexInfo();
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/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
index 401cd7f..c7b5547 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java
@@ -1079,6 +1079,19 @@
     }
 
     @Test
+    public void testGetUserName_shouldReturnTranslatedTextForNullNamedGuestUser() throws Exception {
+        UserInfo guestWithNullName = createUser(null, UserManager.USER_TYPE_FULL_GUEST, 0);
+        assertThat(guestWithNullName).isNotNull();
+
+        UserManager um = (UserManager) mContext.createPackageContextAsUser(
+                "android", 0, guestWithNullName.getUserHandle())
+                .getSystemService(Context.USER_SERVICE);
+
+        assertThat(um.getUserName()).isEqualTo(
+                mContext.getString(com.android.internal.R.string.guest_name));
+    }
+
+    @Test
     public void testGetUserIcon_withContextUserId() throws Exception {
         assumeManagedUsersSupported();
         final int primaryUserId = mUserManager.getPrimaryUser().id;
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
index c59b58d..d8c9c34 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
@@ -17,23 +17,43 @@
 package com.android.server.power;
 
 
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DIM;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_VR;
 import static android.os.PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
 import static android.os.PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN;
+import static android.os.PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD;
 import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT;
 import static android.os.PowerManager.WAKE_REASON_GESTURE;
+import static android.os.PowerManager.WAKE_REASON_PLUGGED_IN;
 import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
 import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
 import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
 
+import static com.android.server.power.PowerManagerService.USER_ACTIVITY_SCREEN_BRIGHT;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_DOZE;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
-import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.hardware.display.DisplayManagerInternal;
+import android.os.PowerManager;
+import android.os.PowerSaveState;
+import android.view.Display;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.internal.util.LatencyTracker;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -49,26 +69,56 @@
 public class PowerGroupTest {
 
     private static final int GROUP_ID = 0;
+    private static final int UID = 11;
     private static final long TIMESTAMP_CREATE = 1;
     private static final long TIMESTAMP1 = 999;
     private static final long TIMESTAMP2 = TIMESTAMP1 + 10;
     private static final long TIMESTAMP3 = TIMESTAMP2 + 10;
-    private static final int UID = 11;
+
+    private static final float PRECISION = 0.001f;
+
+    private static final float BRIGHTNESS = 0.99f;
+    private static final float BRIGHTNESS_DOZE = 0.5f;
+
+
 
     private PowerGroup mPowerGroup;
-    @Mock
-    private PowerGroup.PowerGroupListener mWakefulnessCallbackMock;
+    @Mock private PowerGroup.PowerGroupListener mWakefulnessCallbackMock;
+    @Mock private Notifier mNotifier;
+    @Mock private DisplayManagerInternal mDisplayManagerInternal;
+
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mPowerGroup = new PowerGroup(GROUP_ID, mWakefulnessCallbackMock, new DisplayPowerRequest(),
-                WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */true, TIMESTAMP_CREATE);
+        mPowerGroup = new PowerGroup(GROUP_ID, mWakefulnessCallbackMock, mNotifier,
+                mDisplayManagerInternal, WAKEFULNESS_AWAKE, /* ready= */ true,
+                /* supportsSandman= */ true, TIMESTAMP_CREATE);
     }
 
     @Test
-    public void testDreamPowerGroupTriggersOnWakefulnessChangedCallback() {
+    public void testWakePowerGroup() {
+        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_APPLICATION);
+        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION),
+                eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */
+                isNull());
+        String details = "wake PowerGroup1";
+        LatencyTracker latencyTracker = LatencyTracker.getInstance(
+                InstrumentationRegistry.getInstrumentation().getContext());
+        mPowerGroup.wakeUpLocked(TIMESTAMP2, WAKE_REASON_PLUGGED_IN, details, UID,
+                /* opPackageName= */ null, /* opUid= */ 0, latencyTracker);
+        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+                eq(WAKEFULNESS_AWAKE), eq(TIMESTAMP2), eq(WAKE_REASON_PLUGGED_IN), eq(UID),
+                /* opUid= */ anyInt(), /* opPackageName= */ isNull(), eq(details));
+    }
+
+    @Test
+    public void testDreamPowerGroup() {
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
         mPowerGroup.dreamLocked(TIMESTAMP1, UID);
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
+        assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue();
         verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
                 eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION),
                 eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */
@@ -76,6 +126,61 @@
     }
 
     @Test
+    public void testDozePowerGroup() {
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+        assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue();
+        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+                eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
+                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
+                /* details= */ isNull());
+    }
+
+    @Test
+    public void testDozePowerGroupWhenNonInteractiveHasNoEffect() {
+        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
+        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
+                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
+                /* details= */ isNull());
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mPowerGroup.dozeLocked(TIMESTAMP2, UID, GO_TO_SLEEP_REASON_TIMEOUT)).isFalse();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+        verify(mWakefulnessCallbackMock, never()).onWakefulnessChangedLocked(
+                eq(GROUP_ID), eq(WAKEFULNESS_DOZING), eq(TIMESTAMP2), /* reason= */ anyInt(),
+                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ any(), /* details= */ any());
+    }
+
+    @Test
+    public void testSleepPowerGroup() {
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_DEVICE_FOLD);
+        assertThat(mPowerGroup.isSandmanSummonedLocked()).isTrue();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+                eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_DEVICE_FOLD),
+                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
+                /* details= */ isNull());
+    }
+
+    @Test
+    public void testDreamPowerGroupWhenNotAwakeHasNoEffect() {
+        mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
+        verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+                eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
+                eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(),
+                /* details= */ isNull());
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+        assertThat(mPowerGroup.dreamLocked(TIMESTAMP2, UID)).isFalse();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+        verify(mWakefulnessCallbackMock, never()).onWakefulnessChangedLocked(
+                eq(GROUP_ID), /* wakefulness= */ eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP2),
+                /* reason= */ anyInt(), eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ any(),
+                /* details= */ any());
+    }
+
+    @Test
     public void testLastWakeAndSleepTimeIsUpdated() {
         assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
         assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
@@ -126,4 +231,433 @@
                 eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP3), eq(GO_TO_SLEEP_REASON_DEVICE_ADMIN),
                 eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details));
     }
+
+    @Test
+    public void testUpdateWhileAwake_UpdatesDisplayPowerRequest() {
+        final boolean batterySaverEnabled = true;
+        float brightnessFactor = 0.7f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ false,
+                /* useProximitySensor= */ false,
+                /* boostScreenBrightness= */ false,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ false,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_DIM);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(false);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(false);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(false);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileDozing_UpdatesDisplayPowerRequest() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_APPLICATION);
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+        mPowerGroup.setWakeLockSummaryLocked(WAKE_LOCK_DOZE);
+
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ false,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_DOZE);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_ON);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isWithin(PRECISION).of(
+                BRIGHTNESS_DOZE);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileDozing_DozeAfterScreenOff() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        mPowerGroup.dozeLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_APPLICATION);
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ true,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateQuiescent() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ true,
+                /* dozeAfterScreenOff= */ true,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileAsleep_VrModeEnabled() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ true,
+                /* vrModeEnabled= */ true,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileAwake_VrModeEnabled() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ true,
+                /* vrModeEnabled= */ true,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_VR);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileAsleep_UpdatesDisplayPowerRequest() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        mPowerGroup.sleepLocked(TIMESTAMP1, UID, GO_TO_SLEEP_REASON_TIMEOUT);
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ false,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_OFF);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileDreamingWithScreenBrightWakelock_UpdatesDisplayPowerRequest() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        mPowerGroup.dreamLocked(TIMESTAMP1, UID);
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
+        mPowerGroup.setWakeLockSummaryLocked(WAKE_LOCK_SCREEN_BRIGHT);
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ false,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileAwakeBootNotComplete_UpdatesDisplayPowerRequest() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ false,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ false,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileAwakeUserActivityScreenBright_UpdatesDisplayPowerRequest() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        mPowerGroup.setUserActivitySummaryLocked(USER_ACTIVITY_SCREEN_BRIGHT);
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ false,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ false,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
+
+    @Test
+    public void testUpdateWhileAwakeScreenBrightnessBoostInProgress_UpdatesDisplayPowerRequest() {
+        final boolean batterySaverEnabled = false;
+        float brightnessFactor = 0.3f;
+        PowerSaveState powerSaveState = new PowerSaveState.Builder()
+                .setBatterySaverEnabled(batterySaverEnabled)
+                .setBrightnessFactor(brightnessFactor)
+                .build();
+        assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        mPowerGroup.updateLocked(/* screenBrightnessOverride= */ BRIGHTNESS,
+                /* autoBrightness = */ true,
+                /* useProximitySensor= */ true,
+                /* boostScreenBrightness= */ true,
+                /* dozeScreenStateOverride= */ Display.STATE_ON,
+                /* dozeScreenBrightness= */ BRIGHTNESS_DOZE,
+                /* overrideDrawWakeLock= */ false,
+                powerSaveState,
+                /* quiescent= */ false,
+                /* dozeAfterScreenOff= */ false,
+                /* vrModeEnabled= */ false,
+                /* bootCompleted= */ true,
+                /* screenBrightnessBoostInProgress= */ true,
+                /* waitForNegativeProximity= */ false);
+        DisplayManagerInternal.DisplayPowerRequest displayPowerRequest =
+                mPowerGroup.mDisplayPowerRequest;
+        assertThat(displayPowerRequest.policy).isEqualTo(POLICY_BRIGHT);
+        assertThat(displayPowerRequest.screenBrightnessOverride).isWithin(PRECISION).of(BRIGHTNESS);
+        assertThat(displayPowerRequest.useAutoBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.useProximitySensor).isEqualTo(true);
+        assertThat(displayPowerRequest.boostScreenBrightness).isEqualTo(true);
+        assertThat(displayPowerRequest.dozeScreenState).isEqualTo(Display.STATE_UNKNOWN);
+        assertThat(displayPowerRequest.dozeScreenBrightness).isEqualTo(
+                PowerManager.BRIGHTNESS_INVALID_FLOAT);
+        assertThat(displayPowerRequest.lowPowerMode).isEqualTo(batterySaverEnabled);
+        assertThat(displayPowerRequest.screenLowPowerBrightnessFactor).isWithin(PRECISION).of(
+                brightnessFactor);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 1b92017..b2f506a 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -123,7 +123,6 @@
     private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
     private static final String SYSTEM_PROPERTY_REBOOT_REASON = "sys.boot.reason";
 
-    private static final float PRECISION = 0.001f;
     private static final float BRIGHTNESS_FACTOR = 0.7f;
     private static final boolean BATTERY_SAVER_ENABLED = true;
 
@@ -146,7 +145,6 @@
     private InattentiveSleepWarningController mInattentiveSleepWarningControllerMock;
 
     private PowerManagerService mService;
-    private DisplayPowerRequest mDisplayPowerRequest;
     private ContextWrapper mContextSpy;
     private BatteryReceiver mBatteryReceiver;
     private UserSwitchedReceiver mUserSwitchedReceiver;
@@ -195,7 +193,6 @@
         when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_QUIESCENT), anyString())).thenReturn("");
         when(mAmbientDisplayConfigurationMock.ambientDisplayAvailable()).thenReturn(true);
 
-        mDisplayPowerRequest = new DisplayPowerRequest();
         addLocalServiceMock(LightsManager.class, mLightsManagerMock);
         addLocalServiceMock(DisplayManagerInternal.class, mDisplayManagerInternalMock);
         addLocalServiceMock(BatteryManagerInternal.class, mBatteryManagerInternalMock);
@@ -419,15 +416,6 @@
     }
 
     @Test
-    public void testUpdatePowerScreenPolicy_UpdateDisplayPowerRequest() {
-        createService();
-        mService.updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest);
-        assertThat(mDisplayPowerRequest.lowPowerMode).isEqualTo(BATTERY_SAVER_ENABLED);
-        assertThat(mDisplayPowerRequest.screenLowPowerBrightnessFactor)
-                .isWithin(PRECISION).of(BRIGHTNESS_FACTOR);
-    }
-
-    @Test
     public void testGetLastShutdownReasonInternal() {
         when(mSystemPropertiesMock.get(eq(SYSTEM_PROPERTY_REBOOT_REASON), any())).thenReturn(
                 "shutdown,thermal");
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
index 16cfd13..6bdd88c 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/SoundHw2CompatTest.java
@@ -31,7 +31,6 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -49,7 +48,6 @@
 import android.os.IHwBinder;
 import android.os.IHwInterface;
 import android.os.RemoteException;
-import android.system.OsConstants;
 
 import org.junit.After;
 import org.junit.Before;
@@ -60,6 +58,7 @@
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
 
 @RunWith(Parameterized.class)
 public class SoundHw2CompatTest {
@@ -240,14 +239,15 @@
                 (android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver;
 
         final int handle = 29;
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel> modelCaptor =
-                ArgumentCaptor.forClass(
-                        android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel.class);
+        AtomicReference<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel> model =
+                new AtomicReference<>();
         ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
 
         doAnswer(invocation -> {
+            // We need to dup the model, as it gets invalidated after the call returns.
+            model.set(TestUtil.dupModel_2_1(invocation.getArgument(0)));
             android.hardware.soundtrigger.V2_1.ISoundTriggerHw.loadSoundModel_2_1Callback
                     resultCallback = invocation.getArgument(3);
 
@@ -259,10 +259,9 @@
         assertEquals(handle,
                 mCanonical.loadSoundModel(TestUtil.createGenericSoundModel(), canonicalCallback));
 
-        verify(driver_2_1).loadSoundModel_2_1(modelCaptor.capture(), callbackCaptor.capture(),
-                anyInt(), any());
+        verify(driver_2_1).loadSoundModel_2_1(any(), callbackCaptor.capture(), anyInt(), any());
 
-        TestUtil.validateGenericSoundModel_2_1(modelCaptor.getValue());
+        TestUtil.validateGenericSoundModel_2_1(model.get());
         validateCallback_2_1(callbackCaptor.getValue(), canonicalCallback);
         return handle;
     }
@@ -355,14 +354,16 @@
                 (android.hardware.soundtrigger.V2_1.ISoundTriggerHw) mHalDriver;
 
         final int handle = 29;
-        ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel>
-                modelCaptor = ArgumentCaptor.forClass(
-                android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel.class);
+        AtomicReference<android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel> model =
+                new AtomicReference<>();
         ArgumentCaptor<android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback> callbackCaptor =
                 ArgumentCaptor.forClass(
                         android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback.class);
 
         doAnswer(invocation -> {
+            // We need to dup the model, as it gets invalidated after the call returns.
+            model.set(TestUtil.dupPhraseModel_2_1(invocation.getArgument(0)));
+
             android.hardware.soundtrigger.V2_1.ISoundTriggerHw.loadPhraseSoundModel_2_1Callback
                     resultCallback = invocation.getArgument(3);
 
@@ -374,10 +375,10 @@
         assertEquals(handle, mCanonical.loadPhraseSoundModel(TestUtil.createPhraseSoundModel(),
                 canonicalCallback));
 
-        verify(driver_2_1).loadPhraseSoundModel_2_1(modelCaptor.capture(), callbackCaptor.capture(),
-                anyInt(), any());
+        verify(driver_2_1).loadPhraseSoundModel_2_1(any(), callbackCaptor.capture(), anyInt(),
+                any());
 
-        TestUtil.validatePhraseSoundModel_2_1(modelCaptor.getValue());
+        TestUtil.validatePhraseSoundModel_2_1(model.get());
         validateCallback_2_1(callbackCaptor.getValue(), canonicalCallback);
         return handle;
     }
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
index e687a2a..30b4a59 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/TestUtil.java
@@ -47,6 +47,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.SharedMemory;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.List;
 
@@ -82,6 +83,19 @@
                 HidlMemoryUtil.hidlMemoryToByteArray(model.data));
     }
 
+    static android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel dupModel_2_1(
+            android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel model) {
+        android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel dup =
+                new android.hardware.soundtrigger.V2_1.ISoundTriggerHw.SoundModel();
+        dup.header = model.header;
+        try {
+            dup.data = model.data.dup();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return dup;
+    }
+
     private static void validateSoundModel_2_0(
             android.hardware.soundtrigger.V2_0.ISoundTriggerHw.SoundModel model, int type) {
         assertEquals(type, model.type);
@@ -121,6 +135,15 @@
         validatePhrases_2_0(model.phrases);
     }
 
+    static android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel dupPhraseModel_2_1(
+            android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel model) {
+        android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel dup =
+                new android.hardware.soundtrigger.V2_1.ISoundTriggerHw.PhraseSoundModel();
+        dup.common = dupModel_2_1(model.common);
+        dup.phrases = model.phrases;
+        return dup;
+    }
+
     static void validatePhraseSoundModel_2_0(
             android.hardware.soundtrigger.V2_0.ISoundTriggerHw.PhraseSoundModel model) {
         validateSoundModel_2_0(model.common,
@@ -190,31 +213,27 @@
         properties.maxKeyPhrases = 567;
         properties.maxUsers = 678;
         properties.recognitionModes =
-                RecognitionMode.VOICE_TRIGGER
-                        | RecognitionMode.USER_IDENTIFICATION
-                        | RecognitionMode.USER_AUTHENTICATION
-                        | RecognitionMode.GENERIC_TRIGGER;
+                RecognitionMode.VOICE_TRIGGER | RecognitionMode.USER_IDENTIFICATION
+                        | RecognitionMode.USER_AUTHENTICATION | RecognitionMode.GENERIC_TRIGGER;
         properties.captureTransition = true;
         properties.maxBufferMs = 321;
         properties.concurrentCapture = supportConcurrentCapture;
         properties.triggerInEvent = true;
         properties.powerConsumptionMw = 432;
         properties.supportedModelArch = "supportedModelArch";
-        properties.audioCapabilities = AudioCapabilities.ECHO_CANCELLATION
-                | AudioCapabilities.NOISE_SUPPRESSION;
+        properties.audioCapabilities =
+                AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION;
         return properties;
     }
 
-    static void validateDefaultProperties(Properties properties,
-            boolean supportConcurrentCapture) {
+    static void validateDefaultProperties(Properties properties, boolean supportConcurrentCapture) {
         validateDefaultProperties(properties, supportConcurrentCapture,
                 AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION,
                 "supportedModelArch");
     }
 
-    static void validateDefaultProperties(Properties properties,
-            boolean supportConcurrentCapture, @AudioCapabilities int audioCapabilities,
-            @NonNull String supportedModelArch) {
+    static void validateDefaultProperties(Properties properties, boolean supportConcurrentCapture,
+            @AudioCapabilities int audioCapabilities, @NonNull String supportedModelArch) {
         assertEquals("implementor", properties.implementor);
         assertEquals("description", properties.description);
         assertEquals(123, properties.version);
@@ -222,10 +241,9 @@
         assertEquals(456, properties.maxSoundModels);
         assertEquals(567, properties.maxKeyPhrases);
         assertEquals(678, properties.maxUsers);
-        assertEquals(RecognitionMode.GENERIC_TRIGGER
-                | RecognitionMode.USER_AUTHENTICATION
-                | RecognitionMode.USER_IDENTIFICATION
-                | RecognitionMode.VOICE_TRIGGER, properties.recognitionModes);
+        assertEquals(RecognitionMode.GENERIC_TRIGGER | RecognitionMode.USER_AUTHENTICATION
+                        | RecognitionMode.USER_IDENTIFICATION | RecognitionMode.VOICE_TRIGGER,
+                properties.recognitionModes);
         assertTrue(properties.captureTransition);
         assertEquals(321, properties.maxBufferMs);
         assertEquals(supportConcurrentCapture, properties.concurrentCapture);
@@ -246,8 +264,8 @@
         config.phraseRecognitionExtras[0].levels[0].userId = 234;
         config.phraseRecognitionExtras[0].levels[0].levelPercent = 34;
         config.data = new byte[]{5, 4, 3, 2, 1};
-        config.audioCapabilities = AudioCapabilities.ECHO_CANCELLATION
-                | AudioCapabilities.NOISE_SUPPRESSION;
+        config.audioCapabilities =
+                AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION;
         return config;
     }
 
@@ -295,13 +313,12 @@
             int captureHandle) {
         validateRecognitionConfig_2_1(config.base, captureDevice, captureHandle);
 
-        assertEquals(AudioCapabilities.ECHO_CANCELLATION
-                | AudioCapabilities.NOISE_SUPPRESSION, config.audioCapabilities);
+        assertEquals(AudioCapabilities.ECHO_CANCELLATION | AudioCapabilities.NOISE_SUPPRESSION,
+                config.audioCapabilities);
     }
 
     static android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent createRecognitionEvent_2_0(
-            int hwHandle,
-            int status) {
+            int hwHandle, int status) {
         android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent halEvent =
                 new android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent();
         halEvent.status = status;
@@ -351,8 +368,7 @@
         return event;
     }
 
-    static ISoundTriggerHwCallback.RecognitionEvent createRecognitionEvent_2_1(
-            int hwHandle,
+    static ISoundTriggerHwCallback.RecognitionEvent createRecognitionEvent_2_1(int hwHandle,
             int status) {
         ISoundTriggerHwCallback.RecognitionEvent halEvent =
                 new ISoundTriggerHwCallback.RecognitionEvent();
@@ -386,8 +402,7 @@
         PhraseRecognitionExtra extra = new PhraseRecognitionExtra();
         extra.id = 123;
         extra.confidenceLevel = 52;
-        extra.recognitionModes = RecognitionMode.VOICE_TRIGGER
-                | RecognitionMode.GENERIC_TRIGGER;
+        extra.recognitionModes = RecognitionMode.VOICE_TRIGGER | RecognitionMode.GENERIC_TRIGGER;
         ConfidenceLevel level = new ConfidenceLevel();
         level.userId = 31;
         level.levelPercent = 43;
@@ -396,8 +411,8 @@
         return event;
     }
 
-    static android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent
-    createPhraseRecognitionEvent_2_0(int hwHandle, int status) {
+    static android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent createPhraseRecognitionEvent_2_0(
+            int hwHandle, int status) {
         android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent halEvent =
                 new android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent();
         halEvent.common = createRecognitionEvent_2_0(hwHandle, status);
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 0e98b5e..1442f1c 100644
--- a/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
@@ -584,55 +584,55 @@
     }
 
     @Test
-    public void testSetNavBarModeOverride_setsOverrideModeKids() throws RemoteException {
-        int navBarModeOverrideKids = StatusBarManager.NAV_BAR_MODE_OVERRIDE_KIDS;
+    public void testSetNavBarMode_setsModeKids() throws RemoteException {
+        int navBarModeKids = StatusBarManager.NAV_BAR_MODE_KIDS;
 
-        mStatusBarManagerService.setNavBarModeOverride(navBarModeOverrideKids);
+        mStatusBarManagerService.setNavBarMode(navBarModeKids);
 
-        assertEquals(navBarModeOverrideKids, mStatusBarManagerService.getNavBarModeOverride());
+        assertEquals(navBarModeKids, mStatusBarManagerService.getNavBarMode());
         verify(mOverlayManager).setEnabledExclusiveInCategory(anyString(), anyInt());
     }
 
     @Test
-    public void testSetNavBarModeOverride_setsOverrideModeNone() throws RemoteException {
-        int navBarModeOverrideNone = StatusBarManager.NAV_BAR_MODE_OVERRIDE_NONE;
+    public void testSetNavBarMode_setsModeNone() throws RemoteException {
+        int navBarModeNone = StatusBarManager.NAV_BAR_MODE_DEFAULT;
 
-        mStatusBarManagerService.setNavBarModeOverride(navBarModeOverrideNone);
+        mStatusBarManagerService.setNavBarMode(navBarModeNone);
 
-        assertEquals(navBarModeOverrideNone, mStatusBarManagerService.getNavBarModeOverride());
+        assertEquals(navBarModeNone, mStatusBarManagerService.getNavBarMode());
         verify(mOverlayManager, never()).setEnabledExclusiveInCategory(anyString(), anyInt());
     }
 
     @Test
-    public void testSetNavBarModeOverride_invalidInputThrowsError() throws RemoteException {
-        int navBarModeOverrideInvalid = -1;
+    public void testSetNavBarMode_invalidInputThrowsError() throws RemoteException {
+        int navBarModeInvalid = -1;
 
         assertThrows(UnsupportedOperationException.class,
-                () -> mStatusBarManagerService.setNavBarModeOverride(navBarModeOverrideInvalid));
+                () -> mStatusBarManagerService.setNavBarMode(navBarModeInvalid));
         verify(mOverlayManager, never()).setEnabledExclusiveInCategory(anyString(), anyInt());
     }
 
     @Test
-    public void testSetNavBarModeOverride_noOverlayManagerDoesNotEnable() throws RemoteException {
+    public void testSetNavBarMode_noOverlayManagerDoesNotEnable() throws RemoteException {
         mOverlayManager = null;
-        int navBarModeOverrideKids = StatusBarManager.NAV_BAR_MODE_OVERRIDE_KIDS;
+        int navBarModeKids = StatusBarManager.NAV_BAR_MODE_KIDS;
 
-        mStatusBarManagerService.setNavBarModeOverride(navBarModeOverrideKids);
+        mStatusBarManagerService.setNavBarMode(navBarModeKids);
 
-        assertEquals(navBarModeOverrideKids, mStatusBarManagerService.getNavBarModeOverride());
+        assertEquals(navBarModeKids, mStatusBarManagerService.getNavBarMode());
         verify(mOverlayManager, never()).setEnabledExclusiveInCategory(anyString(), anyInt());
     }
 
     @Test
-    public void testSetNavBarModeOverride_noPackageDoesNotEnable() throws Exception {
+    public void testSetNavBarMode_noPackageDoesNotEnable() throws Exception {
         mContext.setMockPackageManager(mPackageManager);
         when(mPackageManager.getPackageInfo(anyString(),
                 any(PackageManager.PackageInfoFlags.class))).thenReturn(null);
-        int navBarModeOverrideKids = StatusBarManager.NAV_BAR_MODE_OVERRIDE_KIDS;
+        int navBarModeKids = StatusBarManager.NAV_BAR_MODE_KIDS;
 
-        mStatusBarManagerService.setNavBarModeOverride(navBarModeOverrideKids);
+        mStatusBarManagerService.setNavBarMode(navBarModeKids);
 
-        assertEquals(navBarModeOverrideKids, mStatusBarManagerService.getNavBarModeOverride());
+        assertEquals(navBarModeKids, mStatusBarManagerService.getNavBarMode());
         verify(mOverlayManager, never()).setEnabledExclusiveInCategory(anyString(), anyInt());
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index eeaf781..bfdffc0 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -39,9 +39,11 @@
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.Arrays;
@@ -137,13 +139,14 @@
                 new ArraySet<>(Arrays.asList("GUEST", "PROFILE")));
 
         final File folder1 = createTempSubfolder("folder1");
-        createTempFile(folder1, "permFile1.xml", contents1);
+        createTempFile(folder1, "permissionFile1.xml", contents1);
 
         final File folder2 = createTempSubfolder("folder2");
-        createTempFile(folder2, "permFile2.xml", contents2);
+        createTempFile(folder2, "permissionFile2.xml", contents2);
 
-        // Also, make a third file, but with the name folder1/permFile2.xml, to prove no conflicts.
-        createTempFile(folder1, "permFile2.xml", contents3);
+        // Also, make a third file, but with the name folder1/permissionFile2.xml, to prove no
+        // conflicts.
+        createTempFile(folder1, "permissionFile2.xml", contents3);
 
         readPermissions(folder1, /* No permission needed anyway */ 0);
         readPermissions(folder2, /* No permission needed anyway */ 0);
@@ -333,6 +336,91 @@
         assertThat(mSysConfig.getAllowedVendorApexes()).isEmpty();
     }
 
+    @Test
+    public void readApexPrivAppPermissions_addAllPermissions()
+            throws Exception {
+        final String contents =
+                "<privapp-permissions package=\"com.android.apk_in_apex\">"
+                        + "<permission name=\"android.permission.FOO\"/>"
+                        + "<deny-permission name=\"android.permission.BAR\"/>"
+                        + "</privapp-permissions>";
+        File apexDir = createTempSubfolder("apex");
+        File permissionFile = createTempFile(
+                createTempSubfolder("apex/com.android.my_module/etc/permissions"),
+                    "permissions.xml", contents);
+        XmlPullParser parser = readXmlUntilStartTag(permissionFile);
+
+        mSysConfig.readApexPrivAppPermissions(parser, permissionFile, apexDir.toPath());
+
+        assertThat(mSysConfig.getApexPrivAppPermissions("com.android.my_module",
+                "com.android.apk_in_apex"))
+            .containsExactly("android.permission.FOO");
+        assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.my_module",
+                "com.android.apk_in_apex"))
+            .containsExactly("android.permission.BAR");
+    }
+
+    @Test
+    public void pruneVendorApexPrivappAllowlists_removeVendor()
+            throws Exception {
+        File apexDir = createTempSubfolder("apex");
+
+        // Read non-vendor apex permission allowlists
+        final String allowlistNonVendorContents =
+                "<privapp-permissions package=\"com.android.apk_in_non_vendor_apex\">"
+                        + "<permission name=\"android.permission.FOO\"/>"
+                        + "<deny-permission name=\"android.permission.BAR\"/>"
+                        + "</privapp-permissions>";
+        File nonVendorPermDir =
+                createTempSubfolder("apex/com.android.non_vendor/etc/permissions");
+        File nonVendorPermissionFile =
+                createTempFile(nonVendorPermDir, "permissions.xml", allowlistNonVendorContents);
+        XmlPullParser nonVendorParser = readXmlUntilStartTag(nonVendorPermissionFile);
+        mSysConfig.readApexPrivAppPermissions(nonVendorParser, nonVendorPermissionFile,
+                apexDir.toPath());
+
+        // Read vendor apex permission allowlists
+        final String allowlistVendorContents =
+                "<privapp-permissions package=\"com.android.apk_in_vendor_apex\">"
+                        + "<permission name=\"android.permission.BAZ\"/>"
+                        + "<deny-permission name=\"android.permission.BAT\"/>"
+                        + "</privapp-permissions>";
+        File vendorPermissionFile =
+                createTempFile(createTempSubfolder("apex/com.android.vendor/etc/permissions"),
+                        "permissions.xml", allowlistNonVendorContents);
+        XmlPullParser vendorParser = readXmlUntilStartTag(vendorPermissionFile);
+        mSysConfig.readApexPrivAppPermissions(vendorParser, vendorPermissionFile,
+                apexDir.toPath());
+
+        // Read allowed vendor apex list
+        final String allowedVendorContents =
+                "<config>\n"
+                        + "    <allowed-vendor-apex package=\"com.android.vendor\" "
+                        + "installerPackage=\"com.installer\" />\n"
+                        + "</config>";
+        final File allowedVendorFolder = createTempSubfolder("folder");
+        createTempFile(allowedVendorFolder, "vendor-apex-allowlist.xml", allowedVendorContents);
+        readPermissions(allowedVendorFolder, /* Grant all permission flags */ ~0);
+
+        // Finally, prune non-vendor allowlists.
+        // There is no guarantee in which order the above reads will be done, however pruning
+        // will always happen last.
+        mSysConfig.pruneVendorApexPrivappAllowlists();
+
+        assertThat(mSysConfig.getApexPrivAppPermissions("com.android.non_vendor",
+                "com.android.apk_in_non_vendor_apex"))
+            .containsExactly("android.permission.FOO");
+        assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.non_vendor",
+                "com.android.apk_in_non_vendor_apex"))
+            .containsExactly("android.permission.BAR");
+        assertThat(mSysConfig.getApexPrivAppPermissions("com.android.vendor",
+                "com.android.apk_in_vendor_apex"))
+            .isNull();
+        assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.vendor",
+                "com.android.apk_in_vendor_apex"))
+            .isNull();
+    }
+
     /**
      * Tests that readPermissions works correctly for a library with on-bootclasspath-before
      * and on-bootclasspath-since.
@@ -492,6 +580,25 @@
     }
 
     /**
+     * Create an {@link XmlPullParser} for {@param permissionFile} and begin parsing it until
+     * reaching the root tag.
+     */
+    private XmlPullParser readXmlUntilStartTag(File permissionFile)
+            throws IOException, XmlPullParserException {
+        FileReader permReader = new FileReader(permissionFile);
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(permReader);
+        int type;
+        do {
+            type = parser.next();
+        } while (type != parser.START_TAG && type != parser.END_DOCUMENT);
+        if (type != parser.START_TAG) {
+            throw new XmlPullParserException("No start tag found");
+        }
+        return parser;
+    }
+
+    /**
      * Creates folderName/fileName in the mTemporaryFolder and fills it with the contents.
      *
      * @param folderName subdirectory of mTemporaryFolder to put the file, creating if needed
@@ -500,7 +607,7 @@
     private File createTempSubfolder(String folderName)
             throws IOException {
         File folder = new File(mTemporaryFolder.getRoot(), folderName);
-        folder.mkdir();
+        folder.mkdirs();
         return folder;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
index 5e9e16a..1a146f6 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/DeviceVibrationEffectAdapterTest.java
@@ -18,7 +18,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
+import android.content.pm.PackageManagerInternal;
 import android.hardware.vibrator.IVibrator;
 import android.os.Handler;
 import android.os.VibrationEffect;
@@ -33,8 +36,14 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.server.LocalServices;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 
 import java.util.Arrays;
 import java.util.stream.IntStream;
@@ -59,10 +68,19 @@
             new VibratorInfo.FrequencyProfile(TEST_RESONANT_FREQUENCY, TEST_MIN_FREQUENCY,
                     TEST_FREQUENCY_RESOLUTION, TEST_AMPLITUDE_MAP);
 
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock private PackageManagerInternal mPackageManagerInternalMock;
+
     private DeviceVibrationEffectAdapter mAdapter;
 
     @Before
     public void setUp() throws Exception {
+        when(mPackageManagerInternalMock.getSystemUiServiceComponent())
+                .thenReturn(new ComponentName("", ""));
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
+        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
+
         VibrationSettings vibrationSettings = new VibrationSettings(
                 InstrumentationRegistry.getContext(), new Handler(new TestLooper().getLooper()));
         mAdapter = new DeviceVibrationEffectAdapter(vibrationSettings);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java b/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
index e88e988..fa3fcd9 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/FakeVibratorControllerProvider.java
@@ -34,6 +34,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 
 /**
  * Provides {@link VibratorController} with controlled vibrator hardware capabilities and
@@ -43,8 +44,8 @@
     private static final int EFFECT_DURATION = 20;
 
     private final Map<Long, PrebakedSegment> mEnabledAlwaysOnEffects = new HashMap<>();
-    private final List<VibrationEffectSegment> mEffectSegments = new ArrayList<>();
-    private final List<Integer> mBraking = new ArrayList<>();
+    private final Map<Long, List<VibrationEffectSegment>> mEffectSegments = new TreeMap<>();
+    private final Map<Long, List<Integer>> mBraking = new HashMap<>();
     private final List<Float> mAmplitudes = new ArrayList<>();
     private final List<Boolean> mExternalControlStates = new ArrayList<>();
     private final Handler mHandler;
@@ -67,6 +68,14 @@
     private float mQFactor = Float.NaN;
     private float[] mMaxAmplitudes;
 
+    void recordEffectSegment(long vibrationId, VibrationEffectSegment segment) {
+        mEffectSegments.computeIfAbsent(vibrationId, k -> new ArrayList<>()).add(segment);
+    }
+
+    void recordBraking(long vibrationId, int braking) {
+        mBraking.computeIfAbsent(vibrationId, k -> new ArrayList<>()).add(braking);
+    }
+
     private final class FakeNativeWrapper extends VibratorController.NativeWrapper {
         public int vibratorId;
         public OnVibrationCompleteListener listener;
@@ -86,7 +95,7 @@
 
         @Override
         public long on(long milliseconds, long vibrationId) {
-            mEffectSegments.add(new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE,
+            recordEffectSegment(vibrationId, new StepSegment(VibrationEffect.DEFAULT_AMPLITUDE,
                     /* frequencyHz= */ 0, (int) milliseconds));
             applyLatency();
             scheduleListener(milliseconds, vibrationId);
@@ -110,7 +119,8 @@
                     || Arrays.binarySearch(mSupportedEffects, (int) effect) < 0) {
                 return 0;
             }
-            mEffectSegments.add(new PrebakedSegment((int) effect, false, (int) strength));
+            recordEffectSegment(vibrationId,
+                    new PrebakedSegment((int) effect, false, (int) strength));
             applyLatency();
             scheduleListener(EFFECT_DURATION, vibrationId);
             return EFFECT_DURATION;
@@ -121,7 +131,7 @@
             long duration = 0;
             for (PrimitiveSegment primitive : effects) {
                 duration += EFFECT_DURATION + primitive.getDelay();
-                mEffectSegments.add(primitive);
+                recordEffectSegment(vibrationId, primitive);
             }
             applyLatency();
             scheduleListener(duration, vibrationId);
@@ -133,9 +143,9 @@
             long duration = 0;
             for (RampSegment primitive : primitives) {
                 duration += primitive.getDuration();
-                mEffectSegments.add(primitive);
+                recordEffectSegment(vibrationId, primitive);
             }
-            mBraking.add(braking);
+            recordBraking(vibrationId, braking);
             applyLatency();
             scheduleListener(duration, vibrationId);
             return duration;
@@ -304,15 +314,35 @@
     }
 
     /** Return the braking values passed to the compose PWLE method. */
-    public List<Integer> getBraking() {
-        return mBraking;
+    public List<Integer> getBraking(long vibrationId) {
+        if (mBraking.containsKey(vibrationId)) {
+            return new ArrayList<>(mBraking.get(vibrationId));
+        } else {
+            return new ArrayList<>();
+        }
     }
 
     /** Return list of {@link VibrationEffectSegment} played by this controller, in order. */
-    public List<VibrationEffectSegment> getEffectSegments() {
-        return new ArrayList<>(mEffectSegments);
+    public List<VibrationEffectSegment> getEffectSegments(long vibrationId) {
+        if (mEffectSegments.containsKey(vibrationId)) {
+            return new ArrayList<>(mEffectSegments.get(vibrationId));
+        } else {
+            return new ArrayList<>();
+        }
     }
 
+    /**
+     * Returns a list of all vibrations' effect segments, for external-use where vibration IDs
+     * aren't exposed.
+     */
+    public List<VibrationEffectSegment> getAllEffectSegments() {
+        // Returns segments in order of vibrationId, which increases over time. TreeMap gives order.
+        ArrayList<VibrationEffectSegment> result = new ArrayList<>();
+        for (List<VibrationEffectSegment> subList : mEffectSegments.values()) {
+            result.addAll(subList);
+        }
+        return result;
+    }
     /** Return list of states set for external control to the fake vibrator hardware. */
     public List<Boolean> getExternalControlStates() {
         return mExternalControlStates;
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
index 8167710..0301e94 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
@@ -31,8 +31,10 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContextWrapper;
+import android.content.pm.PackageManagerInternal;
 import android.os.Handler;
 import android.os.IExternalVibratorService;
 import android.os.PowerManagerInternal;
@@ -76,6 +78,7 @@
     @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
 
     @Mock private PowerManagerInternal mPowerManagerInternalMock;
+    @Mock private PackageManagerInternal mPackageManagerInternalMock;
     @Mock private VibrationConfig mVibrationConfigMock;
 
     private TestLooper mTestLooper;
@@ -90,7 +93,11 @@
 
         ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
         when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
+        when(mPackageManagerInternalMock.getSystemUiServiceComponent())
+                .thenReturn(new ComponentName("", ""));
 
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
+        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
         LocalServices.removeServiceForTest(PowerManagerInternal.class);
         LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
 
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 5d4ffbb..ec16188 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -47,13 +47,16 @@
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContextWrapper;
 import android.content.Intent;
+import android.content.pm.PackageManagerInternal;
 import android.media.AudioManager;
 import android.os.Handler;
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
+import android.os.Process;
 import android.os.UserHandle;
 import android.os.VibrationAttributes;
 import android.os.VibrationEffect;
@@ -87,6 +90,7 @@
 public class VibrationSettingsTest {
 
     private static final int UID = 1;
+    private static final String SYSUI_PACKAGE_NAME = "sysui";
     private static final PowerSaveState NORMAL_POWER_STATE = new PowerSaveState.Builder().build();
     private static final PowerSaveState LOW_POWER_STATE = new PowerSaveState.Builder()
             .setBatterySaverEnabled(true).build();
@@ -104,17 +108,13 @@
             USAGE_TOUCH,
     };
 
-    @Rule
-    public MockitoRule mMockitoRule = MockitoJUnit.rule();
-    @Rule
-    public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
 
-    @Mock
-    private VibrationSettings.OnVibratorSettingsChanged mListenerMock;
-    @Mock
-    private PowerManagerInternal mPowerManagerInternalMock;
-    @Mock
-    private VibrationConfig mVibrationConfigMock;
+    @Mock private VibrationSettings.OnVibratorSettingsChanged mListenerMock;
+    @Mock private PowerManagerInternal mPowerManagerInternalMock;
+    @Mock private PackageManagerInternal mPackageManagerInternalMock;
+    @Mock private VibrationConfig mVibrationConfigMock;
 
     private TestLooper mTestLooper;
     private ContextWrapper mContextSpy;
@@ -129,14 +129,17 @@
 
         ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
         when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
-
         doAnswer(invocation -> {
             mRegisteredPowerModeListener = invocation.getArgument(0);
             return null;
         }).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any());
+        when(mPackageManagerInternalMock.getSystemUiServiceComponent())
+                .thenReturn(new ComponentName(SYSUI_PACKAGE_NAME, ""));
 
         LocalServices.removeServiceForTest(PowerManagerInternal.class);
         LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
+        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
 
         setDefaultIntensity(VIBRATION_INTENSITY_MEDIUM);
         mAudioManager = mContextSpy.getSystemService(AudioManager.class);
@@ -285,7 +288,7 @@
     }
 
     @Test
-    public void shouldIgnoreVibration_withRingerModeSilent_ignoresRingtoneAndTouch() {
+    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);
@@ -293,7 +296,7 @@
         setRingerMode(AudioManager.RINGER_MODE_SILENT);
 
         for (int usage : ALL_USAGES) {
-            if (usage == USAGE_RINGTONE || usage == USAGE_TOUCH) {
+            if (usage == USAGE_RINGTONE || usage == USAGE_NOTIFICATION) {
                 assertVibrationIgnoredForUsage(usage, Vibration.Status.IGNORED_FOR_RINGER_MODE);
             } else {
                 assertVibrationNotIgnoredForUsage(usage);
@@ -302,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);
 
@@ -472,6 +485,55 @@
     }
 
     @Test
+    public void shouldCancelVibrationOnScreenOff_withNonSystemPackageAndUid_returnsAlwaysTrue() {
+        for (int usage : ALL_USAGES) {
+            assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(UID, "some.app", usage));
+        }
+    }
+
+    @Test
+    public void shouldCancelVibrationOnScreenOff_withUidZero_returnsFalseForTouchAndHardware() {
+        for (int usage : ALL_USAGES) {
+            if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
+                    || usage == USAGE_PHYSICAL_EMULATION) {
+                assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
+                        /* uid= */ 0, "", usage));
+            } else {
+                assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
+                        /* uid= */ 0, "", usage));
+            }
+        }
+    }
+
+    @Test
+    public void shouldCancelVibrationOnScreenOff_withSystemUid_returnsFalseForTouchAndHardware() {
+        for (int usage : ALL_USAGES) {
+            if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
+                    || usage == USAGE_PHYSICAL_EMULATION) {
+                assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
+                        Process.SYSTEM_UID, "", usage));
+            } else {
+                assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
+                        Process.SYSTEM_UID, "", usage));
+            }
+        }
+    }
+
+    @Test
+    public void shouldCancelVibrationOnScreenOff_withSysUi_returnsFalseForTouchAndHardware() {
+        for (int usage : ALL_USAGES) {
+            if (usage == USAGE_TOUCH || usage == USAGE_HARDWARE_FEEDBACK
+                    || usage == USAGE_PHYSICAL_EMULATION) {
+                assertFalse(mVibrationSettings.shouldCancelVibrationOnScreenOff(
+                        UID, SYSUI_PACKAGE_NAME, usage));
+            } else {
+                assertTrue(mVibrationSettings.shouldCancelVibrationOnScreenOff(
+                        UID, SYSUI_PACKAGE_NAME, usage));
+            }
+        }
+    }
+
+    @Test
     public void getDefaultIntensity_returnsIntensityFromVibratorConfig() {
         setDefaultIntensity(VIBRATION_INTENSITY_HIGH);
         setUserSetting(Settings.System.ALARM_VIBRATION_INTENSITY, VIBRATION_INTENSITY_OFF);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index 01e306e..704729e 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.same;
+import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.never;
@@ -35,7 +36,9 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManagerInternal;
 import android.hardware.vibrator.Braking;
 import android.hardware.vibrator.IVibrator;
 import android.hardware.vibrator.IVibratorManager;
@@ -61,6 +64,8 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.server.LocalServices;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -75,7 +80,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Predicate;
+import java.util.function.BooleanSupplier;
 import java.util.stream.Collectors;
 
 /**
@@ -94,24 +99,23 @@
     private static final VibrationAttributes ATTRS = new VibrationAttributes.Builder().build();
     private static final int TEST_RAMP_STEP_DURATION = 5;
 
-    @Rule
-    public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
 
-    @Mock
-    private VibrationThread.VibratorManagerHooks mManagerHooks;
-    @Mock
-    private VibratorController.OnVibrationCompleteListener mControllerCallbacks;
-    @Mock
-    private IBinder mVibrationToken;
-    @Mock
-    private VibrationConfig mVibrationConfigMock;
+    @Mock private PackageManagerInternal mPackageManagerInternalMock;
+    @Mock private VibrationThread.VibratorManagerHooks mManagerHooks;
+    @Mock private VibratorController.OnVibrationCompleteListener mControllerCallbacks;
+    @Mock private IBinder mVibrationToken;
+    @Mock private VibrationConfig mVibrationConfigMock;
 
     private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
     private VibrationSettings mVibrationSettings;
     private DeviceVibrationEffectAdapter mEffectAdapter;
-    private PowerManager.WakeLock mWakeLock;
     private TestLooper mTestLooper;
     private TestLooperAutoDispatcher mCustomTestLooperDispatcher;
+    private VibrationThread mThread;
+
+    // Setup from the providers when VibrationThread is initialized.
+    private SparseArray<VibratorController> mControllers;
 
     @Before
     public void setUp() throws Exception {
@@ -120,15 +124,23 @@
         when(mVibrationConfigMock.getDefaultVibrationIntensity(anyInt()))
                 .thenReturn(Vibrator.VIBRATION_INTENSITY_MEDIUM);
         when(mVibrationConfigMock.getRampStepDurationMs()).thenReturn(TEST_RAMP_STEP_DURATION);
+        when(mPackageManagerInternalMock.getSystemUiServiceComponent())
+                .thenReturn(new ComponentName("", ""));
+
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
+        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
 
         Context context = InstrumentationRegistry.getContext();
         mVibrationSettings = new VibrationSettings(context, new Handler(mTestLooper.getLooper()),
                 mVibrationConfigMock);
-        mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
-        mWakeLock = context.getSystemService(
-                PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
 
         mockVibrators(VIBRATOR_ID);
+
+        mEffectAdapter = new DeviceVibrationEffectAdapter(mVibrationSettings);
+        PowerManager.WakeLock wakeLock = context.getSystemService(
+                PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");
+        mThread = new VibrationThread(wakeLock, mManagerHooks);
+        mThread.start();
     }
 
     @After
@@ -144,8 +156,8 @@
         long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.IGNORED_UNSUPPORTED);
@@ -158,8 +170,8 @@
                 .addNext(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .addNext(3, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mControllerCallbacks, never()).onComplete(anyInt(), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.IGNORED_UNSUPPORTED);
@@ -171,17 +183,17 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
     }
 
@@ -190,17 +202,17 @@
             throws Exception {
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10, 100);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
     }
 
@@ -212,17 +224,17 @@
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{5, 5, 5}, new int[]{1, 2, 3}, -1);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(15L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(15)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(1, 2, 3),
                 mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
     }
@@ -236,25 +248,26 @@
         long vibrationId = 1;
         int[] amplitudes = new int[]{1, 2, 3};
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5, 5, 5}, amplitudes, 0);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
         assertTrue(
-                waitUntil(t -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
-                        thread, TEST_TIMEOUT_MILLIS));
+                waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
+                        TEST_TIMEOUT_MILLIS));
         // Vibration still running after 2 cycles.
-        assertTrue(thread.isAlive());
-        assertTrue(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
+        assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
 
-        thread.cancel();
-        waitForCompletion(thread);
+        conductor.notifyCancelled(/* immediate= */ false);
+        waitForCompletion();
+        assertFalse(mThread.isRunningVibrationId(vibrationId));
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), anyLong());
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         List<Float> playedAmplitudes = fakeVibrator.getAmplitudes();
-        assertFalse(fakeVibrator.getEffectSegments().isEmpty());
+        assertFalse(fakeVibrator.getEffectSegments(vibrationId).isEmpty());
         assertFalse(playedAmplitudes.isEmpty());
 
         for (int i = 0; i < playedAmplitudes.size(); i++) {
@@ -272,16 +285,16 @@
         int[] amplitudes = new int[]{1, 2, 3};
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{1, 10, 100}, amplitudes, 0);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> !fakeVibrator.getAmplitudes().isEmpty(), thread,
-                TEST_TIMEOUT_MILLIS));
-        thread.cancel();
-        waitForCompletion(thread);
+        assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
+        conductor.notifyCancelled(/* immediate= */ false);
+        waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
-        assertEquals(Arrays.asList(expectedOneShot(1000)), fakeVibrator.getEffectSegments());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+        assertEquals(Arrays.asList(expectedOneShot(1000)),
+                fakeVibrator.getEffectSegments(vibrationId));
     }
 
     @Test
@@ -294,16 +307,16 @@
         int[] amplitudes = new int[]{1, 2, 3};
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{5000, 500, 50}, amplitudes, 0);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> !fakeVibrator.getAmplitudes().isEmpty(), thread,
-                TEST_TIMEOUT_MILLIS));
-        thread.cancel();
-        waitForCompletion(thread);
+        assertTrue(waitUntil(() -> !fakeVibrator.getAmplitudes().isEmpty(), TEST_TIMEOUT_MILLIS));
+        conductor.notifyCancelled(/* immediate= */ false);
+        waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
-        assertEquals(Arrays.asList(expectedOneShot(5550)), fakeVibrator.getEffectSegments());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+        assertEquals(Arrays.asList(expectedOneShot(5550)),
+                fakeVibrator.getEffectSegments(vibrationId));
     }
 
 
@@ -317,21 +330,22 @@
         int[] amplitudes = new int[]{1, 2};
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{900, 50}, amplitudes, 0);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
-                thread, 1000 + TEST_TIMEOUT_MILLIS));
-        thread.cancel();
-        waitForCompletion(thread);
+        assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2 * amplitudes.length,
+                1000 + TEST_TIMEOUT_MILLIS));
+        conductor.notifyCancelled(/* immediate= */ false);
+        waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
-        assertEquals(2, fakeVibrator.getEffectSegments().size());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+        assertEquals(2, fakeVibrator.getEffectSegments(vibrationId).size());
         // First time turn vibrator ON for minimum of 1s.
-        assertEquals(1000L, fakeVibrator.getEffectSegments().get(0).getDuration());
+        assertEquals(1000L, fakeVibrator.getEffectSegments(vibrationId).get(0).getDuration());
         // Vibrator turns off in the middle of the second execution of first step, turn it back ON
         // for another 1s + remaining of 850ms.
-        assertEquals(1850, fakeVibrator.getEffectSegments().get(1).getDuration(), /* delta= */ 20);
+        assertEquals(1850,
+                fakeVibrator.getEffectSegments(vibrationId).get(1).getDuration(), /* delta= */ 20);
         // Set amplitudes for a cycle {1, 2}, start second loop then turn it back on to same value.
         assertEquals(expectedAmplitudes(1, 2, 1, 1),
                 mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().subList(0, 4));
@@ -348,22 +362,23 @@
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
                 .compose();
-        VibrationThread vibrationThread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> t.getVibrators().get(VIBRATOR_ID).isVibrating(), vibrationThread,
+        assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
-        assertTrue(vibrationThread.isAlive());
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
 
         // Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
         // fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
-        Thread cancellingThread = new Thread(() -> vibrationThread.cancel());
+        Thread cancellingThread =
+                new Thread(() -> conductor.notifyCancelled(/* immediate= */ false));
         cancellingThread.start();
 
-        waitForCompletion(vibrationThread, /* timeout= */ 50);
-        waitForCompletion(cancellingThread);
+        waitForCompletion(/* timeout= */ 50);
+        cancellingThread.join();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(vibrationThread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
     }
 
     @Test
@@ -373,22 +388,23 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{100}, new int[]{100}, 0);
-        VibrationThread vibrationThread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> t.getVibrators().get(VIBRATOR_ID).isVibrating(), vibrationThread,
+        assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
-        assertTrue(vibrationThread.isAlive());
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
 
         // Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
         // fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
-        Thread cancellingThread = new Thread(() -> vibrationThread.cancel());
+        Thread cancellingThread =
+                new Thread(() -> conductor.notifyCancelled(/* immediate= */ false));
         cancellingThread.start();
 
-        waitForCompletion(vibrationThread, /* timeout= */ 50);
-        waitForCompletion(cancellingThread);
+        waitForCompletion(/* timeout= */ 50);
+        cancellingThread.join();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(vibrationThread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
     }
 
     @Test
@@ -397,17 +413,17 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_THUD);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_THUD)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
     }
 
     @Test
@@ -420,17 +436,17 @@
         Vibration vibration = createVibration(vibrationId, CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK)));
         vibration.addFallback(VibrationEffect.EFFECT_CLICK, fallback);
-        VibrationThread thread = startThreadAndDispatcher(vibration);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibration);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
     }
 
@@ -439,14 +455,14 @@
             throws Exception {
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks, never()).noteVibratorOn(eq(UID), anyLong());
         verify(mManagerHooks, never()).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.IGNORED_UNSUPPORTED);
-        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
+        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).isEmpty());
     }
 
     @Test
@@ -459,18 +475,18 @@
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .compose();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(40L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
         assertEquals(Arrays.asList(
                 expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0),
                 expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, 0)),
-                fakeVibrator.getEffectSegments());
+                fakeVibrator.getEffectSegments(vibrationId));
     }
 
     @Test
@@ -479,14 +495,14 @@
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .compose();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks, never()).noteVibratorOn(eq(UID), anyLong());
         verify(mManagerHooks, never()).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks, never()).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.IGNORED_UNSUPPORTED);
-        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
+        assertTrue(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).isEmpty());
     }
 
     @Test
@@ -501,13 +517,13 @@
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_SPIN, 0.8f)
                 .compose();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         // Vibrator compose called twice.
         verify(mControllerCallbacks, times(2)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
-        assertEquals(3, fakeVibrator.getEffectSegments().size());
+        assertEquals(3, fakeVibrator.getEffectSegments(vibrationId).size());
     }
 
     @Test
@@ -528,22 +544,22 @@
                 .addOffDuration(Duration.ofMillis(100))
                 .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .compose();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         // Use first duration the vibrator is turned on since we cannot estimate the clicks.
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(10L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks, times(4)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
         assertEquals(Arrays.asList(
                 expectedOneShot(10),
                 expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0),
                 expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f, 0),
                 expectedPrebaked(VibrationEffect.EFFECT_CLICK),
                 expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(100), mVibratorProviders.get(VIBRATOR_ID).getAmplitudes());
     }
 
@@ -566,14 +582,14 @@
                 .addSustain(Duration.ofMillis(30))
                 .addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
                 .build();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(100L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
         assertEquals(Arrays.asList(
                 expectedRamp(/* amplitude= */ 1, /* frequencyHz= */ 150, /* duration= */ 10),
                 expectedRamp(/* startAmplitude= */ 1, /* endAmplitude= */ 0,
@@ -582,8 +598,8 @@
                 expectedRamp(/* startAmplitude= */ 0.5f, /* endAmplitude= */ 0.6f,
                         /* startFrequencyHz= */ 100, /* endFrequencyHz= */ 200,
                         /* duration= */ 40)),
-                fakeVibrator.getEffectSegments());
-        assertEquals(Arrays.asList(Braking.CLAB), fakeVibrator.getBraking());
+                fakeVibrator.getEffectSegments(vibrationId));
+        assertEquals(Arrays.asList(Braking.CLAB), fakeVibrator.getBraking(vibrationId));
     }
 
     @Test
@@ -604,13 +620,13 @@
                 .addSustain(Duration.ofMillis(30))
                 .addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
                 .build();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         // Vibrator compose called twice.
         verify(mControllerCallbacks, times(2)).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
-        assertEquals(4, fakeVibrator.getEffectSegments().size());
+        assertEquals(4, fakeVibrator.getEffectSegments(vibrationId).size());
     }
 
     @Test
@@ -620,17 +636,16 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> fakeVibrator.getAmplitudes().size() > 2, thread,
-                TEST_TIMEOUT_MILLIS));
+        assertTrue(waitUntil(() -> fakeVibrator.getAmplitudes().size() > 2, TEST_TIMEOUT_MILLIS));
         // Vibration still running after 2 cycles.
-        assertTrue(thread.isAlive());
-        assertTrue(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
+        assertTrue(mControllers.get(VIBRATOR_ID).isVibrating());
 
-        thread.binderDied();
-        waitForCompletion(thread);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        conductor.binderDied();
+        waitForCompletion();
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
     }
@@ -640,8 +655,9 @@
         mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
 
         long vibrationId = 1;
-        waitForCompletion(startThreadAndDispatcher(vibrationId,
-                VibrationEffect.createOneShot(10, 100)));
+        startThreadAndDispatcher(vibrationId,
+                VibrationEffect.createOneShot(10, 100));
+        waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
         verify(mManagerHooks, never()).prepareSyncedVibration(anyLong(), any());
@@ -659,18 +675,18 @@
                 .addVibrator(VIBRATOR_ID, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
                 .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_TICK))
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verify(mControllerCallbacks, never()).onComplete(eq(2), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
 
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_TICK)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
     }
 
     @Test
@@ -683,8 +699,8 @@
         long vibrationId = 1;
         CombinedVibration effect = CombinedVibration.createParallel(
                 VibrationEffect.get(VibrationEffect.EFFECT_CLICK));
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
@@ -692,14 +708,17 @@
         verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
         verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(1).isVibrating());
-        assertFalse(thread.getVibrators().get(2).isVibrating());
-        assertFalse(thread.getVibrators().get(3).isVibrating());
+        assertFalse(mControllers.get(1).isVibrating());
+        assertFalse(mControllers.get(2).isVibrating());
+        assertFalse(mControllers.get(3).isVibrating());
 
         VibrationEffectSegment expected = expectedPrebaked(VibrationEffect.EFFECT_CLICK);
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(1).getEffectSegments());
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(2).getEffectSegments());
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(3).getEffectSegments());
+        assertEquals(Arrays.asList(expected),
+                mVibratorProviders.get(1).getEffectSegments(vibrationId));
+        assertEquals(Arrays.asList(expected),
+                mVibratorProviders.get(2).getEffectSegments(vibrationId));
+        assertEquals(Arrays.asList(expected),
+                mVibratorProviders.get(3).getEffectSegments(vibrationId));
     }
 
     @Test
@@ -721,8 +740,8 @@
                         new long[]{10, 10}, new int[]{1, 2}, -1))
                 .addVibrator(4, composed)
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(20L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
@@ -731,22 +750,22 @@
         verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
         verify(mControllerCallbacks).onComplete(eq(4), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(1).isVibrating());
-        assertFalse(thread.getVibrators().get(2).isVibrating());
-        assertFalse(thread.getVibrators().get(3).isVibrating());
-        assertFalse(thread.getVibrators().get(4).isVibrating());
+        assertFalse(mControllers.get(1).isVibrating());
+        assertFalse(mControllers.get(2).isVibrating());
+        assertFalse(mControllers.get(3).isVibrating());
+        assertFalse(mControllers.get(4).isVibrating());
 
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
-                mVibratorProviders.get(1).getEffectSegments());
+                mVibratorProviders.get(1).getEffectSegments(vibrationId));
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(2).getEffectSegments());
+                mVibratorProviders.get(2).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(100), mVibratorProviders.get(2).getAmplitudes());
         assertEquals(Arrays.asList(expectedOneShot(20)),
-                mVibratorProviders.get(3).getEffectSegments());
+                mVibratorProviders.get(3).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(1, 2), mVibratorProviders.get(3).getAmplitudes());
         assertEquals(Arrays.asList(
                 expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
-                mVibratorProviders.get(4).getEffectSegments());
+                mVibratorProviders.get(4).getEffectSegments(vibrationId));
     }
 
     @Test
@@ -765,9 +784,9 @@
                 .addNext(1, VibrationEffect.createOneShot(10, 100), /* delay= */ 50)
                 .addNext(2, composed, /* delay= */ 50)
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        startThreadAndDispatcher(vibrationId, effect);
 
-        waitForCompletion(thread);
+        waitForCompletion();
         InOrder controllerVerifier = inOrder(mControllerCallbacks);
         controllerVerifier.verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
         controllerVerifier.verify(mControllerCallbacks).onComplete(eq(1), eq(vibrationId));
@@ -782,18 +801,18 @@
         batteryVerifier.verify(mManagerHooks).noteVibratorOff(eq(UID));
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(1).isVibrating());
-        assertFalse(thread.getVibrators().get(2).isVibrating());
-        assertFalse(thread.getVibrators().get(3).isVibrating());
+        assertFalse(mControllers.get(1).isVibrating());
+        assertFalse(mControllers.get(2).isVibrating());
+        assertFalse(mControllers.get(3).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(1).getEffectSegments());
+                mVibratorProviders.get(1).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
         assertEquals(Arrays.asList(
                 expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
-                mVibratorProviders.get(2).getEffectSegments());
+                mVibratorProviders.get(2).getEffectSegments(vibrationId));
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
-                mVibratorProviders.get(3).getEffectSegments());
+                mVibratorProviders.get(3).getEffectSegments(vibrationId));
     }
 
     @Test
@@ -810,13 +829,14 @@
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100)
                 .compose();
         CombinedVibration effect = CombinedVibration.createParallel(composed);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> !mVibratorProviders.get(1).getEffectSegments().isEmpty()
-                        && !mVibratorProviders.get(2).getEffectSegments().isEmpty(), thread,
+        assertTrue(waitUntil(
+                () -> !mVibratorProviders.get(1).getEffectSegments(vibrationId).isEmpty()
+                        && !mVibratorProviders.get(2).getEffectSegments(vibrationId).isEmpty(),
                 TEST_TIMEOUT_MILLIS));
-        thread.syncedVibrationComplete();
-        waitForCompletion(thread);
+        conductor.notifySyncedVibrationComplete();
+        waitForCompletion();
 
         long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_COMPOSE;
         verify(mManagerHooks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
@@ -826,8 +846,10 @@
 
         VibrationEffectSegment expected = expectedPrimitive(
                 VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100);
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(1).getEffectSegments());
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(2).getEffectSegments());
+        assertEquals(Arrays.asList(expected),
+                mVibratorProviders.get(1).getEffectSegments(vibrationId));
+        assertEquals(Arrays.asList(expected),
+                mVibratorProviders.get(2).getEffectSegments(vibrationId));
     }
 
     @Test
@@ -849,8 +871,8 @@
                 .addVibrator(3, VibrationEffect.createWaveform(new long[]{10}, new int[]{100}, -1))
                 .addVibrator(4, composed)
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         long expectedCap = IVibratorManager.CAP_SYNC
                 | IVibratorManager.CAP_PREPARE_ON
@@ -878,8 +900,8 @@
                 .addVibrator(1, VibrationEffect.createOneShot(10, 100))
                 .addVibrator(2, VibrationEffect.createWaveform(new long[]{5}, new int[]{200}, -1))
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         long expectedCap = IVibratorManager.CAP_SYNC | IVibratorManager.CAP_PREPARE_ON;
         verify(mManagerHooks).prepareSyncedVibration(eq(expectedCap), eq(vibratorIds));
@@ -887,10 +909,10 @@
         verify(mManagerHooks, never()).cancelSyncedVibration();
 
         assertEquals(Arrays.asList(expectedOneShot(10)),
-                mVibratorProviders.get(1).getEffectSegments());
+                mVibratorProviders.get(1).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(100), mVibratorProviders.get(1).getAmplitudes());
         assertEquals(Arrays.asList(expectedOneShot(5)),
-                mVibratorProviders.get(2).getEffectSegments());
+                mVibratorProviders.get(2).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(200), mVibratorProviders.get(2).getAmplitudes());
     }
 
@@ -907,8 +929,8 @@
                 .addVibrator(1, VibrationEffect.createOneShot(10, 100))
                 .addVibrator(2, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         long expectedCap = IVibratorManager.CAP_SYNC
                 | IVibratorManager.CAP_PREPARE_ON
@@ -937,16 +959,16 @@
                 .addVibrator(3, VibrationEffect.createWaveform(
                         new long[]{60}, new int[]{6}, -1))
                 .combine();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        startThreadAndDispatcher(vibrationId, effect);
 
         // All vibrators are turned on in parallel.
         assertTrue(waitUntil(
-                t -> t.getVibrators().get(1).isVibrating()
-                        && t.getVibrators().get(2).isVibrating()
-                        && t.getVibrators().get(3).isVibrating(),
-                thread, TEST_TIMEOUT_MILLIS));
+                () -> mControllers.get(1).isVibrating()
+                        && mControllers.get(2).isVibrating()
+                        && mControllers.get(3).isVibrating(),
+                TEST_TIMEOUT_MILLIS));
 
-        waitForCompletion(thread);
+        waitForCompletion();
 
         verify(mManagerHooks).noteVibratorOn(eq(UID), eq(80L));
         verify(mManagerHooks).noteVibratorOff(eq(UID));
@@ -954,16 +976,16 @@
         verify(mControllerCallbacks).onComplete(eq(2), eq(vibrationId));
         verify(mControllerCallbacks).onComplete(eq(3), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
-        assertFalse(thread.getVibrators().get(1).isVibrating());
-        assertFalse(thread.getVibrators().get(2).isVibrating());
-        assertFalse(thread.getVibrators().get(3).isVibrating());
+        assertFalse(mControllers.get(1).isVibrating());
+        assertFalse(mControllers.get(2).isVibrating());
+        assertFalse(mControllers.get(3).isVibrating());
 
         assertEquals(Arrays.asList(expectedOneShot(25)),
-                mVibratorProviders.get(1).getEffectSegments());
+                mVibratorProviders.get(1).getEffectSegments(vibrationId));
         assertEquals(Arrays.asList(expectedOneShot(80)),
-                mVibratorProviders.get(2).getEffectSegments());
+                mVibratorProviders.get(2).getEffectSegments(vibrationId));
         assertEquals(Arrays.asList(expectedOneShot(60)),
-                mVibratorProviders.get(3).getEffectSegments());
+                mVibratorProviders.get(3).getEffectSegments(vibrationId));
         assertEquals(expectedAmplitudes(1, 2, 3), mVibratorProviders.get(1).getAmplitudes());
         assertEquals(expectedAmplitudes(4, 5), mVibratorProviders.get(2).getAmplitudes());
         assertEquals(expectedAmplitudes(6), mVibratorProviders.get(3).getAmplitudes());
@@ -988,10 +1010,10 @@
         VibrationEffect effect = VibrationEffect.createWaveform(timings, amplitudes, -1);
 
         long vibrationId = 1;
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        startThreadAndDispatcher(vibrationId, effect);
         long startTime = SystemClock.elapsedRealtime();
 
-        waitForCompletion(thread, totalDuration + TEST_TIMEOUT_MILLIS);
+        waitForCompletion(totalDuration + TEST_TIMEOUT_MILLIS);
         long delay = Math.abs(SystemClock.elapsedRealtime() - startTime - totalDuration);
 
         // Allow some delay for thread scheduling and callback triggering.
@@ -1012,26 +1034,26 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-        VibrationThread vibrationThread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(
-                t -> !fakeVibrator.getEffectSegments().isEmpty(),
-                vibrationThread, TEST_TIMEOUT_MILLIS));
-        assertTrue(vibrationThread.isAlive());
+        assertTrue(waitUntil(() -> !fakeVibrator.getEffectSegments(vibrationId).isEmpty(),
+                TEST_TIMEOUT_MILLIS));
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
 
         // Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
         // fail at waitForCompletion(cancellingThread).
-        Thread cancellingThread = new Thread(() -> vibrationThread.cancel());
+        Thread cancellingThread = new Thread(
+                () -> conductor.notifyCancelled(/* immediate= */ false));
         cancellingThread.start();
 
         // Cancelling the vibration should be fast and return right away, even if the thread is
         // stuck at the slow call to the vibrator.
-        waitForCompletion(cancellingThread, /* timeout= */ 50);
+        waitForCompletion(/* timeout= */ 50);
 
         // After the vibrator call ends the vibration is cancelled and the vibrator is turned off.
-        waitForCompletion(vibrationThread, /* timeout= */ latency + TEST_TIMEOUT_MILLIS);
+        waitForCompletion(/* timeout= */ latency + TEST_TIMEOUT_MILLIS);
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(vibrationThread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
     }
 
     @Test
@@ -1049,23 +1071,24 @@
                         .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, 100)
                         .compose())
                 .combine();
-        VibrationThread vibrationThread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> t.getVibrators().get(2).isVibrating(), vibrationThread,
+        assertTrue(waitUntil(() -> mControllers.get(2).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
-        assertTrue(vibrationThread.isAlive());
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
 
         // Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
         // fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
-        Thread cancellingThread = new Thread(() -> vibrationThread.cancel());
+        Thread cancellingThread = new Thread(
+                () -> conductor.notifyCancelled(/* immediate= */ false));
         cancellingThread.start();
 
-        waitForCompletion(vibrationThread, /* timeout= */ 50);
-        waitForCompletion(cancellingThread);
+        waitForCompletion(/* timeout= */ 50);
+        cancellingThread.join();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(vibrationThread.getVibrators().get(1).isVibrating());
-        assertFalse(vibrationThread.getVibrators().get(2).isVibrating());
+        assertFalse(mControllers.get(1).isVibrating());
+        assertFalse(mControllers.get(2).isVibrating());
     }
 
     @Test
@@ -1080,44 +1103,45 @@
                         new long[]{100, 100}, new int[]{1, 2}, 0))
                 .addVibrator(2, VibrationEffect.createOneShot(100, 100))
                 .combine();
-        VibrationThread vibrationThread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> t.getVibrators().get(1).isVibrating()
-                        && t.getVibrators().get(2).isVibrating(),
-                vibrationThread, TEST_TIMEOUT_MILLIS));
-        assertTrue(vibrationThread.isAlive());
+        assertTrue(waitUntil(() -> mControllers.get(1).isVibrating()
+                        && mControllers.get(2).isVibrating(),
+                TEST_TIMEOUT_MILLIS));
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
 
         // Run cancel in a separate thread so if VibrationThread.cancel blocks then this test should
         // fail at waitForCompletion(vibrationThread) if the vibration not cancelled immediately.
-        Thread cancellingThread = new Thread(() -> vibrationThread.cancel());
+        Thread cancellingThread =
+                new Thread(() -> conductor.notifyCancelled(/* immediate= */ false));
         cancellingThread.start();
 
-        waitForCompletion(vibrationThread, /* timeout= */ 50);
-        waitForCompletion(cancellingThread);
+        waitForCompletion(/* timeout= */ 50);
+        cancellingThread.join();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(vibrationThread.getVibrators().get(1).isVibrating());
-        assertFalse(vibrationThread.getVibrators().get(2).isVibrating());
+        assertFalse(mControllers.get(1).isVibrating());
+        assertFalse(mControllers.get(2).isVibrating());
     }
 
     @Test
     public void vibrate_binderDied_cancelsVibration() throws Exception {
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(new long[]{5}, new int[]{100}, 0);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
-        assertTrue(waitUntil(t -> t.getVibrators().get(VIBRATOR_ID).isVibrating(), thread,
+        assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
-        assertTrue(thread.isAlive());
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
 
-        thread.binderDied();
-        waitForCompletion(thread);
+        conductor.binderDied();
+        waitForCompletion();
 
-        verify(mVibrationToken).linkToDeath(same(thread), eq(0));
-        verify(mVibrationToken).unlinkToDeath(same(thread), eq(0));
+        verify(mVibrationToken).linkToDeath(same(conductor), eq(0));
+        verify(mVibrationToken).unlinkToDeath(same(conductor), eq(0));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
-        assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments().isEmpty());
-        assertFalse(thread.getVibrators().get(VIBRATOR_ID).isVibrating());
+        assertFalse(mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId).isEmpty());
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
     }
 
     @Test
@@ -1129,15 +1153,15 @@
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createWaveform(
                 new long[]{5, 5, 5}, new int[]{60, 120, 240}, -1);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
 
         // Duration extended for 5 + 5 + 5 + 15.
         assertEquals(Arrays.asList(expectedOneShot(30)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
         assertTrue(amplitudes.size() > 3);
         assertEquals(expectedAmplitudes(60, 120, 240), amplitudes.subList(0, 3));
@@ -1154,28 +1178,28 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10, 200);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
 
         // Vibration completed but vibrator not yet released.
         verify(mManagerHooks, timeout(TEST_TIMEOUT_MILLIS)).onVibrationCompleted(eq(vibrationId),
                 eq(Vibration.Status.FINISHED));
-        verify(mManagerHooks, never()).onVibrationThreadReleased();
+        verify(mManagerHooks, never()).onVibrationThreadReleased(anyLong());
 
         // Thread still running ramp down.
-        assertTrue(thread.isAlive());
+        assertTrue(mThread.isRunningVibrationId(vibrationId));
 
         // Duration extended for 10 + 10000.
         assertEquals(Arrays.asList(expectedOneShot(10_010)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
 
         // Will stop the ramp down right away.
-        thread.cancelImmediately();
-        waitForCompletion(thread);
+        conductor.notifyCancelled(/* immediate= */ true);
+        waitForCompletion();
 
         // Does not cancel already finished vibration, but releases vibrator.
         verify(mManagerHooks, never()).onVibrationCompleted(eq(vibrationId),
                 eq(Vibration.Status.CANCELLED));
-        verify(mManagerHooks).onVibrationThreadReleased();
+        verify(mManagerHooks).onVibrationThreadReleased(vibrationId);
     }
 
     @Test
@@ -1187,17 +1211,17 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.createOneShot(10_000, 240);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        assertTrue(waitUntil(t -> t.getVibrators().get(VIBRATOR_ID).isVibrating(), thread,
+        VibrationStepConductor conductor = startThreadAndDispatcher(vibrationId, effect);
+        assertTrue(waitUntil(() -> mControllers.get(VIBRATOR_ID).isVibrating(),
                 TEST_TIMEOUT_MILLIS));
-        thread.cancel();
-        waitForCompletion(thread);
+        conductor.notifyCancelled(/* immediate= */ false);
+        waitForCompletion();
 
         verifyCallbacksTriggered(vibrationId, Vibration.Status.CANCELLED);
 
         // Duration extended for 10000 + 15.
         assertEquals(Arrays.asList(expectedOneShot(10_015)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         List<Float> amplitudes = mVibratorProviders.get(VIBRATOR_ID).getAmplitudes();
         assertTrue(amplitudes.size() > 1);
         for (int i = 1; i < amplitudes.size(); i++) {
@@ -1214,14 +1238,14 @@
 
         long vibrationId = 1;
         VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
 
         assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
     }
 
@@ -1238,15 +1262,15 @@
         VibrationEffect effect = VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
                 .compose();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
 
         assertEquals(
                 Arrays.asList(expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
-                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments());
+                mVibratorProviders.get(VIBRATOR_ID).getEffectSegments(vibrationId));
         assertTrue(mVibratorProviders.get(VIBRATOR_ID).getAmplitudes().isEmpty());
     }
 
@@ -1267,17 +1291,112 @@
         VibrationEffect effect = VibrationEffect.startWaveform()
                 .addTransition(Duration.ofMillis(1), targetAmplitude(1))
                 .build();
-        VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
-        waitForCompletion(thread);
+        startThreadAndDispatcher(vibrationId, effect);
+        waitForCompletion();
 
         verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId));
         verifyCallbacksTriggered(vibrationId, Vibration.Status.FINISHED);
 
         assertEquals(Arrays.asList(expectedRamp(0, 1, 150, 150, 1)),
-                fakeVibrator.getEffectSegments());
+                fakeVibrator.getEffectSegments(vibrationId));
         assertTrue(fakeVibrator.getAmplitudes().isEmpty());
     }
 
+    @Test
+    public void vibrate_multipleVibrations_withCancel() throws Exception {
+        mVibratorProviders.get(VIBRATOR_ID).setSupportedEffects(
+                VibrationEffect.EFFECT_CLICK, VibrationEffect.EFFECT_TICK);
+        mVibratorProviders.get(VIBRATOR_ID).setSupportedPrimitives(
+                VibrationEffect.Composition.PRIMITIVE_CLICK);
+        mVibratorProviders.get(VIBRATOR_ID).setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL,
+                IVibrator.CAP_COMPOSE_EFFECTS);
+
+        long vibrationId1 = 1;
+        long vibrationId2 = 2;
+        long vibrationId3 = 3;
+        long vibrationId4 = 4;
+        long vibrationId5 = 5;
+
+        // A simple effect, followed by a repeating effect that gets cancelled, followed by another
+        // simple effect.
+        VibrationEffect effect1 = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
+        VibrationEffect effect2 = VibrationEffect.startComposition()
+                .repeatEffectIndefinitely(VibrationEffect.get(VibrationEffect.EFFECT_TICK))
+                .compose();
+        VibrationEffect effect3 = VibrationEffect.startComposition()
+                .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+                .compose();
+        VibrationEffect effect4 = VibrationEffect.createOneShot(8000, 100);
+        VibrationEffect effect5 = VibrationEffect.createOneShot(20, 222);
+
+        startThreadAndDispatcher(vibrationId1, effect1);
+        waitForCompletion();
+        verify(mControllerCallbacks).onComplete(VIBRATOR_ID, vibrationId1);
+        verifyCallbacksTriggered(vibrationId1, Vibration.Status.FINISHED);
+
+        VibrationStepConductor conductor2 = startThreadAndDispatcher(vibrationId2, effect2);
+        // Effect2 won't complete on its own. Cancel it after a couple of repeats.
+        Thread.sleep(150);  // More than two TICKs.
+        conductor2.notifyCancelled(/* immediate= */ false);
+        waitForCompletion();
+
+        startThreadAndDispatcher(vibrationId3, effect3);
+        waitForCompletion();
+
+        // Effect4 is a long oneshot, but it gets cancelled as fast as possible.
+        long start4 = System.currentTimeMillis();
+        VibrationStepConductor conductor4 = startThreadAndDispatcher(vibrationId4, effect4);
+        conductor4.notifyCancelled(/* immediate= */ true);
+        waitForCompletion();
+        long duration4 = System.currentTimeMillis() - start4;
+
+        // Effect5 is to show that things keep going after the immediate cancel.
+        startThreadAndDispatcher(vibrationId5, effect5);
+        waitForCompletion();
+
+        FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(VIBRATOR_ID);
+        assertFalse(mControllers.get(VIBRATOR_ID).isVibrating());
+
+        // Effect1
+        verify(mControllerCallbacks).onComplete(VIBRATOR_ID, vibrationId1);
+        verifyCallbacksTriggered(vibrationId1, Vibration.Status.FINISHED);
+
+        assertEquals(Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK)),
+                fakeVibrator.getEffectSegments(vibrationId1));
+
+        // Effect2: repeating, cancelled.
+        verify(mControllerCallbacks, atLeast(2)).onComplete(VIBRATOR_ID, vibrationId2);
+        verifyCallbacksTriggered(vibrationId2, Vibration.Status.CANCELLED);
+
+        // The exact count of segments might vary, so just check that there's more than 2 and
+        // all elements are the same segment.
+        List<VibrationEffectSegment> actualSegments2 = fakeVibrator.getEffectSegments(vibrationId2);
+        assertTrue(actualSegments2.size() + " > 2", actualSegments2.size() > 2);
+        for (VibrationEffectSegment segment : actualSegments2) {
+            assertEquals(expectedPrebaked(VibrationEffect.EFFECT_TICK), segment);
+        }
+
+        // Effect3
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId3));
+        verifyCallbacksTriggered(vibrationId3, Vibration.Status.FINISHED);
+        assertEquals(Arrays.asList(
+                        expectedPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 0)),
+                fakeVibrator.getEffectSegments(vibrationId3));
+
+        // Effect4: cancelled quickly.
+        verifyCallbacksTriggered(vibrationId4, Vibration.Status.CANCELLED);
+        assertTrue("Tested duration=" + duration4, duration4 < 2000);
+
+        // Effect5: normal oneshot. Don't worry about amplitude, as effect4 may or may not have
+        // started.
+
+        verify(mControllerCallbacks).onComplete(eq(VIBRATOR_ID), eq(vibrationId5));
+        verifyCallbacksTriggered(vibrationId5, Vibration.Status.FINISHED);
+
+        assertEquals(Arrays.asList(expectedOneShot(20)),
+                fakeVibrator.getEffectSegments(vibrationId5));
+    }
+
     private void mockVibrators(int... vibratorIds) {
         for (int vibratorId : vibratorIds) {
             mVibratorProviders.put(vibratorId,
@@ -1285,52 +1404,46 @@
         }
     }
 
-    private VibrationThread startThreadAndDispatcher(long vibrationId, VibrationEffect effect) {
+    private VibrationStepConductor startThreadAndDispatcher(
+            long vibrationId, VibrationEffect effect) {
         return startThreadAndDispatcher(vibrationId, CombinedVibration.createParallel(effect));
     }
 
-    private VibrationThread startThreadAndDispatcher(long vibrationId,
+    private VibrationStepConductor startThreadAndDispatcher(long vibrationId,
             CombinedVibration effect) {
         return startThreadAndDispatcher(createVibration(vibrationId, effect));
     }
 
-    private VibrationThread startThreadAndDispatcher(Vibration vib) {
-        VibrationThread thread = new VibrationThread(vib, mVibrationSettings, mEffectAdapter,
-                createVibratorControllers(), mWakeLock, mManagerHooks);
+    private VibrationStepConductor startThreadAndDispatcher(Vibration vib) {
+        mControllers = createVibratorControllers();
+        VibrationStepConductor conductor = new VibrationStepConductor(vib, mVibrationSettings,
+                mEffectAdapter, mControllers, mManagerHooks);
         doAnswer(answer -> {
-            thread.vibratorComplete(answer.getArgument(0));
+            conductor.notifyVibratorComplete(answer.getArgument(0));
             return null;
         }).when(mControllerCallbacks).onComplete(anyInt(), eq(vib.id));
-        // TestLooper.AutoDispatchThread has a fixed 1s duration. Use a custom auto-dispatcher.
-        mCustomTestLooperDispatcher = new TestLooperAutoDispatcher(mTestLooper);
-        mCustomTestLooperDispatcher.start();
-        thread.start();
-        return thread;
+        assertTrue(mThread.runVibrationOnVibrationThread(conductor));
+        return conductor;
     }
 
-    private boolean waitUntil(Predicate<VibrationThread> predicate, VibrationThread thread,
-            long timeout) throws InterruptedException {
+    private boolean waitUntil(BooleanSupplier predicate, long timeout)
+            throws InterruptedException {
         long timeoutTimestamp = SystemClock.uptimeMillis() + timeout;
         boolean predicateResult = false;
         while (!predicateResult && SystemClock.uptimeMillis() < timeoutTimestamp) {
             Thread.sleep(10);
-            predicateResult = predicate.test(thread);
+            predicateResult = predicate.getAsBoolean();
         }
         return predicateResult;
     }
 
-    private void waitForCompletion(Thread thread) {
-        waitForCompletion(thread, TEST_TIMEOUT_MILLIS);
+    private void waitForCompletion() {
+        waitForCompletion(TEST_TIMEOUT_MILLIS);
     }
 
-    private void waitForCompletion(Thread thread, long timeout) {
-        try {
-            thread.join(timeout);
-        } catch (InterruptedException e) {
-        }
-        assertFalse(thread.isAlive());
-        mCustomTestLooperDispatcher.cancel();
-        mTestLooper.dispatchAll();
+    private void waitForCompletion(long timeout) {
+        mThread.waitForThreadIdle(timeout);
+        mTestLooper.dispatchAll();  // Flush callbacks
     }
 
     private Vibration createVibration(long id, CombinedVibration effect) {
@@ -1343,6 +1456,12 @@
             int id = e.getKey();
             array.put(id, e.getValue().newVibratorController(id, mControllerCallbacks));
         }
+        // Start a looper for the vibrationcontrollers if it's not already running.
+        // TestLooper.AutoDispatchThread has a fixed 1s duration. Use a custom auto-dispatcher.
+        if (mCustomTestLooperDispatcher == null) {
+            mCustomTestLooperDispatcher = new TestLooperAutoDispatcher(mTestLooper);
+            mCustomTestLooperDispatcher.start();
+        }
         return array;
     }
 
@@ -1377,10 +1496,10 @@
 
     private void verifyCallbacksTriggered(long vibrationId, Vibration.Status expectedStatus) {
         verify(mManagerHooks).onVibrationCompleted(eq(vibrationId), eq(expectedStatus));
-        verify(mManagerHooks).onVibrationThreadReleased();
+        verify(mManagerHooks).onVibrationThreadReleased(vibrationId);
     }
 
-    private final class TestLooperAutoDispatcher extends Thread {
+    private static final class TestLooperAutoDispatcher extends Thread {
         private final TestLooper mTestLooper;
         private boolean mCancelled;
 
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 19111e5..92736c5 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -571,27 +571,27 @@
         VibratorManagerService service = createSystemReadyService();
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), RINGTONE_ATTRS);
         // Wait before checking it never played.
-        assertFalse(waitUntil(s -> !fakeVibrator.getEffectSegments().isEmpty(),
+        assertFalse(waitUntil(s -> !fakeVibrator.getAllEffectSegments().isEmpty(),
                 service, /* timeout= */ 50));
 
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
         setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 1);
         service = createSystemReadyService();
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK), RINGTONE_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 1,
                 service, TEST_TIMEOUT_MILLIS));
 
         setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
         setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
         service = createSystemReadyService();
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK), RINGTONE_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 2,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 2,
                 service, TEST_TIMEOUT_MILLIS));
 
         assertEquals(
                 Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_HEAVY_CLICK),
                         expectedPrebaked(VibrationEffect.EFFECT_DOUBLE_CLICK)),
-                mVibratorProviders.get(1).getEffectSegments());
+                mVibratorProviders.get(1).getAllEffectSegments());
     }
 
     @Test
@@ -604,25 +604,25 @@
         mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), HAPTIC_FEEDBACK_ATTRS);
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), RINGTONE_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 1,
                 service, TEST_TIMEOUT_MILLIS));
 
         mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK),
                 /* attrs= */ null);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 2,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 2,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK),
                 NOTIFICATION_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 3,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 3,
                 service, TEST_TIMEOUT_MILLIS));
 
         assertEquals(
                 Arrays.asList(expectedPrebaked(VibrationEffect.EFFECT_CLICK),
                         expectedPrebaked(VibrationEffect.EFFECT_HEAVY_CLICK),
                         expectedPrebaked(VibrationEffect.EFFECT_DOUBLE_CLICK)),
-                mVibratorProviders.get(1).getEffectSegments());
+                mVibratorProviders.get(1).getAllEffectSegments());
     }
 
     @Test
@@ -738,14 +738,14 @@
                 VibrationAttributes.USAGE_UNKNOWN).build());
 
         // VibrationThread will start this vibration async, so wait before checking it started.
-        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
                 HAPTIC_FEEDBACK_ATTRS);
 
         // Wait before checking it never played a second effect.
-        assertFalse(waitUntil(s -> mVibratorProviders.get(1).getEffectSegments().size() > 1,
+        assertFalse(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1,
                 service, /* timeout= */ 50));
 
         // The time estimate is recorded when the vibration starts, repeating vibrations
@@ -767,14 +767,14 @@
                 VibrationAttributes.USAGE_ALARM).build());
 
         // VibrationThread will start this vibration async, so wait before checking it started.
-        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK),
                 HAPTIC_FEEDBACK_ATTRS);
 
         // Wait before checking it never played a second effect.
-        assertFalse(waitUntil(s -> mVibratorProviders.get(1).getEffectSegments().size() > 1,
+        assertFalse(waitUntil(s -> mVibratorProviders.get(1).getAllEffectSegments().size() > 1,
                 service, /* timeout= */ 50));
     }
 
@@ -798,7 +798,7 @@
         verify(mIInputManagerMock).vibrateCombined(eq(1), eq(effect), any());
 
         // VibrationThread will start this vibration async, so wait before checking it never played.
-        assertFalse(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(),
+        assertFalse(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
                 service, /* timeout= */ 50));
     }
 
@@ -863,8 +863,8 @@
         verify(mNativeWrapperMock).triggerSynced(anyLong());
         PrimitiveSegment expected = new PrimitiveSegment(
                 VibrationEffect.Composition.PRIMITIVE_CLICK, 1, 100);
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(1).getEffectSegments());
-        assertEquals(Arrays.asList(expected), mVibratorProviders.get(2).getEffectSegments());
+        assertEquals(Arrays.asList(expected), mVibratorProviders.get(1).getAllEffectSegments());
+        assertEquals(Arrays.asList(expected), mVibratorProviders.get(2).getAllEffectSegments());
 
         // VibrationThread needs some time to react to native callbacks and stop the vibrator.
         assertTrue(waitUntil(s -> !s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
@@ -891,7 +891,7 @@
                         .compose())
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !fakeVibrator1.getEffectSegments().isEmpty(), service,
+        assertTrue(waitUntil(s -> !fakeVibrator1.getAllEffectSegments().isEmpty(), service,
                 TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
@@ -915,7 +915,7 @@
                 .addVibrator(2, VibrationEffect.createOneShot(10, 100))
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !fakeVibrator1.getEffectSegments().isEmpty(), service,
+        assertTrue(waitUntil(s -> !fakeVibrator1.getAllEffectSegments().isEmpty(), service,
                 TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock, never()).prepareSynced(any());
@@ -935,8 +935,8 @@
                 .addVibrator(2, VibrationEffect.createOneShot(10, 100))
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(), service,
-                TEST_TIMEOUT_MILLIS));
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
+                service, TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
         verify(mNativeWrapperMock, never()).triggerSynced(anyLong());
@@ -956,8 +956,8 @@
                 .addVibrator(2, VibrationEffect.createOneShot(10, 100))
                 .combine();
         vibrate(service, effect, ALARM_ATTRS);
-        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getEffectSegments().isEmpty(), service,
-                TEST_TIMEOUT_MILLIS));
+        assertTrue(waitUntil(s -> !mVibratorProviders.get(1).getAllEffectSegments().isEmpty(),
+                service, TEST_TIMEOUT_MILLIS));
 
         verify(mNativeWrapperMock).prepareSynced(eq(new int[]{1, 2}));
         verify(mNativeWrapperMock).triggerSynced(anyLong());
@@ -995,26 +995,26 @@
         vibrate(service, CombinedVibration.startSequential()
                 .addNext(1, VibrationEffect.createOneShot(100, 125))
                 .combine(), NOTIFICATION_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 1,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 1,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
                 .compose(), HAPTIC_FEEDBACK_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 2,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 2,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.startComposition()
                 .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
                 .compose(), ALARM_ATTRS);
-        assertTrue(waitUntil(s -> fakeVibrator.getEffectSegments().size() == 3,
+        assertTrue(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() == 3,
                 service, TEST_TIMEOUT_MILLIS));
 
         vibrate(service, VibrationEffect.createOneShot(100, 125), RINGTONE_ATTRS);
-        assertFalse(waitUntil(s -> fakeVibrator.getEffectSegments().size() > 3,
+        assertFalse(waitUntil(s -> fakeVibrator.getAllEffectSegments().size() > 3,
                 service, TEST_TIMEOUT_MILLIS));
 
-        assertEquals(3, fakeVibrator.getEffectSegments().size());
+        assertEquals(3, fakeVibrator.getAllEffectSegments().size());
 
         // Notification vibrations will be scaled with SCALE_HIGH or none if default is high.
         assertEquals(defaultNotificationIntensity < Vibrator.VIBRATION_INTENSITY_HIGH,
@@ -1022,11 +1022,11 @@
 
         // Haptic feedback vibrations will be scaled with SCALE_LOW or none if default is low.
         assertEquals(defaultTouchIntensity > Vibrator.VIBRATION_INTENSITY_LOW,
-                0.5 > ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(1)).getScale());
+                0.5 > ((PrimitiveSegment) fakeVibrator.getAllEffectSegments().get(1)).getScale());
 
         // Alarm vibration will be scaled with SCALE_NONE.
         assertEquals(1f,
-                ((PrimitiveSegment) fakeVibrator.getEffectSegments().get(2)).getScale(), 1e-5);
+                ((PrimitiveSegment) fakeVibrator.getAllEffectSegments().get(2)).getScale(), 1e-5);
 
         // Ring vibrations have intensity OFF and are not played.
     }
@@ -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/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
index 2794d48..c64ff9e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowOrientationListenerTest.java
@@ -114,7 +114,7 @@
     }
 
     @Test
-    public void testSensorChanged_normalCase2() {
+    public void testOnSensorChanged_normalCase2() {
         mWindowOrientationListener.mOrientationJudge.onSensorChanged(mFakeSensorEvent);
 
         mFakeRotationResolverInternal.callbackWithFailureResult(
@@ -123,6 +123,15 @@
         assertThat(mFinalizedRotation).isEqualTo(DEFAULT_SENSOR_ROTATION);
     }
 
+    @Test
+    public void testOnSensorChanged_rotationResolverServiceIsNull_useSensorResult() {
+        mWindowOrientationListener.mRotationResolverService = null;
+
+        mWindowOrientationListener.mOrientationJudge.onSensorChanged(mFakeSensorEvent);
+
+        assertThat(mFinalizedRotation).isEqualTo(DEFAULT_SENSOR_ROTATION);
+    }
+
     static final class TestableRotationResolver extends RotationResolverInternal {
         @Surface.Rotation
         RotationResolverCallbackInternal mCallback;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 721641a..5458a5b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -174,7 +174,7 @@
         }
 
         verify(mCallback, times(AUTOGROUP_AT_COUNT + 1))
-            .updateAutogroupSummary(anyString(), eq(true));
+            .updateAutogroupSummary(anyInt(), anyString(), eq(true));
 
         int userId = UserHandle.SYSTEM.getIdentifier();
         assertEquals(mGroupHelper.getOngoingGroupCount(
@@ -203,7 +203,7 @@
         mGroupHelper.onNotificationUpdated(notifications.get(0), true);
 
         verify(mCallback, times(AUTOGROUP_AT_COUNT + 2))
-                .updateAutogroupSummary(anyString(), eq(true));
+                .updateAutogroupSummary(anyInt(), anyString(), eq(true));
 
         int userId = UserHandle.SYSTEM.getIdentifier();
         assertEquals(mGroupHelper.getOngoingGroupCount(
@@ -236,7 +236,7 @@
         mGroupHelper.onNotificationUpdated(notifications.get(0), true);
 
         verify(mCallback, times(AUTOGROUP_AT_COUNT + 3))
-                .updateAutogroupSummary(anyString(), eq(true));
+                .updateAutogroupSummary(anyInt(), anyString(), eq(true));
 
         int userId = UserHandle.SYSTEM.getIdentifier();
         assertEquals(mGroupHelper.getOngoingGroupCount(
@@ -263,7 +263,7 @@
         mGroupHelper.onNotificationRemoved(notifications.get(0));
 
         verify(mCallback, times(AUTOGROUP_AT_COUNT + 2))
-                .updateAutogroupSummary(anyString(), eq(true));
+                .updateAutogroupSummary(anyInt(), anyString(), eq(true));
 
         int userId = UserHandle.SYSTEM.getIdentifier();
         assertEquals(mGroupHelper.getOngoingGroupCount(
@@ -291,7 +291,7 @@
         mGroupHelper.onNotificationUpdated(notifications.get(0), true);
 
         verify(mCallback, times(1))
-                .updateAutogroupSummary(anyString(), eq(true));
+                .updateAutogroupSummary(anyInt(), anyString(), eq(true));
 
         int userId = UserHandle.SYSTEM.getIdentifier();
         assertEquals(mGroupHelper.getOngoingGroupCount(
@@ -315,7 +315,7 @@
         }
 
         verify(mCallback, times(1))
-                .updateAutogroupSummary(anyString(), eq(true));
+                .updateAutogroupSummary(anyInt(), anyString(), eq(true));
 
         int userId = UserHandle.SYSTEM.getIdentifier();
         assertEquals(mGroupHelper.getOngoingGroupCount(
@@ -339,7 +339,7 @@
         }
 
         verify(mCallback, times(0))
-                .updateAutogroupSummary(anyString(), eq(true));
+                .updateAutogroupSummary(anyInt(), anyString(), eq(true));
 
         int userId = UserHandle.SYSTEM.getIdentifier();
         assertEquals(mGroupHelper.getOngoingGroupCount(userId, pkg, AUTOGROUP_KEY), 0);
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 018a916..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;
@@ -420,6 +421,11 @@
                     return getApplicationInfo((String) args[0], mUid);
                 });
         when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
+        when(mPackageManagerInternal.isSameApp(anyString(), anyInt(), anyInt())).thenAnswer(
+                (Answer<Boolean>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (int) args[1] == mUid;
+                });
         final LightsManager mockLightsManager = mock(LightsManager.class);
         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class));
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
@@ -427,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});
 
@@ -966,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,
@@ -980,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 =
@@ -996,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);
@@ -2702,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);
@@ -2717,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
@@ -2734,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 5a6ca6d..2ba587d 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java
@@ -316,6 +316,11 @@
                     return getApplicationInfo((String) args[0], mUid);
                 });
         when(mPackageManagerClient.getPackageUidAsUser(any(), anyInt())).thenReturn(mUid);
+        when(mPackageManagerInternal.isSameApp(anyString(), anyInt(), anyInt())).thenAnswer(
+                (Answer<Boolean>) invocation -> {
+                    Object[] args = invocation.getArguments();
+                    return (int) args[1] == mUid;
+                });
         final LightsManager mockLightsManager = mock(LightsManager.class);
         when(mockLightsManager.getLight(anyInt())).thenReturn(mock(LogicalLight.class));
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
@@ -601,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();
 
@@ -613,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..50151bf 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PermissionHelperTest.java
@@ -89,6 +89,10 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mPermissionHelper = new PermissionHelper(mPmi, mPackageManager, mPermManager, true);
+        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
@@ -384,6 +388,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/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index 90dac47..57bbe40 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -57,6 +57,7 @@
         "ub-uiautomator",
         "hamcrest-library",
         "platform-compat-test-rules",
+        "CtsSurfaceValidatorLib",
     ],
 
     libs: [
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index c2298d0..2918365 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -43,6 +43,8 @@
     <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
     <uses-permission android:name="android.permission.CAPTURE_BLACKOUT_CONTENT"/>
     <uses-permission android:name="android.permission.WRITE_DEVICE_CONFIG" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 
     <!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
     <application android:debuggable="true"
@@ -78,6 +80,12 @@
                   android:turnScreenOn="true"
                   android:showWhenLocked="true" />
         <activity android:name="com.android.server.wm.ScreenshotTests$ScreenshotActivity" />
+        <activity android:name="android.view.cts.surfacevalidator.CapturedActivity"/>
+
+        <service android:name="android.view.cts.surfacevalidator.LocalMediaProjectionService"
+            android:foregroundServiceType="mediaProjection"
+            android:enabled="true">
+        </service>
     </application>
 
     <instrumentation
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/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index b3d6b3e..40ab8eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -24,6 +24,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
 import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
@@ -54,6 +55,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_CLOSE;
 import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN;
+import static android.view.WindowManager.TRANSIT_PIP;
 import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
@@ -2215,6 +2217,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);
@@ -2623,14 +2638,14 @@
                 .setTask(sourceRecord.getTask()).build();
         secondRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
                 true /* startActivity */, sourceRecord);
-        assertFalse(secondRecord.mSplashScreenStyleEmpty);
+        assertFalse(secondRecord.mSplashScreenStyleSolidColor);
         secondRecord.onStartingWindowDrawn();
 
         final ActivityRecord finalRecord = new ActivityBuilder(mAtm)
                 .setTask(sourceRecord.getTask()).build();
         finalRecord.showStartingWindow(null /* prev */, true /* newTask */, false,
                 true /* startActivity */, secondRecord);
-        assertTrue(finalRecord.mSplashScreenStyleEmpty);
+        assertTrue(finalRecord.mSplashScreenStyleSolidColor);
     }
 
     @Test
@@ -3397,6 +3412,24 @@
         assertFalse(activity.mVisibleRequested);
     }
 
+    @Test
+    public void testShellTransitionTaskWindowingModeChange() {
+        final ActivityRecord activity = createActivityWithTask();
+        final Task task = activity.getTask();
+        task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        assertTrue(activity.isVisible());
+        assertTrue(activity.isVisibleRequested());
+        assertEquals(WINDOWING_MODE_FULLSCREEN, activity.getWindowingMode());
+
+        registerTestTransitionPlayer();
+        task.mTransitionController.requestTransitionIfNeeded(TRANSIT_PIP, task);
+        task.setWindowingMode(WINDOWING_MODE_PINNED);
+
+        // Collect activity in the transition if the Task windowing mode is going to change.
+        assertTrue(activity.inTransition());
+    }
+
     private ICompatCameraControlCallback getCompatCameraControlCallback() {
         return new ICompatCameraControlCallback.Stub() {
             @Override
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 55d6df9..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");
@@ -352,6 +352,6 @@
         spyOn(callback);
         mInterceptor.onActivityLaunched(null, null);
 
-        verify(callback, times(1)).onActivityLaunched(any(), any());
+        verify(callback, times(1)).onActivityLaunched(any(), any(), any());
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 87abc53..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 =
@@ -925,14 +925,10 @@
                 any(), anyBoolean(), anyBoolean(), eq(false));
     }
 
-    private ActivityRecord createSingleTaskActivityOn(Task stack) {
+    private ActivityRecord createSingleTaskActivityOn(Task task) {
         final ComponentName componentName = ComponentName.createRelative(
                 DEFAULT_COMPONENT_PACKAGE_NAME,
                 DEFAULT_COMPONENT_PACKAGE_NAME + ".SingleTaskActivity");
-        final Task task = new TaskBuilder(mSupervisor)
-                .setComponent(componentName)
-                .setParentTaskFragment(stack)
-                .build();
         return new ActivityBuilder(mAtm)
                 .setComponent(componentName)
                 .setLaunchMode(LAUNCH_SINGLE_TASK)
@@ -947,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);
@@ -1080,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];
@@ -1089,7 +1085,7 @@
         starter.setActivityOptions(options.toBundle())
                 .setReason("testWindowingModeOptionsLaunchAdjacent")
                 .setOutActivity(outActivity).execute();
-        assertThat(outActivity[0].inSplitScreenWindowingMode()).isFalse();
+        assertThat(outActivity[0].inMultiWindowMode()).isFalse();
 
         // Move activity to split-screen-primary stack and make sure it has the focus.
         TestSplitOrganizer splitOrg = new TestSplitOrganizer(mAtm, top.getDisplayContent());
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 8ada971..a857190 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -355,7 +355,8 @@
     @Test
     public void testUpdateSleep() {
         doCallRealMethod().when(mWm.mRoot).hasAwakeDisplay();
-        mSupervisor.mGoingToSleepWakeLock = mock(PowerManager.WakeLock.class);
+        mSupervisor.mGoingToSleepWakeLock =
+                mSystemServicesTestRule.createStubbedWakeLock(true /* needVerification */);
         final Task rootHomeTask = mWm.mRoot.getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
         final ActivityRecord homeActivity = new ActivityBuilder(mAtm).setTask(rootHomeTask).build();
         final ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 0d67946..72521fd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -120,7 +120,7 @@
         behind.setState(ActivityRecord.State.STARTED, "test");
         behind.mVisibleRequested = true;
 
-        task.performClearTask("test");
+        task.removeActivities("test", false /* excludingTaskOverlay */);
         assertFalse(mDisplayContent.mAppTransition.isReady());
     }
 
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/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
new file mode 100644
index 0000000..50eefa0
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -0,0 +1,239 @@
+/*
+ * 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 static android.content.res.Configuration.ORIENTATION_PORTRAIT;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
+import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.never;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.display.VirtualDisplay;
+import android.os.Binder;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
+import android.view.ContentRecordingSession;
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link ContentRecorder} class.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:ContentRecorderTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class ContentRecorderTests extends WindowTestsBase {
+    private static final IBinder TEST_TOKEN = new RecordingTestToken();
+    private final ContentRecordingSession mDefaultSession =
+            ContentRecordingSession.createDisplaySession(TEST_TOKEN);
+    private static Point sSurfaceSize;
+    private ContentRecorder mContentRecorder;
+    private SurfaceControl mRecordedSurface;
+
+    @Before public void setUp() {
+        // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
+        // mirror.
+        setUpDefaultTaskDisplayAreaWindowToken();
+
+        // GIVEN SurfaceControl can successfully mirror the provided surface.
+        sSurfaceSize = new Point(
+                mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(),
+                mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height());
+        mRecordedSurface = surfaceControlMirrors(sSurfaceSize);
+
+        // GIVEN the VirtualDisplay associated with the session (so the display has state ON).
+        VirtualDisplay virtualDisplay = mWm.mDisplayManager.createVirtualDisplay("VirtualDisplay",
+                sSurfaceSize.x, sSurfaceSize.y,
+                DisplayMetrics.DENSITY_140, new Surface(), VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR);
+        final int displayId = virtualDisplay.getDisplay().getDisplayId();
+        mDefaultSession.setDisplayId(displayId);
+
+        mWm.mRoot.onDisplayAdded(displayId);
+        final DisplayContent mVirtualDisplayContent = mWm.mRoot.getDisplayContent(displayId);
+        mContentRecorder = new ContentRecorder(mVirtualDisplayContent);
+        spyOn(mVirtualDisplayContent);
+    }
+
+    @Test
+    public void testIsCurrentlyRecording() {
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+
+        mContentRecorder.updateRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+    }
+
+    @Test
+    public void testUpdateRecording_display() {
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+    }
+
+    @Test
+    public void testUpdateRecording_task() {
+        mDefaultSession.setContentToRecord(RECORD_CONTENT_TASK);
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+    }
+
+    @Test
+    public void testUpdateRecording_wasPaused() {
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+
+        mContentRecorder.pauseRecording();
+        mContentRecorder.updateRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+    }
+
+    @Test
+    public void testUpdateRecording_wasStopped() {
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+
+        mContentRecorder.remove();
+        mContentRecorder.updateRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+    }
+
+    @Test
+    public void testOnConfigurationChanged_neverRecording() {
+        mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT);
+
+        verify(mTransaction, never()).setPosition(eq(mRecordedSurface), anyFloat(), anyFloat());
+        verify(mTransaction, never()).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(),
+                anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testOnConfigurationChanged_resizesSurface() {
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+        mContentRecorder.onConfigurationChanged(ORIENTATION_PORTRAIT);
+
+        verify(mTransaction, atLeastOnce()).setPosition(eq(mRecordedSurface), anyFloat(),
+                anyFloat());
+        verify(mTransaction, atLeastOnce()).setMatrix(eq(mRecordedSurface), anyFloat(), anyFloat(),
+                anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testPauseRecording_pausesRecording() {
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+
+        mContentRecorder.pauseRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+    }
+
+    @Test
+    public void testPauseRecording_neverRecording() {
+        mContentRecorder.pauseRecording();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+    }
+
+    @Test
+    public void testRemove_stopsRecording() {
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+
+        mContentRecorder.remove();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+    }
+
+    @Test
+    public void testRemove_neverRecording() {
+        mContentRecorder.remove();
+        assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+    }
+
+    @Test
+    public void testUpdateMirroredSurface_capturedAreaResized() {
+        mContentRecorder.setContentRecordingSession(mDefaultSession);
+        mContentRecorder.updateRecording();
+
+        // WHEN attempting to mirror on the virtual display, and the captured content is resized.
+        float xScale = 0.7f;
+        float yScale = 2f;
+        Rect displayAreaBounds = new Rect(0, 0, Math.round(sSurfaceSize.x * xScale),
+                Math.round(sSurfaceSize.y * yScale));
+        mContentRecorder.updateMirroredSurface(mTransaction, displayAreaBounds, sSurfaceSize);
+
+        // THEN content in the captured DisplayArea is scaled to fit the surface size.
+        verify(mTransaction, atLeastOnce()).setMatrix(mRecordedSurface, 1.0f / yScale, 0, 0,
+                1.0f / yScale);
+        // THEN captured content is positioned in the centre of the output surface.
+        float scaledWidth = displayAreaBounds.width() / xScale;
+        float xInset = (sSurfaceSize.x - scaledWidth) / 2;
+        verify(mTransaction, atLeastOnce()).setPosition(mRecordedSurface, xInset, 0);
+    }
+
+    private static class RecordingTestToken extends Binder {
+    }
+
+    /**
+     * Creates a WindowToken associated with the default task DisplayArea, in order for that
+     * DisplayArea to be mirrored.
+     */
+    private void setUpDefaultTaskDisplayAreaWindowToken() {
+        // GIVEN the default task display area is represented by the WindowToken.
+        spyOn(mWm.mWindowContextListenerController);
+        doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when(
+                mWm.mWindowContextListenerController).getContainer(any());
+    }
+
+    /**
+     * SurfaceControl successfully creates a mirrored surface of the given size.
+     */
+    private SurfaceControl surfaceControlMirrors(Point surfaceSize) {
+        // Do not set the parent, since the mirrored surface is the root of a new surface hierarchy.
+        SurfaceControl mirroredSurface = new SurfaceControl.Builder()
+                .setName("mirroredSurface")
+                .setBufferSize(surfaceSize.x, surfaceSize.y)
+                .setCallsite("mirrorSurface")
+                .build();
+        doReturn(mirroredSurface).when(() -> SurfaceControl.mirrorSurface(any()));
+        doReturn(surfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize(
+                anyInt());
+        return mirroredSurface;
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
new file mode 100644
index 0000000..7698033d
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecordingControllerTests.java
@@ -0,0 +1,183 @@
+/*
+ * 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 static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.never;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+import android.view.ContentRecordingSession;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link ContentRecordingController} class.
+ *
+ * Build/Install/Run:
+ * atest WmTests:ContentRecordingControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class ContentRecordingControllerTests extends WindowTestsBase {
+    private static final IBinder TEST_TOKEN = new RecordingTestToken();
+    private final ContentRecordingSession mDefaultSession =
+            ContentRecordingSession.createDisplaySession(
+                    TEST_TOKEN);
+
+    @Before
+    public void setup() {
+        spyOn(mDisplayContent);
+        mDefaultSession.setDisplayId(DEFAULT_DISPLAY);
+    }
+
+    @Test
+    public void testGetContentRecordingSessionLocked() {
+        ContentRecordingController controller = new ContentRecordingController();
+        assertThat(controller.getContentRecordingSessionLocked()).isNull();
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_defaultSession() {
+        ContentRecordingController controller = new ContentRecordingController();
+        controller.setContentRecordingSessionLocked(mDefaultSession, mWm);
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        assertThat(resultingSession).isEqualTo(mDefaultSession);
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_invalidDisplayId_notAccepted() {
+        ContentRecordingController controller = new ContentRecordingController();
+        // GIVEN an invalid display session (no display id is set).
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(TEST_TOKEN);
+        // WHEN updating the session.
+        controller.setContentRecordingSessionLocked(session, mWm);
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        // THEN the invalid session was not accepted.
+        assertThat(resultingSession).isNull();
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_invalidToken_notAccepted() {
+        ContentRecordingController controller = new ContentRecordingController();
+        // GIVEN an invalid display session (null token).
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(null);
+        session.setDisplayId(DEFAULT_DISPLAY);
+        // WHEN updating the session.
+        controller.setContentRecordingSessionLocked(session, mWm);
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        // THEN the invalid session was not accepted.
+        assertThat(resultingSession).isNull();
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_newDisplaySession_accepted() {
+        ContentRecordingController controller = new ContentRecordingController();
+        // GIVEN a valid display session.
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(TEST_TOKEN);
+        session.setDisplayId(DEFAULT_DISPLAY);
+        // WHEN updating the session.
+        controller.setContentRecordingSessionLocked(session, mWm);
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        // THEN the valid session was accepted.
+        assertThat(resultingSession).isEqualTo(session);
+        verify(mDisplayContent, atLeastOnce()).setContentRecordingSession(session);
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_updateCurrentDisplaySession_notAccepted() {
+        ContentRecordingController controller = new ContentRecordingController();
+        // GIVEN a valid display session already in place.
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(TEST_TOKEN);
+        session.setDisplayId(DEFAULT_DISPLAY);
+        controller.setContentRecordingSessionLocked(session, mWm);
+        verify(mDisplayContent, atLeastOnce()).setContentRecordingSession(session);
+
+        // WHEN updating the session.
+        ContentRecordingSession sessionUpdate = ContentRecordingSession.createDisplaySession(
+                new RecordingTestToken());
+        sessionUpdate.setDisplayId(DEFAULT_DISPLAY);
+        controller.setContentRecordingSessionLocked(sessionUpdate, mWm);
+
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        // THEN the session was not accepted.
+        assertThat(resultingSession).isEqualTo(session);
+        verify(mDisplayContent, never()).setContentRecordingSession(sessionUpdate);
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_disableCurrentDisplaySession_accepted() {
+        ContentRecordingController controller = new ContentRecordingController();
+        // GIVEN a valid display session already in place.
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(TEST_TOKEN);
+        session.setDisplayId(DEFAULT_DISPLAY);
+        controller.setContentRecordingSessionLocked(session, mWm);
+        verify(mDisplayContent, atLeastOnce()).setContentRecordingSession(session);
+
+        // WHEN updating the session.
+        ContentRecordingSession sessionUpdate = null;
+        controller.setContentRecordingSessionLocked(sessionUpdate, mWm);
+
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        // THEN the valid session was accepted.
+        assertThat(resultingSession).isEqualTo(sessionUpdate);
+        // Do not need to update the display content, since it will handle stopping the session
+        // via state change callbacks.
+    }
+
+    @Test
+    public void testSetContentRecordingSessionLocked_takeOverCurrentDisplaySession_accepted() {
+        ContentRecordingController controller = new ContentRecordingController();
+        // GIVEN a valid display session already in place.
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(TEST_TOKEN);
+        session.setDisplayId(DEFAULT_DISPLAY);
+        controller.setContentRecordingSessionLocked(session, mWm);
+        verify(mDisplayContent, atLeastOnce()).setContentRecordingSession(session);
+
+        // WHEN updating the session.
+        final DisplayContent virtualDisplay = new TestDisplayContent.Builder(mAtm,
+                mDisplayInfo).build();
+        ContentRecordingSession sessionUpdate = ContentRecordingSession.createDisplaySession(
+                TEST_TOKEN);
+        sessionUpdate.setDisplayId(virtualDisplay.getDisplayId());
+        controller.setContentRecordingSessionLocked(sessionUpdate, mWm);
+
+        ContentRecordingSession resultingSession = controller.getContentRecordingSessionLocked();
+        // THEN the valid session was accepted.
+        assertThat(resultingSession).isEqualTo(sessionUpdate);
+        verify(virtualDisplay).setContentRecordingSession(sessionUpdate);
+        // THEN the recording was paused on the prior display.
+        verify(mDisplayContent).pauseRecording();
+
+    }
+
+    private static class RecordingTestToken extends Binder {
+    }
+}
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 9f7130e..8e990f7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -68,18 +68,15 @@
 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.mock;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.same;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
-import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
 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;
@@ -98,7 +95,6 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doCallRealMethod;
@@ -111,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;
@@ -120,6 +117,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
+import android.view.ContentRecordingSession;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -150,8 +148,6 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1117,7 +1113,7 @@
 
         app.removeImmediately();
 
-        assertNull(dc.getImeTarget(IME_TARGET_INPUT));
+        assertNull(dc.getImeInputTarget());
         assertNull(dc.computeImeControlTarget());
     }
 
@@ -1126,19 +1122,19 @@
         final DisplayContent dc = createNewDisplay();
         dc.setRemoteInsetsController(createDisplayWindowInsetsController());
         dc.setImeInputTarget(createWindow(null, TYPE_BASE_APPLICATION, "app"));
-        dc.setImeLayeringTarget(dc.getImeTarget(IME_TARGET_INPUT).getWindow());
-        assertEquals(dc.getImeTarget(IME_TARGET_INPUT).getWindow(), dc.computeImeControlTarget());
+        dc.setImeLayeringTarget(dc.getImeInputTarget().getWindowState());
+        assertEquals(dc.getImeInputTarget().getWindowState(), dc.computeImeControlTarget());
     }
 
     @Test
     public void testComputeImeControlTarget_splitscreen() throws Exception {
         final DisplayContent dc = createNewDisplay();
         dc.setImeInputTarget(createWindow(null, TYPE_BASE_APPLICATION, "app"));
-        dc.getImeTarget(IME_TARGET_INPUT).getWindow().setWindowingMode(
+        dc.getImeInputTarget().getWindowState().setWindowingMode(
                 WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW);
-        dc.setImeLayeringTarget(dc.getImeTarget(IME_TARGET_INPUT).getWindow());
+        dc.setImeLayeringTarget(dc.getImeInputTarget().getWindowState());
         dc.setRemoteInsetsController(createDisplayWindowInsetsController());
-        assertNotEquals(dc.getImeTarget(IME_TARGET_INPUT).getWindow(),
+        assertNotEquals(dc.getImeInputTarget().getWindowState(),
                 dc.computeImeControlTarget());
     }
 
@@ -1149,7 +1145,7 @@
         doReturn(false).when(mAppWindow.mActivityRecord).matchParentBounds();
         mDisplayContent.setImeInputTarget(mAppWindow);
         mDisplayContent.setImeLayeringTarget(
-                mDisplayContent.getImeTarget(IME_TARGET_INPUT).getWindow());
+            mDisplayContent.getImeInputTarget().getWindowState());
         mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController());
         assertEquals(mAppWindow, mDisplayContent.computeImeControlTarget());
     }
@@ -1374,7 +1370,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.
@@ -1447,6 +1445,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));
 
@@ -1915,7 +1914,7 @@
         final WindowState nextImeTargetApp = createWindow(null /* parent */,
                 TYPE_BASE_APPLICATION, "nextImeTargetApp");
         spyOn(child1);
-        doReturn(true).when(child1).inSplitScreenWindowingMode();
+        doReturn(false).when(mDisplayContent).shouldImeAttachedToApp();
         mDisplayContent.setImeLayeringTarget(child1);
 
         spyOn(nextImeTargetApp);
@@ -1927,7 +1926,7 @@
         child1.removeImmediately();
 
         verify(mDisplayContent).computeImeTarget(true);
-        assertNull(mDisplayContent.getImeTarget(IME_TARGET_INPUT));
+        assertNull(mDisplayContent.getImeInputTarget());
         verify(child1, never()).needsRelativeLayeringToIme();
     }
 
@@ -1940,12 +1939,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);
@@ -1971,21 +1968,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)
@@ -2281,86 +2275,10 @@
     }
 
     @Test
-    public void testVirtualDisplayContent() {
-        MockitoSession mockSession = mockitoSession()
-                .initMocks(this)
-                .spyStatic(SurfaceControl.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-
-        // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
-        // mirror.
-        final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken();
-
-        // GIVEN SurfaceControl can successfully mirror the provided surface.
-        Point surfaceSize = new Point(
-                mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(),
-                mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height());
-        surfaceControlMirrors(surfaceSize);
-
-        // WHEN creating the DisplayContent for a new virtual display.
-        final DisplayContent virtualDisplay = new TestDisplayContent.Builder(mAtm,
-                mDisplayInfo).build();
-
-        // THEN mirroring is initiated for the default display's DisplayArea.
-        assertThat(virtualDisplay.mTokenToMirror).isEqualTo(tokenToMirror);
-
-        mockSession.finishMocking();
-    }
-
-    @Test
-    public void testVirtualDisplayContent_capturedAreaResized() {
-        MockitoSession mockSession = mockitoSession()
-                .initMocks(this)
-                .spyStatic(SurfaceControl.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-
-        // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
-        // mirror.
-        final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken();
-
-        // GIVEN SurfaceControl can successfully mirror the provided surface.
-        Point surfaceSize = new Point(
-                mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(),
-                mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height());
-        SurfaceControl mirroredSurface = surfaceControlMirrors(surfaceSize);
-
-        // WHEN creating the DisplayContent for a new virtual display.
-        final DisplayContent virtualDisplay = new TestDisplayContent.Builder(mAtm,
-                mDisplayInfo).build();
-
-        // THEN mirroring is initiated for the default display's DisplayArea.
-        assertThat(virtualDisplay.mTokenToMirror).isEqualTo(tokenToMirror);
-
-        float xScale = 0.7f;
-        float yScale = 2f;
-        Rect displayAreaBounds = new Rect(0, 0, Math.round(surfaceSize.x * xScale),
-                Math.round(surfaceSize.y * yScale));
-        virtualDisplay.updateMirroredSurface(mTransaction, displayAreaBounds, surfaceSize);
-
-        // THEN content in the captured DisplayArea is scaled to fit the surface size.
-        verify(mTransaction, atLeastOnce()).setMatrix(mirroredSurface, 1.0f / yScale, 0, 0,
-                1.0f / yScale);
-        // THEN captured content is positioned in the centre of the output surface.
-        float scaledWidth = displayAreaBounds.width() / xScale;
-        float xInset = (surfaceSize.x - scaledWidth) / 2;
-        verify(mTransaction, atLeastOnce()).setPosition(mirroredSurface, xInset, 0);
-
-        mockSession.finishMocking();
-    }
-
-    @Test
     public void testVirtualDisplayContent_withoutSurface() {
-        MockitoSession mockSession = mockitoSession()
-                .initMocks(this)
-                .spyStatic(SurfaceControl.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-
         // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
         // mirror.
-        setUpDefaultTaskDisplayAreaWindowToken();
+        final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken();
 
         // GIVEN SurfaceControl does not mirror a null surface.
         Point surfaceSize = new Point(
@@ -2374,22 +2292,20 @@
 
         // WHEN getting the DisplayContent for the new virtual display.
         DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId);
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
+                tokenToMirror);
+        session.setDisplayId(displayId);
+        mWm.setContentRecordingSession(session);
+        actualDC.updateRecording();
 
         // THEN mirroring is not started, since a null surface indicates the VirtualDisplay is off.
-        assertThat(actualDC.mTokenToMirror).isNull();
+        assertThat(actualDC.isCurrentlyRecording()).isFalse();
 
         display.release();
-        mockSession.finishMocking();
     }
 
     @Test
     public void testVirtualDisplayContent_withSurface() {
-        MockitoSession mockSession = mockitoSession()
-                .initMocks(this)
-                .spyStatic(SurfaceControl.class)
-                .strictness(Strictness.LENIENT)
-                .startMocking();
-
         // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
         // mirror.
         final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken();
@@ -2403,44 +2319,25 @@
         // GIVEN a new VirtualDisplay with an associated surface.
         final VirtualDisplay display = createVirtualDisplay(surfaceSize, new Surface());
         final int displayId = display.getDisplay().getDisplayId();
+
+        // GIVEN a session for this display.
+        ContentRecordingSession session = ContentRecordingSession.createDisplaySession(
+                tokenToMirror);
+        session.setDisplayId(displayId);
+        mWm.setContentRecordingSession(session);
         mWm.mRoot.onDisplayAdded(displayId);
 
         // WHEN getting the DisplayContent for the new virtual display.
         DisplayContent actualDC = mWm.mRoot.getDisplayContent(displayId);
+        actualDC.updateRecording();
 
         // THEN mirroring is initiated for the default display's DisplayArea.
-        assertThat(actualDC.mTokenToMirror).isEqualTo(tokenToMirror);
+        assertThat(actualDC.isCurrentlyRecording()).isTrue();
 
         display.release();
-        mockSession.finishMocking();
     }
 
-    @Test
-    public void testKeepClearAreasMultipleWindows() {
-        final WindowState w1 = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent, "w1");
-        final Rect rect1 = new Rect(0, 0, 10, 10);
-        w1.setKeepClearAreas(Arrays.asList(rect1));
-        final WindowState w2 = createWindow(null, TYPE_NOTIFICATION_SHADE, mDisplayContent, "w2");
-        final Rect rect2 = new Rect(10, 10, 20, 20);
-        w2.setKeepClearAreas(Arrays.asList(rect2));
-
-        // No keep clear areas on display, because the windows are not visible
-        assertEquals(Arrays.asList(), mDisplayContent.getKeepClearAreas());
-
-        makeWindowVisible(w1);
-
-        // The returned keep-clear areas contain the areas just from the visible window
-        assertEquals(new ArraySet(Arrays.asList(rect1)),
-                     new ArraySet(mDisplayContent.getKeepClearAreas()));
-
-        makeWindowVisible(w1, w2);
-
-        // The returned keep-clear areas contain the areas from all visible windows
-        assertEquals(new ArraySet(Arrays.asList(rect1, rect2)),
-                     new ArraySet(mDisplayContent.getKeepClearAreas()));
-    }
-
-    private class TestToken extends Binder {
+    private static class MirroringTestToken extends Binder {
     }
 
     /**
@@ -2450,10 +2347,7 @@
     private IBinder setUpDefaultTaskDisplayAreaWindowToken() {
         // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to
         // mirror.
-        final IBinder tokenToMirror = new TestToken();
-        doReturn(tokenToMirror).when(mWm.mDisplayManagerInternal).getWindowTokenClientToMirror(
-                anyInt());
-
+        final IBinder tokenToMirror = new MirroringTestToken();
         // GIVEN the default task display area is represented by the WindowToken.
         spyOn(mWm.mWindowContextListenerController);
         doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when(
@@ -2482,6 +2376,30 @@
                 DisplayMetrics.DENSITY_140, surface, VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR);
     }
 
+    @Test
+    public void testKeepClearAreasMultipleWindows() {
+        final WindowState w1 = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent, "w1");
+        final Rect rect1 = new Rect(0, 0, 10, 10);
+        w1.setKeepClearAreas(Arrays.asList(rect1), Collections.emptyList());
+        final WindowState w2 = createWindow(null, TYPE_NOTIFICATION_SHADE, mDisplayContent, "w2");
+        final Rect rect2 = new Rect(10, 10, 20, 20);
+        w2.setKeepClearAreas(Arrays.asList(rect2), Collections.emptyList());
+
+        // No keep clear areas on display, because the windows are not visible
+        assertEquals(Collections.emptySet(), mDisplayContent.getKeepClearAreas());
+
+        makeWindowVisible(w1);
+
+        // The returned keep-clear areas contain the areas just from the visible window
+        assertEquals(new ArraySet(Arrays.asList(rect1)), mDisplayContent.getKeepClearAreas());
+
+        makeWindowVisible(w1, w2);
+
+        // The returned keep-clear areas contain the areas from all visible windows
+        assertEquals(new ArraySet(Arrays.asList(rect1, rect2)),
+                mDisplayContent.getKeepClearAreas());
+    }
+
     private void removeRootTaskTests(Runnable runnable) {
         final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
         final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index e387615..90a6918 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -30,7 +30,6 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
 import static org.junit.Assert.assertEquals;
@@ -182,12 +181,13 @@
         // Make IME and stay visible during the test.
         mImeWindow.setHasSurface(true);
         getController().getSourceProvider(ITYPE_IME).setWindowContainer(mImeWindow, null, null);
-        getController().onImeControlTargetChanged(mDisplayContent.getImeTarget(IME_TARGET_INPUT));
+        getController().onImeControlTargetChanged(
+                mDisplayContent.getImeInputTarget().getWindowState());
         final InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
         requestedVisibilities.setVisibility(ITYPE_IME, true);
-        mDisplayContent.getImeTarget(IME_TARGET_INPUT).getWindow()
+        mDisplayContent.getImeInputTarget().getWindowState()
                 .setRequestedVisibilities(requestedVisibilities);
-        getController().onInsetsModified(mDisplayContent.getImeTarget(IME_TARGET_INPUT));
+        getController().onInsetsModified(mDisplayContent.getImeInputTarget().getWindowState());
 
         // Send our spy window (app) into the system so that we can detect the invocation.
         final WindowState win = createWindow(null, TYPE_APPLICATION, "app");
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index cc1869e..9fc9489 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -557,7 +557,7 @@
         mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist);
 
         // THEN the task running that package should be stopped
-        verify(tr2).performClearTaskLocked();
+        verify(tr2).performClearTaskForReuse(false /* excludingTaskOverlay*/);
         assertFalse(mLockTaskController.isTaskLocked(tr2));
         // THEN the other task should remain locked
         assertEquals(LOCK_TASK_MODE_LOCKED, mLockTaskController.getLockTaskModeState());
@@ -569,7 +569,7 @@
         mLockTaskController.updateLockTaskPackages(TEST_USER_ID, allowlist);
 
         // THEN the last task should be cleared, and the system should quit LockTask mode
-        verify(tr1).performClearTaskLocked();
+        verify(tr1).performClearTaskForReuse(false /* excludingTaskOverlay*/);
         assertFalse(mLockTaskController.isTaskLocked(tr1));
         assertEquals(LOCK_TASK_MODE_NONE, mLockTaskController.getLockTaskModeState());
         verifyLockTaskStopped(times(1));
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/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
index f007149..972567b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertNull;
 
 import android.app.ActivityOptions;
+import android.os.IBinder;
 import android.platform.test.annotations.Presubmit;
 import android.view.RemoteAnimationAdapter;
 
@@ -45,6 +46,7 @@
 public class PendingRemoteAnimationRegistryTest {
 
     @Mock RemoteAnimationAdapter mAdapter;
+    @Mock IBinder mLaunchCookie;
     private PendingRemoteAnimationRegistry mRegistry;
     private final OffsettableClock mClock = new OffsettableClock.Stopped();
     private TestHandler mHandler;
@@ -65,7 +67,7 @@
 
     @Test
     public void testOverrideActivityOptions() {
-        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
         ActivityOptions opts = ActivityOptions.makeBasic();
         opts = mRegistry.overrideOptionsIfNeeded("com.android.test", opts);
         assertEquals(mAdapter, opts.getRemoteAnimationAdapter());
@@ -73,15 +75,24 @@
 
     @Test
     public void testOverrideActivityOptions_null() {
-        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
         final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null);
         assertNotNull(opts);
         assertEquals(mAdapter, opts.getRemoteAnimationAdapter());
     }
 
     @Test
+    public void testOverrideLaunchCookie() {
+        mRegistry.addPendingAnimation("com.android.test", mAdapter, mLaunchCookie);
+        ActivityOptions opts = ActivityOptions.makeBasic();
+        opts = mRegistry.overrideOptionsIfNeeded("com.android.test", opts);
+        assertNotNull(opts);
+        assertEquals(mLaunchCookie, opts.getLaunchCookie());
+    }
+
+    @Test
     public void testTimeout() {
-        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
         mClock.fastForward(5000);
         mHandler.timeAdvance();
         assertNull(mRegistry.overrideOptionsIfNeeded("com.android.test", null));
@@ -89,10 +100,10 @@
 
     @Test
     public void testTimeout_overridenEntry() {
-        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
         mClock.fastForward(2500);
         mHandler.timeAdvance();
-        mRegistry.addPendingAnimation("com.android.test", mAdapter);
+        mRegistry.addPendingAnimation("com.android.test", mAdapter, null /* launchCookie */);
         mClock.fastForward(1000);
         mHandler.timeAdvance();
         final ActivityOptions opts = mRegistry.overrideOptionsIfNeeded("com.android.test", null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index e091190..021568d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -440,16 +441,26 @@
     public void testCheckRotationAfterCleanup() {
         mWm.setRecentsAnimationController(mController);
         spyOn(mDisplayContent.mFixedRotationTransitionListener);
-        doReturn(true).when(mDisplayContent.mFixedRotationTransitionListener)
-                .isTopFixedOrientationRecentsAnimating();
+        final ActivityRecord recents = mock(ActivityRecord.class);
+        recents.mOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+        doReturn(ORIENTATION_PORTRAIT).when(recents)
+                .getRequestedConfigurationOrientation(anyBoolean());
+        mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recents);
+
         // Rotation update is skipped while the recents animation is running.
-        assertFalse(mDisplayContent.getDisplayRotation().updateOrientation(DisplayContentTests
-                .getRotatedOrientation(mDefaultDisplay), false /* forceUpdate */));
+        final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
+        final int topOrientation = DisplayContentTests.getRotatedOrientation(mDefaultDisplay);
+        assertFalse(displayRotation.updateOrientation(topOrientation, false /* forceUpdate */));
+        assertEquals(ActivityInfo.SCREEN_ORIENTATION_UNSET, displayRotation.getLastOrientation());
         final int prevRotation = mDisplayContent.getRotation();
         mWm.cleanupRecentsAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
-        waitHandlerIdle(mWm.mH);
+
+        // In real case, it is called from RecentsAnimation#finishAnimation -> continueWindowLayout
+        // -> handleAppTransitionReady -> add FINISH_LAYOUT_REDO_CONFIG, and DisplayContent#
+        // applySurfaceChangesTransaction will call updateOrientation for FINISH_LAYOUT_REDO_CONFIG.
+        assertTrue(displayRotation.updateOrientation(topOrientation, false  /* forceUpdate */));
         // The display should be updated to the changed orientation after the animation is finished.
-        assertNotEquals(mDisplayContent.getRotation(), prevRotation);
+        assertNotEquals(displayRotation.getRotation(), prevRotation);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index 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 ba65104..99ba3b8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -938,7 +938,33 @@
     }
 
     @Test
-    public void testGetValidLaunchRootTaskOnDisplayWithCandidateRootTask() {
+    public void testGetLaunchRootTaskOnSecondaryTaskDisplayArea() {
+        // Adding another TaskDisplayArea to the default display.
+        final DisplayContent display = mRootWindowContainer.getDefaultDisplay();
+        final TaskDisplayArea taskDisplayArea = new TaskDisplayArea(display,
+                mWm, "TDA", FEATURE_VENDOR_FIRST);
+        display.addChild(taskDisplayArea, POSITION_BOTTOM);
+
+        // Making sure getting the root task from the preferred TDA
+        LaunchParamsController.LaunchParams launchParams =
+                new LaunchParamsController.LaunchParams();
+        launchParams.mPreferredTaskDisplayArea = taskDisplayArea;
+        Task root = mRootWindowContainer.getOrCreateRootTask(null /* r */, null /* options */,
+                null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
+                0 /* launchParams */);
+        assertEquals(taskDisplayArea, root.getTaskDisplayArea());
+
+        // 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.getOrCreateRootTask(r, null /* options */,
+                null /* candidateTask */, null /* sourceTask */, true /* onTop */, launchParams,
+                0 /* launchParams */);
+        assertEquals(taskDisplayArea, root.getTaskDisplayArea());
+    }
+
+    @Test
+    public void testGetOrCreateRootTaskOnDisplayWithCandidateRootTask() {
         // Create a root task with an activity on secondary display.
         final TestDisplayContent secondaryDisplay = new TestDisplayContent.Builder(mAtm, 300,
                 600).build();
@@ -947,9 +973,9 @@
         final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
 
         // Make sure the root task is valid and can be reused on default display.
-        final Task rootTask = mRootWindowContainer.getValidLaunchRootTaskInTaskDisplayArea(
-                mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task,
-                null /* options */, null /* launchParams */);
+        final Task rootTask = mRootWindowContainer.getDefaultTaskDisplayArea().getOrCreateRootTask(
+                activity, null /* options */, task, null /* sourceTask */, null /* launchParams */,
+                0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, true /* onTop */);
         assertEquals(task, rootTask);
     }
 
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 cac948c..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,17 +17,21 @@
 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;
 import android.view.Surface;
 import android.view.SurfaceControl;
 
+import java.util.concurrent.Executor;
+
 /**
  * Stubbed {@link android.view.SurfaceControl.Transaction} class that can be used when unit
  * testing to avoid calls to native code.
@@ -133,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;
     }
@@ -219,6 +229,12 @@
     }
 
     @Override
+    public SurfaceControl.Transaction addTransactionCommittedListener(Executor executor,
+            SurfaceControl.TransactionCommittedListener listener) {
+        return this;
+    }
+
+    @Override
     public SurfaceControl.Transaction syncInputWindows() {
         return this;
     }
@@ -267,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/SurfaceSyncerContinuousTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerContinuousTest.java
new file mode 100644
index 0000000..1e32500
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerContinuousTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.server.wm.UiDeviceUtils.pressUnlockButton;
+import static android.server.wm.UiDeviceUtils.pressWakeupButton;
+import static android.server.wm.WindowManagerState.getLogicalDisplaySize;
+
+import android.app.KeyguardManager;
+import android.os.PowerManager;
+import android.view.SurfaceControl;
+import android.view.cts.surfacevalidator.CapturedActivity;
+import android.window.SurfaceSyncer;
+
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+import java.util.Objects;
+
+public class SurfaceSyncerContinuousTest {
+    @Rule
+    public TestName mName = new TestName();
+
+    @Rule
+    public ActivityTestRule<CapturedActivity> mActivityRule =
+            new ActivityTestRule<>(CapturedActivity.class);
+
+    public CapturedActivity mCapturedActivity;
+
+    @Before
+    public void setup() {
+        mCapturedActivity = mActivityRule.getActivity();
+        mCapturedActivity.setLogicalDisplaySize(getLogicalDisplaySize());
+
+        final KeyguardManager km = mCapturedActivity.getSystemService(KeyguardManager.class);
+        if (km != null && km.isKeyguardLocked() || !Objects.requireNonNull(
+                mCapturedActivity.getSystemService(PowerManager.class)).isInteractive()) {
+            pressWakeupButton();
+            pressUnlockButton();
+        }
+    }
+
+    @Test
+    public void testSurfaceViewSyncDuringResize() throws Throwable {
+        SurfaceSyncer.setTransactionFactory(SurfaceControl.Transaction::new);
+        mCapturedActivity.verifyTest(new SurfaceSyncerValidatorTestCase(), mName);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java
new file mode 100644
index 0000000..cc28ea6
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.Presubmit;
+import android.view.SurfaceControl;
+import android.window.SurfaceSyncer;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@Presubmit
+public class SurfaceSyncerTest {
+    private SurfaceSyncer mSurfaceSyncer;
+
+    @Before
+    public void setup() {
+        mSurfaceSyncer = new SurfaceSyncer();
+        SurfaceSyncer.setTransactionFactory(StubTransaction::new);
+    }
+
+    @Test
+    public void testSyncOne() throws InterruptedException {
+        final CountDownLatch finishedLatch = new CountDownLatch(1);
+        int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown());
+        Syncable syncable = new Syncable();
+        mSurfaceSyncer.addToSync(startSyncId, syncable);
+        mSurfaceSyncer.markSyncReady(startSyncId);
+
+        syncable.onBufferReady();
+
+        finishedLatch.await(5, TimeUnit.SECONDS);
+        assertEquals(0, finishedLatch.getCount());
+    }
+
+    @Test
+    public void testSyncMultiple() throws InterruptedException {
+        final CountDownLatch finishedLatch = new CountDownLatch(1);
+        int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown());
+        Syncable syncable1 = new Syncable();
+        Syncable syncable2 = new Syncable();
+        Syncable syncable3 = new Syncable();
+
+        mSurfaceSyncer.addToSync(startSyncId, syncable1);
+        mSurfaceSyncer.addToSync(startSyncId, syncable2);
+        mSurfaceSyncer.addToSync(startSyncId, syncable3);
+        mSurfaceSyncer.markSyncReady(startSyncId);
+
+        syncable1.onBufferReady();
+        assertNotEquals(0, finishedLatch.getCount());
+
+        syncable3.onBufferReady();
+        assertNotEquals(0, finishedLatch.getCount());
+
+        syncable2.onBufferReady();
+
+        finishedLatch.await(5, TimeUnit.SECONDS);
+        assertEquals(0, finishedLatch.getCount());
+    }
+
+    @Test
+    public void testInvalidSyncId() {
+        assertFalse(mSurfaceSyncer.addToSync(0, new Syncable()));
+    }
+
+    @Test
+    public void testAddSyncWhenSyncComplete() throws InterruptedException {
+        final CountDownLatch finishedLatch = new CountDownLatch(1);
+        int startSyncId = mSurfaceSyncer.setupSync(transaction -> finishedLatch.countDown());
+
+        Syncable syncable1 = new Syncable();
+        Syncable syncable2 = new Syncable();
+
+        assertTrue(mSurfaceSyncer.addToSync(startSyncId, syncable1));
+        mSurfaceSyncer.markSyncReady(startSyncId);
+        // Adding to a sync that has been completed is also invalid since the sync id has been
+        // cleared.
+        assertFalse(mSurfaceSyncer.addToSync(startSyncId, syncable2));
+    }
+
+    @Test
+    public void testMultipleSyncSets() throws InterruptedException {
+        final CountDownLatch finishedLatch1 = new CountDownLatch(1);
+        final CountDownLatch finishedLatch2 = new CountDownLatch(1);
+        int startSyncId1 = mSurfaceSyncer.setupSync(transaction -> finishedLatch1.countDown());
+        int startSyncId2 = mSurfaceSyncer.setupSync(transaction -> finishedLatch2.countDown());
+
+        Syncable syncable1 = new Syncable();
+        Syncable syncable2 = new Syncable();
+
+        assertTrue(mSurfaceSyncer.addToSync(startSyncId1, syncable1));
+        assertTrue(mSurfaceSyncer.addToSync(startSyncId2, syncable2));
+        mSurfaceSyncer.markSyncReady(startSyncId1);
+        mSurfaceSyncer.markSyncReady(startSyncId2);
+
+        syncable1.onBufferReady();
+
+        finishedLatch1.await(5, TimeUnit.SECONDS);
+        assertEquals(0, finishedLatch1.getCount());
+        assertNotEquals(0, finishedLatch2.getCount());
+
+        syncable2.onBufferReady();
+
+        finishedLatch2.await(5, TimeUnit.SECONDS);
+        assertEquals(0, finishedLatch2.getCount());
+    }
+
+    private static class Syncable implements SurfaceSyncer.SyncTarget {
+        private SurfaceSyncer.SyncBufferCallback mSyncBufferCallback;
+
+        @Override
+        public void onReadyToSync(SurfaceSyncer.SyncBufferCallback syncBufferCallback) {
+            mSyncBufferCallback = syncBufferCallback;
+        }
+
+        void onBufferReady() {
+            SurfaceControl.Transaction t = new StubTransaction();
+            mSyncBufferCallback.onBufferReady(t);
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java
new file mode 100644
index 0000000..d65b80a
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceSyncerValidatorTestCase.java
@@ -0,0 +1,218 @@
+/*
+ * 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 static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+import android.view.cts.surfacevalidator.ISurfaceValidatorTestCase;
+import android.view.cts.surfacevalidator.PixelChecker;
+import android.widget.FrameLayout;
+import android.window.SurfaceSyncer;
+
+import androidx.annotation.NonNull;
+
+/**
+ * A validator class that will create a SurfaceView and then update its size over and over. The code
+ * will request to sync the SurfaceView content with the main window and validate that there was
+ * never an empty area (black color). The test uses {@link SurfaceSyncer} class to gather the
+ * content it wants to synchronize.
+ */
+public class SurfaceSyncerValidatorTestCase implements ISurfaceValidatorTestCase {
+    private static final String TAG = "SurfaceSyncerValidatorTestCase";
+
+    private final Runnable mRunnable = new Runnable() {
+        @Override
+        public void run() {
+            updateSurfaceViewSize();
+            mHandler.postDelayed(this, 100);
+        }
+    };
+
+    private Handler mHandler;
+    private SurfaceView mSurfaceView;
+    private boolean mLastExpanded = true;
+    private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
+
+    private RenderingThread mRenderingThread;
+    private FrameLayout mParent;
+
+    private int mLastSyncId = -1;
+
+    final SurfaceHolder.Callback mCallback = new SurfaceHolder.Callback() {
+        @Override
+        public void surfaceCreated(@NonNull SurfaceHolder holder) {
+            final Canvas canvas = holder.lockCanvas();
+            canvas.drawARGB(255, 100, 100, 100);
+            holder.unlockCanvasAndPost(canvas);
+            Log.d(TAG, "surfaceCreated");
+            mRenderingThread = new RenderingThread(holder);
+            mRenderingThread.start();
+        }
+
+        @Override
+        public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width,
+                int height) {
+            if (mLastSyncId >= 0) {
+                mSurfaceSyncer.addToSync(mLastSyncId, mSurfaceView, frameCallback ->
+                        mRenderingThread.setFrameCallback(frameCallback));
+                mSurfaceSyncer.markSyncReady(mLastSyncId);
+                mLastSyncId = -1;
+            }
+        }
+
+        @Override
+        public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+            mRenderingThread.stopRendering();
+        }
+    };
+
+    @Override
+    public PixelChecker getChecker() {
+        return new PixelChecker(Color.BLACK) {
+            @Override
+            public boolean checkPixels(int matchingPixelCount, int width, int height) {
+                return matchingPixelCount == 0;
+            }
+        };
+    }
+
+    @Override
+    public void start(Context context, FrameLayout parent) {
+        mSurfaceView = new SurfaceView(context);
+        mSurfaceView.getHolder().addCallback(mCallback);
+        mParent = parent;
+
+        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(MATCH_PARENT, 600);
+        parent.addView(mSurfaceView, layoutParams);
+        mHandler = new Handler(Looper.getMainLooper());
+        mHandler.post(mRunnable);
+    }
+
+    @Override
+    public void end() {
+        mHandler.removeCallbacks(mRunnable);
+    }
+
+    public void updateSurfaceViewSize() {
+        if (mRenderingThread == null || mLastSyncId >= 0 || !mRenderingThread.isReadyToSync()) {
+            return;
+        }
+
+        Log.d(TAG, "updateSurfaceViewSize");
+
+        final int height;
+        if (mLastExpanded) {
+            height = 300;
+        } else {
+            height = 600;
+        }
+        mLastExpanded = !mLastExpanded;
+
+        mRenderingThread.pauseRendering();
+        mLastSyncId = mSurfaceSyncer.setupSync(() -> { });
+        mSurfaceSyncer.addToSync(mLastSyncId, mParent);
+
+        ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
+        svParams.height = height;
+        mSurfaceView.setLayoutParams(svParams);
+    }
+
+    private static class RenderingThread extends HandlerThread {
+        private final SurfaceHolder mSurfaceHolder;
+        private SurfaceSyncer.SurfaceViewFrameCallback mFrameCallback;
+        private boolean mPauseRendering;
+        private boolean mComplete;
+
+        int mColorValue = 0;
+        int mColorDelta = 10;
+
+        @Override
+        public void run() {
+            try {
+                while (true) {
+                    sleep(10);
+                    synchronized (this) {
+                        if (mComplete) {
+                            break;
+                        }
+                        if (mPauseRendering) {
+                            continue;
+                        }
+
+                        if (mFrameCallback != null) {
+                            Log.d(TAG, "onFrameStarted");
+                            mFrameCallback.onFrameStarted();
+                        }
+
+                        mColorValue += mColorDelta;
+                        if (mColorValue > 245 || mColorValue < 10) {
+                            mColorDelta *= -1;
+                        }
+
+                        Canvas c = mSurfaceHolder.lockCanvas();
+                        if (c != null) {
+                            c.drawRGB(255, mColorValue, 255 - mColorValue);
+                            mSurfaceHolder.unlockCanvasAndPost(c);
+                        }
+
+                        mFrameCallback = null;
+                    }
+                }
+            } catch (InterruptedException e) {
+            }
+        }
+
+        RenderingThread(SurfaceHolder holder) {
+            super("RenderingThread");
+            mSurfaceHolder = holder;
+        }
+
+        public void pauseRendering() {
+            synchronized (this) {
+                mPauseRendering = true;
+            }
+        }
+
+        private boolean isReadyToSync() {
+            synchronized (this) {
+                return mFrameCallback == null;
+            }
+        }
+        public void setFrameCallback(SurfaceSyncer.SurfaceViewFrameCallback frameCallback) {
+            synchronized (this) {
+                mFrameCallback = frameCallback;
+                mPauseRendering = false;
+            }
+        }
+
+        public void stopRendering() {
+            synchronized (this) {
+                mComplete = true;
+            }
+        }
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 9a33e23..f999e49 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -101,6 +101,10 @@
     static int sNextDisplayId = DEFAULT_DISPLAY + 100;
 
     private static final int[] TEST_USER_PROFILE_IDS = {};
+    /** Use a real static object so there won't be NPE in finalize() after clearInlineMocks(). */
+    private static final PowerManager.WakeLock sWakeLock = getInstrumentation().getContext()
+            .getSystemService(PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    private PowerManager.WakeLock mStubbedWakeLock;
 
     private Description mDescription;
     private Context mContext;
@@ -148,6 +152,7 @@
     private void setUp() {
         mMockitoSession = mockitoSession()
                 .spyStatic(LocalServices.class)
+                .spyStatic(SurfaceControl.class)
                 .mockStatic(LockGuard.class)
                 .mockStatic(Watchdog.class)
                 .strictness(Strictness.LENIENT)
@@ -193,7 +198,8 @@
         // Prevent "WakeLock finalized while still held: SCREEN_FROZEN".
         final PowerManager pm = mock(PowerManager.class);
         doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
-        doReturn(mock(PowerManager.WakeLock.class)).when(pm).newWakeLock(anyInt(), anyString());
+        mStubbedWakeLock = createStubbedWakeLock(false /* needVerification */);
+        doReturn(mStubbedWakeLock).when(pm).newWakeLock(anyInt(), anyString());
 
         // DisplayManagerInternal
         final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class);
@@ -400,6 +406,16 @@
         return mPowerManagerWrapper;
     }
 
+    /** Creates a no-op wakelock object. */
+    PowerManager.WakeLock createStubbedWakeLock(boolean needVerification) {
+        if (needVerification) {
+            return mock(PowerManager.WakeLock.class, Mockito.withSettings()
+                    .spiedInstance(sWakeLock).defaultAnswer(Mockito.RETURNS_DEFAULTS));
+        }
+        return mock(PowerManager.WakeLock.class, Mockito.withSettings()
+                .spiedInstance(sWakeLock).stubOnly());
+    }
+
     void setSurfaceFactory(Supplier<Surface> factory) {
         mSurfaceFactory = factory;
     }
@@ -555,7 +571,7 @@
             // unit test version does not handle launch wake lock
             doNothing().when(this).acquireLaunchWakelock();
 
-            mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
+            mLaunchingActivityWakeLock = mStubbedWakeLock;
 
             initialize();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 168c250..c0759c1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -575,7 +575,7 @@
         final TestDisplayContent fullscreenDisplay = createNewDisplayContent(
                 WINDOWING_MODE_FULLSCREEN);
         final ActivityRecord source = createSourceActivity(fullscreenDisplay);
-        source.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM);
 
         assertEquals(RESULT_CONTINUE,
                 new CalculateRequestBuilder().setSource(source).calculate());
@@ -951,7 +951,7 @@
         final TestDisplayContent fullscreenDisplay = createNewDisplayContent(
                 WINDOWING_MODE_FULLSCREEN);
         final ActivityRecord source = createSourceActivity(fullscreenDisplay);
-        source.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        source.getTask().setWindowingMode(WINDOWING_MODE_FREEFORM);
 
         final ActivityOptions options = ActivityOptions.makeBasic();
         final Rect expected = new Rect(0, 0, 150, 150);
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 d74e1be..c4547f6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -19,6 +19,9 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
@@ -29,16 +32,21 @@
 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;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
@@ -321,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();
             }
@@ -483,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));
@@ -557,11 +646,20 @@
 
     @Test
     public void testAppTransitionWithRotationChange() {
+        final TestTransitionPlayer player = registerTestTransitionPlayer();
+        final boolean useFixedRotation = !player.mController.useShellTransitionsRotation();
+        if (useFixedRotation) {
+            testFixedRotationOpen(player);
+        } else {
+            testShellRotationOpen(player);
+        }
+    }
+
+    private void testShellRotationOpen(TestTransitionPlayer player) {
         final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
         makeWindowVisible(statusBar);
         mDisplayContent.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
         final ActivityRecord app = createActivityRecord(mDisplayContent);
-        final TestTransitionPlayer player = registerTestTransitionPlayer();
         final Transition transition = app.mTransitionController.createTransition(TRANSIT_OPEN);
         app.mTransitionController.requestStartTransition(transition, app.getTask(),
                 null /* remoteTransition */, null /* displayChange */);
@@ -605,6 +703,85 @@
         assertNull(mDisplayContent.getAsyncRotationController());
     }
 
+    private void testFixedRotationOpen(TestTransitionPlayer player) {
+        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
+        makeWindowVisible(statusBar);
+        mDisplayContent.getDisplayPolicy().addWindowLw(statusBar, statusBar.mAttrs);
+        final ActivityRecord app = createActivityRecord(mDisplayContent);
+        final Transition transition = app.mTransitionController.createTransition(TRANSIT_OPEN);
+        app.mTransitionController.requestStartTransition(transition, app.getTask(),
+                null /* remoteTransition */, null /* displayChange */);
+        app.mTransitionController.collectExistenceChange(app.getTask());
+        mDisplayContent.setFixedRotationLaunchingAppUnchecked(app);
+        final AsyncRotationController asyncRotationController =
+                mDisplayContent.getAsyncRotationController();
+        assertNotNull(asyncRotationController);
+        assertTrue(asyncRotationController.shouldFreezeInsetsPosition(statusBar));
+        assertTrue(app.getTask().inTransition());
+
+        player.start();
+        player.finish();
+        app.getTask().clearSyncState();
+
+        // The open transition is finished. Continue to play seamless display change transition,
+        // so the previous async rotation controller should still exist.
+        mDisplayContent.getDisplayRotation().setRotation(mDisplayContent.getRotation() + 1);
+        mDisplayContent.setLastHasContent();
+        mDisplayContent.requestChangeTransitionIfNeeded(1 /* changes */, null /* displayChange */);
+        assertTrue(mDisplayContent.hasTopFixedRotationLaunchingApp());
+        assertNotNull(mDisplayContent.getAsyncRotationController());
+
+        statusBar.setOrientationChanging(true);
+        player.startTransition();
+        // Non-app windows should not be collected.
+        assertFalse(statusBar.mToken.inTransition());
+
+        onRotationTransactionReady(player, mWm.mTransactionFactory.get()).onTransactionCommitted();
+        assertEquals(ROTATION_ANIMATION_SEAMLESS, player.mLastReady.getChange(
+                mDisplayContent.mRemoteToken.toWindowContainerToken()).getRotationAnimation());
+        player.finish();
+
+        // The controller should be cleared if the target windows are drawn.
+        statusBar.finishDrawing(mWm.mTransactionFactory.get());
+        statusBar.setOrientationChanging(false);
+        assertNull(mDisplayContent.getAsyncRotationController());
+    }
+
+    @Test
+    public void testDeferRotationForTransientLaunch() {
+        final TestTransitionPlayer player = registerTestTransitionPlayer();
+        assumeFalse(mDisplayContent.mTransitionController.useShellTransitionsRotation());
+        final ActivityRecord app = new ActivityBuilder(mAtm).setCreateTask(true).build();
+        final ActivityRecord home = new ActivityBuilder(mAtm)
+                .setTask(mDisplayContent.getDefaultTaskDisplayArea().getRootHomeTask())
+                .setScreenOrientation(SCREEN_ORIENTATION_NOSENSOR).setVisible(false).build();
+        final Transition transition = home.mTransitionController.createTransition(TRANSIT_OPEN);
+        final int prevRotation = mDisplayContent.getRotation();
+        transition.setTransientLaunch(home, null /* restoreBelow */);
+        home.mTransitionController.requestStartTransition(transition, home.getTask(),
+                null /* remoteTransition */, null /* displayChange */);
+        transition.collectExistenceChange(home);
+        home.mVisibleRequested = true;
+        mDisplayContent.setFixedRotationLaunchingAppUnchecked(home);
+        doReturn(true).when(home).hasFixedRotationTransform(any());
+        player.startTransition();
+        player.onTransactionReady(mDisplayContent.getSyncTransaction());
+
+        final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
+        spyOn(displayRotation);
+        doReturn(true).when(displayRotation).isWaitingForRemoteRotation();
+        doReturn(prevRotation + 1).when(displayRotation).rotationForOrientation(
+                anyInt() /* orientation */, anyInt() /* lastRotation */);
+        // Rotation update is skipped while the recents animation is running.
+        assertFalse(mDisplayContent.updateRotationUnchecked());
+        assertEquals(SCREEN_ORIENTATION_UNSET, displayRotation.getLastOrientation());
+        // Return to the app without fixed orientation from recents.
+        app.moveFocusableActivityToTop("test");
+        player.finish();
+        // The display should be updated to the changed orientation after the animation is finish.
+        assertNotEquals(mDisplayContent.getRotation(), prevRotation);
+    }
+
     @Test
     public void testIntermediateVisibility() {
         final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
@@ -713,7 +890,7 @@
         closeTransition.collectExistenceChange(activity1);
         closeTransition.collectExistenceChange(task2);
         closeTransition.collectExistenceChange(activity2);
-        closeTransition.setTransientLaunch(activity2);
+        closeTransition.setTransientLaunch(activity2, null /* restoreBelow */);
 
         activity1.mVisibleRequested = false;
         activity2.mVisibleRequested = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index a442de5..5743922 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -1340,6 +1340,41 @@
     }
 
     @Test
+    public void testAddLocalInsetsSourceProvider_sameType_replacesInsets() {
+         /*
+                ___ rootTask ________________________________________
+               |                  |                                  |
+          activity0      navigationBarInsetsProvider1    navigationBarInsetsProvider2
+         */
+        final Task rootTask = createTask(mDisplayContent);
+
+        final ActivityRecord activity0 = createActivityRecord(mDisplayContent,
+                createTaskInRootTask(rootTask, 0 /* userId */));
+        final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
+                TYPE_BASE_APPLICATION);
+        attrs.setTitle("AppWindow0");
+        activity0.addWindow(createWindowState(attrs, activity0));
+
+        Rect navigationBarInsetsRect1 = new Rect(0, 200, 1080, 700);
+        Rect navigationBarInsetsRect2 = new Rect(0, 0, 1080, 200);
+
+        rootTask.addLocalRectInsetsSourceProvider(navigationBarInsetsRect1,
+                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+        activity0.forAllWindows(window -> {
+            assertEquals(navigationBarInsetsRect1,
+                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1).getFrame());
+        }, true);
+
+        rootTask.addLocalRectInsetsSourceProvider(navigationBarInsetsRect2,
+                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+
+        activity0.forAllWindows(window -> {
+            assertEquals(navigationBarInsetsRect2,
+                    window.getInsetsState().peekSource(ITYPE_LOCAL_NAVIGATION_BAR_1).getFrame());
+        }, true);
+    }
+
+    @Test
     public void testRemoveLocalInsetsSourceProvider() {
          /*
                 ___ rootTask _______________________________________________
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 338555e..7d2e9bf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowLayoutTests.java
@@ -30,6 +30,7 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
 
 import static org.junit.Assert.assertEquals;
 
@@ -330,6 +331,23 @@
     }
 
     @Test
+    public void layoutExtendedToDisplayCutout() {
+        addDisplayCutout();
+        final int height = DISPLAY_HEIGHT / 2;
+        mRequestedHeight = UNSPECIFIED_LENGTH;
+        mAttrs.height = height;
+        mAttrs.gravity = Gravity.TOP;
+        mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        mAttrs.setFitInsetsTypes(0);
+        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);
+    }
+
+    @Test
     public void layoutInDisplayCutoutModeDefaultWithInvisibleSystemBars() {
         addDisplayCutout();
         mState.getSource(ITYPE_STATUS_BAR).setVisible(false);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 4d5fb6d..25d7334 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -30,6 +30,7 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
 import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
+import static android.view.InsetsState.ITYPE_LOCAL_NAVIGATION_BAR_1;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -610,6 +611,50 @@
         assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
     }
 
+    @Test
+    public void testAddRectInsetsProvider() {
+        final Task rootTask = createTask(mDisplayContent);
+
+        final Task navigationBarInsetsReceiverTask = createTaskInRootTask(rootTask, 0);
+        navigationBarInsetsReceiverTask.getConfiguration().windowConfiguration.setBounds(new Rect(
+                0, 200, 1080, 700));
+
+        final Rect navigationBarInsetsProviderRect = new Rect(0, 0, 1080, 200);
+
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.addRectInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken
+                        .toWindowContainerToken(), navigationBarInsetsProviderRect,
+                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+
+        assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders
+                .valueAt(0).getSource().getType()).isEqualTo(ITYPE_LOCAL_NAVIGATION_BAR_1);
+    }
+
+    @Test
+    public void testRemoveInsetsProvider() {
+        final Task rootTask = createTask(mDisplayContent);
+
+        final Task navigationBarInsetsReceiverTask = createTaskInRootTask(rootTask, 0);
+        navigationBarInsetsReceiverTask.getConfiguration().windowConfiguration.setBounds(new Rect(
+                0, 200, 1080, 700));
+
+        final Rect navigationBarInsetsProviderRect = new Rect(0, 0, 1080, 200);
+
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.addRectInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken
+                        .toWindowContainerToken(), navigationBarInsetsProviderRect,
+                new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+
+        final WindowContainerTransaction wct2 = new WindowContainerTransaction();
+        wct2.removeInsetsProvider(navigationBarInsetsReceiverTask.mRemoteToken
+                .toWindowContainerToken(), new int[]{ITYPE_LOCAL_NAVIGATION_BAR_1});
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct2);
+
+        assertThat(navigationBarInsetsReceiverTask.mLocalInsetsSourceProviders.size()).isEqualTo(0);
+    }
+
     @UseTestDisplay
     @Test
     public void testTaskInfoCallback() {
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 ef600f0..e4f691b 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;
@@ -61,6 +63,7 @@
 import static org.hamcrest.Matchers.not;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
@@ -80,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;
@@ -97,7 +101,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -490,6 +496,26 @@
     }
 
     @Test
+    public void testApplyWithNextDraw() {
+        final WindowState win = createWindow(null, TYPE_APPLICATION_OVERLAY, "app");
+        final SurfaceControl.Transaction[] handledT = { null };
+        // The normal case that the draw transaction is applied with finishing drawing.
+        win.applyWithNextDraw(t -> handledT[0] = t);
+        assertTrue(win.useBLASTSync());
+        final SurfaceControl.Transaction drawT = new StubTransaction();
+        win.prepareDrawHandlers();
+        assertTrue(win.finishDrawing(drawT));
+        assertEquals(drawT, handledT[0]);
+        assertFalse(win.useBLASTSync());
+
+        // If the window is gone before reporting drawn, the sync state should be cleared.
+        win.applyWithNextDraw(t -> handledT[0] = t);
+        win.destroySurfaceUnchecked();
+        assertFalse(win.useBLASTSync());
+        assertNotEquals(drawT, handledT[0]);
+    }
+
+    @Test
     public void testSeamlesslyRotateWindow() {
         final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
         final SurfaceControl.Transaction t = spy(StubTransaction.class);
@@ -731,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);
@@ -744,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;
@@ -776,15 +808,13 @@
         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
@@ -992,14 +1022,18 @@
         final Rect keepClearArea1 = new Rect(0, 0, 10, 10);
         final Rect keepClearArea2 = new Rect(5, 10, 15, 20);
         final List<Rect> keepClearAreas = Arrays.asList(keepClearArea1, keepClearArea2);
-        window.setKeepClearAreas(keepClearAreas);
+        window.setKeepClearAreas(keepClearAreas, Collections.emptyList());
 
         // Test that the keep-clear rects are stored and returned
-        assertEquals(new ArraySet(keepClearAreas), new ArraySet(window.getKeepClearAreas()));
+        final List<Rect> windowKeepClearAreas = new ArrayList();
+        window.getKeepClearAreas(windowKeepClearAreas, new ArrayList());
+        assertEquals(new ArraySet(keepClearAreas), new ArraySet(windowKeepClearAreas));
 
         // Test that keep-clear rects are overwritten
-        window.setKeepClearAreas(Arrays.asList());
-        assertEquals(0, window.getKeepClearAreas().size());
+        window.setKeepClearAreas(Collections.emptyList(), Collections.emptyList());
+        windowKeepClearAreas.clear();
+        window.getKeepClearAreas(windowKeepClearAreas, new ArrayList());
+        assertEquals(0, windowKeepClearAreas.size());
 
         // Move the window position
         final SurfaceControl.Transaction t = spy(StubTransaction.class);
@@ -1010,13 +1044,60 @@
         assertEquals(new Point(frame.left, frame.top), window.mLastSurfacePosition);
 
         // Test that the returned keep-clear rects are translated to display space
-        window.setKeepClearAreas(keepClearAreas);
+        window.setKeepClearAreas(keepClearAreas, Collections.emptyList());
         Rect expectedArea1 = new Rect(keepClearArea1);
         expectedArea1.offset(frame.left, frame.top);
         Rect expectedArea2 = new Rect(keepClearArea2);
         expectedArea2.offset(frame.left, frame.top);
 
+        windowKeepClearAreas.clear();
+        window.getKeepClearAreas(windowKeepClearAreas, new ArrayList());
         assertEquals(new ArraySet(Arrays.asList(expectedArea1, expectedArea2)),
-                     new ArraySet(window.getKeepClearAreas()));
+                     new ArraySet(windowKeepClearAreas));
+    }
+
+    @Test
+    public void testUnrestrictedKeepClearAreas() {
+        final WindowState window = createWindow(null, TYPE_APPLICATION, "window");
+        makeWindowVisible(window);
+
+        final Rect keepClearArea1 = new Rect(0, 0, 10, 10);
+        final Rect keepClearArea2 = new Rect(5, 10, 15, 20);
+        final List<Rect> keepClearAreas = Arrays.asList(keepClearArea1, keepClearArea2);
+        window.setKeepClearAreas(Collections.emptyList(), keepClearAreas);
+
+        // Test that the keep-clear rects are stored and returned
+        final List<Rect> restrictedKeepClearAreas = new ArrayList();
+        final List<Rect> unrestrictedKeepClearAreas = new ArrayList();
+        window.getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas);
+        assertEquals(Collections.emptySet(), new ArraySet(restrictedKeepClearAreas));
+        assertEquals(new ArraySet(keepClearAreas), new ArraySet(unrestrictedKeepClearAreas));
+
+        // Test that keep-clear rects are overwritten
+        window.setKeepClearAreas(Collections.emptyList(), Collections.emptyList());
+        unrestrictedKeepClearAreas.clear();
+        window.getKeepClearAreas(unrestrictedKeepClearAreas, new ArrayList());
+        assertEquals(0, unrestrictedKeepClearAreas.size());
+
+        // Move the window position
+        final SurfaceControl.Transaction t = spy(StubTransaction.class);
+        window.mSurfaceControl = mock(SurfaceControl.class);
+        final Rect frame = window.getFrame();
+        frame.set(10, 20, 60, 80);
+        window.updateSurfacePosition(t);
+        assertEquals(new Point(frame.left, frame.top), window.mLastSurfacePosition);
+
+        // Test that the returned keep-clear rects are translated to display space
+        window.setKeepClearAreas(Collections.emptyList(), keepClearAreas);
+        Rect expectedArea1 = new Rect(keepClearArea1);
+        expectedArea1.offset(frame.left, frame.top);
+        Rect expectedArea2 = new Rect(keepClearArea2);
+        expectedArea2.offset(frame.left, frame.top);
+
+        unrestrictedKeepClearAreas.clear();
+        window.getKeepClearAreas(restrictedKeepClearAreas, unrestrictedKeepClearAreas);
+        assertEquals(Collections.emptySet(), new ArraySet(restrictedKeepClearAreas));
+        assertEquals(new ArraySet(Arrays.asList(expectedArea1, expectedArea2)),
+                     new ArraySet(unrestrictedKeepClearAreas));
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index 0f223ca..eea3f84 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -293,7 +293,8 @@
     public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() {
         final WindowState appBelowImeTarget = createWindow("appBelowImeTarget");
         final WindowState imeAppTarget = createWindow("imeAppTarget");
-        final WindowState appAboveImeTarget = createWindow("appAboveImeTarget");
+        final WindowState appAboveImeTarget = createWindow(imeAppTarget, TYPE_APPLICATION,
+                "appAboveImeTarget");
 
         mDisplayContent.setImeLayeringTarget(imeAppTarget);
         mDisplayContent.setImeControlTarget(imeAppTarget);
diff --git a/services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java b/services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java
new file mode 100644
index 0000000..bfc1771
--- /dev/null
+++ b/services/usage/java/com/android/server/usage/BroadcastResponseStatsLogger.java
@@ -0,0 +1,221 @@
+/*
+ * 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.usage;
+
+import static android.app.ActivityManager.procStateToString;
+
+import static com.android.server.usage.BroadcastResponseStatsTracker.NOTIFICATION_EVENT_TYPE_CANCELLED;
+import static com.android.server.usage.BroadcastResponseStatsTracker.NOTIFICATION_EVENT_TYPE_POSTED;
+import static com.android.server.usage.BroadcastResponseStatsTracker.NOTIFICATION_EVENT_TYPE_UPDATED;
+import static com.android.server.usage.BroadcastResponseStatsTracker.TAG;
+import static com.android.server.usage.UsageStatsService.DEBUG_RESPONSE_STATS;
+
+import android.annotation.ElapsedRealtimeLong;
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.app.ActivityManager.ProcessState;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.util.TimeUtils;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.RingBuffer;
+import com.android.server.usage.BroadcastResponseStatsTracker.NotificationEventType;
+
+public class BroadcastResponseStatsLogger {
+
+    private static final int MAX_LOG_SIZE =
+            ActivityManager.isLowRamDeviceStatic() ? 20 : 50;
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final LogBuffer mBroadcastEventsBuffer = new LogBuffer(
+            BroadcastEvent.class, MAX_LOG_SIZE);
+    @GuardedBy("mLock")
+    private final LogBuffer mNotificationEventsBuffer = new LogBuffer(
+            NotificationEvent.class, MAX_LOG_SIZE);
+
+    void logBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
+            UserHandle targetUser, long idForResponseEvent,
+            @ElapsedRealtimeLong long timeStampMs, @ProcessState int targetUidProcessState) {
+        synchronized (mLock) {
+            if (DEBUG_RESPONSE_STATS) {
+                Slog.d(TAG, getBroadcastDispatchEventLog(sourceUid, targetPackage,
+                        targetUser.getIdentifier(), idForResponseEvent, timeStampMs,
+                        targetUidProcessState));
+            }
+            mBroadcastEventsBuffer.logBroadcastDispatchEvent(sourceUid, targetPackage,
+                    targetUser, idForResponseEvent, timeStampMs, targetUidProcessState);
+        }
+    }
+
+    void logNotificationEvent(@NotificationEventType int event,
+            @NonNull String packageName, UserHandle user, @ElapsedRealtimeLong long timestampMs) {
+        synchronized (mLock) {
+            if (DEBUG_RESPONSE_STATS) {
+                Slog.d(TAG, getNotificationEventLog(event, packageName, user.getIdentifier(),
+                        timestampMs));
+            }
+            mNotificationEventsBuffer.logNotificationEvent(event, packageName, user, timestampMs);
+        }
+    }
+
+    void dumpLogs(IndentingPrintWriter ipw) {
+        synchronized (mLock) {
+            ipw.println("Broadcast events (most recent first):");
+            ipw.increaseIndent();
+            mBroadcastEventsBuffer.reverseDump(ipw);
+            ipw.decreaseIndent();
+
+            ipw.println();
+            ipw.println("Notification events (most recent first):");
+            ipw.increaseIndent();
+            mNotificationEventsBuffer.reverseDump(ipw);
+            ipw.decreaseIndent();
+        }
+    }
+
+    private static final class LogBuffer<T extends Data> extends RingBuffer<T> {
+
+        LogBuffer(Class<T> classType, int capacity) {
+            super(classType, capacity);
+        }
+
+        void logBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
+                UserHandle targetUser, long idForResponseEvent,
+                @ElapsedRealtimeLong long timeStampMs, @ProcessState int targetUidProcessState) {
+            final Data data = getNextSlot();
+            if (data == null) return;
+
+            data.reset();
+            final BroadcastEvent event = (BroadcastEvent) data;
+            event.sourceUid = sourceUid;
+            event.targetUserId = targetUser.getIdentifier();
+            event.targetUidProcessState = targetUidProcessState;
+            event.targetPackage = targetPackage;
+            event.idForResponseEvent = idForResponseEvent;
+            event.timestampMs = timeStampMs;
+        }
+
+        void logNotificationEvent(@NotificationEventType int type,
+                @NonNull String packageName, UserHandle user,
+                @ElapsedRealtimeLong long timestampMs) {
+            final Data data = getNextSlot();
+            if (data == null) return;
+
+            data.reset();
+            final NotificationEvent event = (NotificationEvent) data;
+            event.type = type;
+            event.packageName = packageName;
+            event.userId = user.getIdentifier();
+            event.timestampMs = timestampMs;
+        }
+
+        public void reverseDump(IndentingPrintWriter pw) {
+            final Data[] allData = toArray();
+            for (int i = allData.length - 1; i >= 0; --i) {
+                if (allData[i] == null) {
+                    continue;
+                }
+                pw.println(getContent(allData[i]));
+            }
+        }
+
+        @NonNull
+        public String getContent(Data data) {
+            return data.toString();
+        }
+    }
+
+    @NonNull
+    private static String getBroadcastDispatchEventLog(int sourceUid, @NonNull String targetPackage,
+            @UserIdInt int targetUserId, long idForResponseEvent,
+            @ElapsedRealtimeLong long timestampMs, @ProcessState int targetUidProcState) {
+        return TextUtils.formatSimple(
+                "broadcast:%s; srcUid=%d, tgtPkg=%s, tgtUsr=%d, id=%d, state=%s",
+                TimeUtils.formatDuration(timestampMs), sourceUid, targetPackage, targetUserId,
+                idForResponseEvent, procStateToString(targetUidProcState));
+    }
+
+    @NonNull
+    private static String getNotificationEventLog(@NotificationEventType int event,
+            @NonNull String packageName, @UserIdInt int userId,
+            @ElapsedRealtimeLong long timestampMs) {
+        return TextUtils.formatSimple("notification:%s; event=<%s>, pkg=%s, usr=%d",
+                TimeUtils.formatDuration(timestampMs), notificationEventToString(event),
+                packageName, userId);
+    }
+
+    @NonNull
+    private static String notificationEventToString(@NotificationEventType int event) {
+        switch (event) {
+            case NOTIFICATION_EVENT_TYPE_POSTED:
+                return "posted";
+            case NOTIFICATION_EVENT_TYPE_UPDATED:
+                return "updated";
+            case NOTIFICATION_EVENT_TYPE_CANCELLED:
+                return "cancelled";
+            default:
+                return String.valueOf(event);
+        }
+    }
+
+    public static final class BroadcastEvent implements Data {
+        public int sourceUid;
+        public int targetUserId;
+        public int targetUidProcessState;
+        public String targetPackage;
+        public long idForResponseEvent;
+        public long timestampMs;
+
+        @Override
+        public void reset() {
+            targetPackage = null;
+        }
+
+        @Override
+        public String toString() {
+            return getBroadcastDispatchEventLog(sourceUid, targetPackage, targetUserId,
+                    idForResponseEvent, timestampMs, targetUidProcessState);
+        }
+    }
+
+    public static final class NotificationEvent implements Data {
+        public int type;
+        public String packageName;
+        public int userId;
+        public long timestampMs;
+
+        @Override
+        public void reset() {
+            packageName = null;
+        }
+
+        @Override
+        public String toString() {
+            return getNotificationEventLog(type, packageName, userId, timestampMs);
+        }
+    }
+
+    public interface Data {
+        void reset();
+    }
+}
diff --git a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
index ab8f69b..76d2fe7 100644
--- a/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
+++ b/services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java
@@ -16,10 +16,6 @@
 
 package com.android.server.usage;
 
-import static android.app.ActivityManager.procStateToString;
-
-import static com.android.server.usage.UsageStatsService.DEBUG_RESPONSE_STATS;
-
 import android.annotation.ElapsedRealtimeLong;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
@@ -29,11 +25,9 @@
 import android.app.ActivityManager.ProcessState;
 import android.app.usage.BroadcastResponseStats;
 import android.os.UserHandle;
-import android.text.TextUtils;
 import android.util.LongSparseArray;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
@@ -44,19 +38,19 @@
 import java.util.List;
 
 class BroadcastResponseStatsTracker {
-    private static final String TAG = "ResponseStatsTracker";
+    static final String TAG = "ResponseStatsTracker";
 
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"NOTIFICATION_EVENT"}, value = {
-            NOTIFICATION_EVENT_POSTED,
-            NOTIFICATION_EVENT_UPDATED,
-            NOTIFICATION_EVENT_CANCELLED
+    @IntDef(prefix = {"NOTIFICATION_EVENT_TYPE_"}, value = {
+            NOTIFICATION_EVENT_TYPE_POSTED,
+            NOTIFICATION_EVENT_TYPE_UPDATED,
+            NOTIFICATION_EVENT_TYPE_CANCELLED
     })
-    public @interface NotificationEvent {}
+    public @interface NotificationEventType {}
 
-    private static final int NOTIFICATION_EVENT_POSTED = 0;
-    private static final int NOTIFICATION_EVENT_UPDATED = 1;
-    private static final int NOTIFICATION_EVENT_CANCELLED = 2;
+    static final int NOTIFICATION_EVENT_TYPE_POSTED = 0;
+    static final int NOTIFICATION_EVENT_TYPE_UPDATED = 1;
+    static final int NOTIFICATION_EVENT_TYPE_CANCELLED = 2;
 
     private final Object mLock = new Object();
 
@@ -76,21 +70,19 @@
             new SparseArray<>();
 
     private AppStandbyInternal mAppStandby;
+    private BroadcastResponseStatsLogger mLogger;
 
     BroadcastResponseStatsTracker(@NonNull AppStandbyInternal appStandby) {
         mAppStandby = appStandby;
+        mLogger = new BroadcastResponseStatsLogger();
     }
 
     // TODO (206518114): Move all callbacks handling to a handler thread.
     void reportBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage,
             UserHandle targetUser, long idForResponseEvent,
             @ElapsedRealtimeLong long timestampMs, @ProcessState int targetUidProcState) {
-        if (DEBUG_RESPONSE_STATS) {
-            Slog.d(TAG, TextUtils.formatSimple("reportBroadcastDispatchEvent; "
-                            + "srcUid=%d, tgtPkg=%s, tgtUsr=%d, id=%d, ts=%s, state=%s",
-                    sourceUid, targetPackage, targetUser, idForResponseEvent,
-                    TimeUtils.formatDuration(timestampMs), procStateToString(targetUidProcState)));
-        }
+        mLogger.logBroadcastDispatchEvent(sourceUid, targetPackage, targetUser,
+                idForResponseEvent, timestampMs, targetUidProcState);
         if (targetUidProcState <= mAppStandby.getBroadcastResponseFgThresholdState()) {
             // No need to track the broadcast response state while the target app is
             // in the foreground.
@@ -110,29 +102,23 @@
 
     void reportNotificationPosted(@NonNull String packageName, UserHandle user,
             @ElapsedRealtimeLong long timestampMs) {
-        reportNotificationEvent(NOTIFICATION_EVENT_POSTED, packageName, user, timestampMs);
+        reportNotificationEvent(NOTIFICATION_EVENT_TYPE_POSTED, packageName, user, timestampMs);
     }
 
     void reportNotificationUpdated(@NonNull String packageName, UserHandle user,
             @ElapsedRealtimeLong long timestampMs) {
-        reportNotificationEvent(NOTIFICATION_EVENT_UPDATED, packageName, user, timestampMs);
+        reportNotificationEvent(NOTIFICATION_EVENT_TYPE_UPDATED, packageName, user, timestampMs);
 
     }
 
     void reportNotificationCancelled(@NonNull String packageName, UserHandle user,
             @ElapsedRealtimeLong long timestampMs) {
-        reportNotificationEvent(NOTIFICATION_EVENT_CANCELLED, packageName, user, timestampMs);
+        reportNotificationEvent(NOTIFICATION_EVENT_TYPE_CANCELLED, packageName, user, timestampMs);
     }
 
-    private void reportNotificationEvent(@NotificationEvent int event,
+    private void reportNotificationEvent(@NotificationEventType int event,
             @NonNull String packageName, UserHandle user, @ElapsedRealtimeLong long timestampMs) {
-        if (DEBUG_RESPONSE_STATS) {
-            Slog.d(TAG, TextUtils.formatSimple(
-                    "reportNotificationEvent; event=<%s>, pkg=%s, usr=%d, ts=%s",
-                    notificationEventToString(event), packageName, user.getIdentifier(),
-                    TimeUtils.formatDuration(timestampMs)));
-        }
-        // TODO (206518114): Store last N events to dump for debugging purposes.
+        mLogger.logNotificationEvent(event, packageName, user, timestampMs);
         synchronized (mLock) {
             final LongSparseArray<BroadcastEvent> broadcastEvents =
                     getBroadcastEventsLocked(packageName, user);
@@ -157,13 +143,13 @@
                         continue;
                     }
                     switch (event) {
-                        case NOTIFICATION_EVENT_POSTED:
+                        case NOTIFICATION_EVENT_TYPE_POSTED:
                             responseStats.incrementNotificationsPostedCount(1);
                             break;
-                        case NOTIFICATION_EVENT_UPDATED:
+                        case NOTIFICATION_EVENT_TYPE_UPDATED:
                             responseStats.incrementNotificationsUpdatedCount(1);
                             break;
-                        case NOTIFICATION_EVENT_CANCELLED:
+                        case NOTIFICATION_EVENT_TYPE_CANCELLED:
                             responseStats.incrementNotificationsCancelledCount(1);
                             break;
                         default:
@@ -329,20 +315,6 @@
         return userResponseStats.getOrCreateBroadcastResponseStats(broadcastEvent);
     }
 
-    @NonNull
-    private String notificationEventToString(@NotificationEvent int event) {
-        switch (event) {
-            case NOTIFICATION_EVENT_POSTED:
-                return "posted";
-            case NOTIFICATION_EVENT_UPDATED:
-                return "updated";
-            case NOTIFICATION_EVENT_CANCELLED:
-                return "cancelled";
-            default:
-                return String.valueOf(event);
-        }
-    }
-
     void dump(@NonNull IndentingPrintWriter ipw) {
         ipw.println("Broadcast response stats:");
         ipw.increaseIndent();
@@ -351,6 +323,8 @@
             dumpBroadcastEventsLocked(ipw);
             ipw.println();
             dumpResponseStatsLocked(ipw);
+            ipw.println();
+            mLogger.dumpLogs(ipw);
         }
 
         ipw.decreaseIndent();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 06aa8f0..b9abbf0 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -2379,6 +2379,40 @@
         }
 
         @Override
+        public int getAppMinStandbyBucket(String packageName, String callingPackage, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            try {
+                userId = ActivityManager.getService().handleIncomingUser(
+                        Binder.getCallingPid(), callingUid, userId, false, false,
+                        "getAppStandbyBucket", null);
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+            final int packageUid = mPackageManagerInternal.getPackageUid(packageName, 0, userId);
+            // If the calling app is asking about itself, continue, else check for permission.
+            if (packageUid != callingUid) {
+                if (!hasPermission(callingPackage)) {
+                    throw new SecurityException(
+                            "Don't have permission to query min app standby bucket");
+                }
+            }
+            if (packageUid < 0) {
+                throw new IllegalArgumentException(
+                        "Cannot get min standby bucket for non existent package ("
+                                + packageName + ")");
+            }
+            final boolean obfuscateInstantApps = shouldObfuscateInstantAppsForCaller(callingUid,
+                    userId);
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return mAppStandby.getAppMinStandbyBucket(
+                        packageName, UserHandle.getAppId(packageUid), userId, obfuscateInstantApps);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
         public void setEstimatedLaunchTime(String packageName, long estimatedLaunchTime,
                 int userId) {
             getContext().enforceCallingPermission(
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 7f70301..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;
@@ -2187,7 +2187,7 @@
      * @param uid Uid of the caller
      */
     public ParcelFileDescriptor openAccessory(UsbAccessory accessory,
-            UsbUserPermissionManager permissions, int uid) {
+            UsbUserPermissionManager permissions, int pid, int uid) {
         UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
         if (currentAccessory == null) {
             throw new IllegalArgumentException("no accessory attached");
@@ -2198,7 +2198,7 @@
                     + currentAccessory;
             throw new IllegalArgumentException(error);
         }
-        permissions.checkPermission(accessory, uid);
+        permissions.checkPermission(accessory, pid, uid);
         return nativeOpenAccessory();
     }
 
diff --git a/services/usb/java/com/android/server/usb/UsbSerialReader.java b/services/usb/java/com/android/server/usb/UsbSerialReader.java
index f241e65..9dda0e7 100644
--- a/services/usb/java/com/android/server/usb/UsbSerialReader.java
+++ b/services/usb/java/com/android/server/usb/UsbSerialReader.java
@@ -98,7 +98,7 @@
                                     .checkPermission((UsbDevice) mDevice, packageName, pid, uid);
                         } else {
                             mPermissionManager.getPermissionsForUser(userId)
-                                    .checkPermission((UsbAccessory) mDevice, uid);
+                                    .checkPermission((UsbAccessory) mDevice, pid, uid);
                         }
                     }
                 }
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index c0ecf58..e06ab02 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -321,6 +321,7 @@
     public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
         if (mDeviceManager != null) {
             int uid = Binder.getCallingUid();
+            int pid = Binder.getCallingPid();
             int user = UserHandle.getUserId(uid);
 
             final long ident = clearCallingIdentity();
@@ -328,7 +329,7 @@
                 synchronized (mLock) {
                     if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) {
                         return mDeviceManager.openAccessory(accessory, getPermissionsForUser(user),
-                                uid);
+                                pid, uid);
                     } else {
                         Slog.w(TAG, "Cannot open " + accessory + " for user " + user
                                 + " as user is not active.");
@@ -505,11 +506,12 @@
     @Override
     public boolean hasAccessoryPermission(UsbAccessory accessory) {
         final int uid = Binder.getCallingUid();
+        final int pid = Binder.getCallingPid();
         final int userId = UserHandle.getUserId(uid);
 
         final long token = Binder.clearCallingIdentity();
         try {
-            return getPermissionsForUser(userId).hasPermission(accessory, uid);
+            return getPermissionsForUser(userId).hasPermission(accessory, pid, uid);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
@@ -533,11 +535,12 @@
     public void requestAccessoryPermission(
             UsbAccessory accessory, String packageName, PendingIntent pi) {
         final int uid = Binder.getCallingUid();
+        final int pid = Binder.getCallingPid();
         final int userId = UserHandle.getUserId(uid);
 
         final long token = Binder.clearCallingIdentity();
         try {
-            getPermissionsForUser(userId).requestPermission(accessory, packageName, pi, uid);
+            getPermissionsForUser(userId).requestPermission(accessory, packageName, pi, pid, uid);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
diff --git a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
index 286cff9..dd5f153 100644
--- a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
+++ b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
@@ -246,9 +246,13 @@
      * @param uid to check permission for
      * @return {@code true} if caller has permssion
      */
-    boolean hasPermission(@NonNull UsbAccessory accessory, int uid) {
+    boolean hasPermission(@NonNull UsbAccessory accessory, int pid, int uid) {
         synchronized (mLock) {
-            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
+            if (uid == Process.SYSTEM_UID
+                    || mDisablePermissionDialogs
+                    || mContext.checkPermission(
+                        android.Manifest.permission.MANAGE_USB, pid, uid)
+                         == android.content.pm.PackageManager.PERMISSION_GRANTED) {
                 return true;
             }
             AccessoryFilter filter = new AccessoryFilter(accessory);
@@ -675,8 +679,8 @@
         }
     }
 
-    public void checkPermission(UsbAccessory accessory, int uid) {
-        if (!hasPermission(accessory, uid)) {
+    public void checkPermission(UsbAccessory accessory, int pid, int uid) {
+        if (!hasPermission(accessory, pid, uid)) {
             throw new SecurityException("User has not given " + uid + " permission to accessory "
                     + accessory);
         }
@@ -745,9 +749,9 @@
     }
 
     public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi,
-            int uid) {
+            int pid, int uid) {
         // respond immediately if permission has already been granted
-        if (hasPermission(accessory, uid)) {
+        if (hasPermission(accessory, pid, uid)) {
             Intent intent = new Intent();
             intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
             intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 84bd983..a597fc6 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -97,6 +97,7 @@
     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
+    private static final int MAX_ISOLATED_PROCESS_NUMBER = 10;
 
     private final Executor mAudioCopyExecutor = Executors.newCachedThreadPool();
     // TODO: This may need to be a Handler(looper)
@@ -772,7 +773,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);
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..de0b960
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordMetricsLogger.java
@@ -0,0 +1,69 @@
+/*
+ * 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 com.android.internal.util.FrameworkStatsLog;
+
+/**
+ * A utility class for logging hotword statistics event.
+ */
+public final class HotwordMetricsLogger {
+
+    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) {
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_CREATE_REQUESTED, detectorType,
+                isCreated, uid);
+    }
+
+    /**
+     * Logs information related to hotword detection service init result.
+     */
+    public static void writeServiceInitResultEvent(int detectorType, int result) {
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED,
+                detectorType, result);
+    }
+
+    /**
+     * Logs information related to hotword detection service restarting.
+     */
+    public static void writeServiceRestartEvent(int detectorType, int reason) {
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_RESTARTED,
+                detectorType, reason);
+    }
+
+    /**
+     * Logs information related to keyphrase trigger.
+     */
+    public static void writeKeyphraseTriggerEvent(int detectorType, int result) {
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED,
+                detectorType, result);
+    }
+
+    /**
+     * Logs information related to hotword detector events.
+     */
+    public static void writeDetectorEvent(int detectorType, int event, int uid) {
+        FrameworkStatsLog.write(FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS,
+                detectorType, event, uid);
+    }
+}
diff --git a/startop/iorap/Android.bp b/startop/iorap/Android.bp
deleted file mode 100644
index 4fdf34c..0000000
--- a/startop/iorap/Android.bp
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-filegroup {
-  name: "services.startop.iorap-javasources",
-  srcs: ["src/**/*.java"],
-  path: "src",
-  visibility: ["//visibility:private"],
-}
-
-filegroup {
-  name: "services.startop.iorap-sources",
-  srcs: [
-    ":services.startop.iorap-javasources",
-    ":iorap-aidl",
-  ],
-  visibility: ["//frameworks/base/services:__subpackages__"],
-}
-
-java_library_static {
-  name: "services.startop.iorap",
-  srcs: [":services.startop.iorap-sources"],
-  libs: ["services.core"],
-}
diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/TEST_MAPPING
deleted file mode 100644
index 8c9d4df..0000000
--- a/startop/iorap/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "libiorap-java-tests"
-    }
-  ],
-  "imports": [
-    {
-      "path": "system/iorap"
-    }
-  ]
-}
diff --git a/startop/iorap/functional_tests/Android.bp b/startop/iorap/functional_tests/Android.bp
deleted file mode 100644
index 43c6155..0000000
--- a/startop/iorap/functional_tests/Android.bp
+++ /dev/null
@@ -1,50 +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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
-    name: "iorap-functional-tests",
-    srcs: ["src/**/*.java"],
-    data: [":iorap-functional-test-apps"],
-    static_libs: [
-        // Non-test dependencies
-        // library under test
-        "services.startop.iorap",
-        // Test Dependencies
-        // test android dependencies
-        "platform-test-annotations",
-        "androidx.test.rules",
-        "androidx.test.ext.junit",
-        "androidx.test.uiautomator_uiautomator",
-        // test framework dependencies
-        "truth-prebuilt",
-    ],
-    dxflags: ["--multi-dex"],
-    test_suites: ["device-tests"],
-    compile_multilib: "both",
-    libs: [
-        "android.test.base",
-        "android.test.runner",
-    ],
-    certificate: "platform",
-    platform_apis: true,
-}
diff --git a/startop/iorap/functional_tests/AndroidManifest.xml b/startop/iorap/functional_tests/AndroidManifest.xml
deleted file mode 100644
index 6bddc4a3..0000000
--- a/startop/iorap/functional_tests/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<!--suppress AndroidUnknownAttribute -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.google.android.startop.iorap.tests"
-    android:sharedUserId="com.google.android.startop.iorap.tests.functional"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <!--suppress AndroidDomInspection -->
-    <instrumentation
-        android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.google.android.startop.iorap.tests" />
-
-      <!--
-       'debuggable=true' is required to properly load mockito jvmti dependencies,
-         otherwise it gives the following error at runtime:
-
-       Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
-       Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-</manifest>
diff --git a/startop/iorap/functional_tests/AndroidTest.xml b/startop/iorap/functional_tests/AndroidTest.xml
deleted file mode 100644
index 31d4f6c..0000000
--- a/startop/iorap/functional_tests/AndroidTest.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<configuration description="Runs iorap-functional-tests.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-instrumentation" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="iorap-functional-tests.apk" />
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
-    <target_preparer
-        class="com.android.tradefed.targetprep.DeviceSetup">
-
-        <!-- iorapd does not pick up the above changes until we restart it -->
-        <option name="run-command" value="stop iorapd" />
-
-        <!-- Clean up the existing iorap database. -->
-        <option name="run-command" value="rm -r /data/misc/iorapd/*" />
-        <option name="run-command" value="sleep 1" />
-
-        <!-- Set system properties to enable perfetto tracing, readahead and detailed logging. -->
-        <option name="run-command" value="setprop iorapd.perfetto.enable true" />
-        <option name="run-command" value="setprop iorapd.readahead.enable true" />
-        <option name="run-command" value="setprop iorapd.log.verbose true" />
-
-        <option name="run-command" value="start iorapd" />
-
-        <!-- give it some time to restart the service; otherwise the first unit test might fail -->
-        <option name="run-command" value="sleep 1" />
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="abort-on-push-failure" value="true" />
-        <option name="push-file"
-          key="iorap_test_app_v1.apk"
-          value="/data/misc/iorapd/iorap_test_app_v1.apk" />
-        <option name="push-file"
-          key="iorap_test_app_v2.apk"
-          value="/data/misc/iorapd/iorap_test_app_v2.apk" />
-        <option name="push-file"
-          key="iorap_test_app_v3.apk"
-          value="/data/misc/iorapd/iorap_test_app_v3.apk" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.google.android.startop.iorap.tests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <!-- test-timeout unit is ms, value = 30 min -->
-        <option name="test-timeout" value="1800000" />
-    </test>
-
-</configuration>
-
diff --git a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java b/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java
deleted file mode 100644
index 5352be6..0000000
--- a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java
+++ /dev/null
@@ -1,416 +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.google.android.startop.iorapd;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.Until;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-import java.util.Date;
-import java.util.function.BooleanSupplier;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.List;
-import java.text.SimpleDateFormat;
-
-/**
- * Test for the work flow of iorap.
- *
- * <p> This test tests the function of iorap from:
- * perfetto collection -> compilation ->  prefetching -> version update -> perfetto collection.
- */
-@RunWith(AndroidJUnit4.class)
-public class IorapWorkFlowTest {
-  private static final String TAG = "IorapWorkFlowTest";
-
-  private static final String TEST_APP_VERSION_ONE_PATH = "/data/misc/iorapd/iorap_test_app_v1.apk";
-  private static final String TEST_APP_VERSION_TWO_PATH = "/data/misc/iorapd/iorap_test_app_v2.apk";
-  private static final String TEST_APP_VERSION_THREE_PATH = "/data/misc/iorapd/iorap_test_app_v3.apk";
-
-  private static final String DB_PATH = "/data/misc/iorapd/sqlite.db";
-  private static final Duration TIMEOUT = Duration.ofSeconds(300L);
-
-  private UiDevice mDevice;
-
-  @Before
-  public void setUp() throws Exception {
-    // Initialize UiDevice instance
-    mDevice = UiDevice.getInstance(getInstrumentation());
-
-    // Start from the home screen
-    mDevice.pressHome();
-
-    // Wait for launcher
-    final String launcherPackage = mDevice.getLauncherPackageName();
-    assertThat(launcherPackage, notNullValue());
-    mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), TIMEOUT.getSeconds());
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    String packageName = "com.example.ioraptestapp";
-    uninstallApk(packageName);
-  }
-
-  @Test (timeout = 300000)
-  public void testNormalWorkFlow() throws Exception {
-    assertThat(mDevice, notNullValue());
-
-    // Install test app version one
-    installApk(TEST_APP_VERSION_ONE_PATH);
-    String packageName = "com.example.ioraptestapp";
-    String activityName = "com.example.ioraptestapp.MainActivity";
-
-    // Perfetto trace collection phase.
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/1L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/1L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/1L));
-
-    // Trigger maintenance service for compilation.
-    TimeUnit.SECONDS.sleep(5L);
-    assertTrue(compile(packageName, activityName, /*version=*/1L));
-
-    // Run app with prefetching
-    assertTrue(startAppWithCompiledTrace(
-        packageName, activityName, /*version=*/1L));
-  }
-
-  @Test (timeout = 300000)
-  public void testUpdateApp() throws Exception {
-    assertThat(mDevice, notNullValue());
-
-    // Install test app version two,
-    String packageName = "com.example.ioraptestapp";
-    String activityName = "com.example.ioraptestapp.MainActivity";
-    installApk(TEST_APP_VERSION_TWO_PATH);
-
-    // Perfetto trace collection phase.
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/2L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/2L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/2L));
-
-    // Trigger maintenance service for compilation.
-    TimeUnit.SECONDS.sleep(5L);
-    assertTrue(compile(packageName, activityName, /*version=*/2L));
-
-    // Run app with prefetching
-    assertTrue(startAppWithCompiledTrace(
-        packageName, activityName, /*version=*/2L));
-
-    // Update test app to version 3
-    installApk(TEST_APP_VERSION_THREE_PATH);
-
-    // Rerun app, should do pefetto tracing.
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/3L));
-  }
-
-  private static void installApk(String apkPath) throws Exception {
-    // Disable the selinux to allow pm install apk in the dir.
-    executeShellCommand("setenforce 0");
-    executeShellCommand("pm install -r -d " + apkPath);
-    executeShellCommand("setenforce 1");
-
-  }
-
-  private static void uninstallApk(String apkPath) throws Exception {
-    executeShellCommand("pm uninstall " + apkPath);
-  }
-
-  /**
-   * Starts the testing app to collect the perfetto trace.
-   *
-   * @param expectPerfettoTraceCount is the expected count of perfetto traces.
-   */
-  private boolean startAppForPerfettoTrace(
-      String packageName, String activityName, long version)
-      throws Exception {
-    LogcatTimestamp timestamp = runAppOnce(packageName, activityName);
-    return waitForPerfettoTraceSavedFromLogcat(
-        packageName, activityName, version, timestamp);
-  }
-
-  private boolean startAppWithCompiledTrace(
-      String packageName, String activityName, long version)
-      throws Exception {
-    LogcatTimestamp timestamp = runAppOnce(packageName, activityName);
-    return waitForPrefetchingFromLogcat(
-        packageName, activityName, version, timestamp);
-  }
-
-  private LogcatTimestamp runAppOnce(String packageName, String activityName) throws Exception {
-    // Close the specified app if it's open
-    closeApp(packageName);
-    LogcatTimestamp timestamp = new LogcatTimestamp();
-    // Launch the specified app
-    startApp(packageName, activityName);
-    // Wait for the app to appear
-    mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), TIMEOUT.getSeconds());
-    return timestamp;
-  }
-
-  // Invokes the maintenance to compile the perfetto traces to compiled trace.
-  private boolean compile(
-      String packageName, String activityName, long version) throws Exception {
-    // The job id (283673059) is defined in class IorapForwardingService.
-    executeShellCommandViaTmpFile("cmd jobscheduler run -f android 283673059");
-    return waitForFileExistence(getCompiledTracePath(packageName, activityName, version));
-  }
-
-  private String getCompiledTracePath(
-      String packageName, String activityName, long version) {
-    return String.format(
-        "/data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb",
-        packageName, version, activityName);
-  }
-
-  /**
-   * Starts the testing app.
-   */
-  private void startApp(String packageName, String activityName) throws Exception {
-    executeShellCommandViaTmpFile(
-        String.format("am start %s/%s", packageName, activityName));
-  }
-
-  /**
-   * Closes the testing app.
-   * <p> Keep trying to kill the process of the app until no process of the app package
-   * appears.</p>
-   */
-  private void closeApp(String packageName) throws Exception {
-    while (true) {
-      String pid = executeShellCommand("pidof " + packageName);
-      if (pid.isEmpty()) {
-        Log.i(TAG, "Closed app " + packageName);
-        return;
-      }
-      executeShellCommand("kill -9 " + pid);
-      TimeUnit.SECONDS.sleep(1L);
-    }
-  }
-
-  /** Waits for a file to appear. */
-  private boolean waitForFileExistence(String fileName) throws Exception {
-    return retryWithTimeout(TIMEOUT, () -> {
-      try {
-        String fileExists = executeShellCommandViaTmpFile(
-            String.format("test -f %s; echo $?", fileName));
-        Log.i(TAG, fileName + " existence is " +  fileExists);
-        return fileExists.trim().equals("0");
-      } catch (Exception e) {
-        Log.i(TAG, e.getMessage());
-        return false;
-      }
-    });
-  }
-
-  /** Waits for the perfetto trace saved message from logcat. */
-  private boolean waitForPerfettoTraceSavedFromLogcat(
-      String packageName, String activityName, long version, LogcatTimestamp timestamp)
-      throws Exception {
-    Pattern p = Pattern.compile(".*"
-        + getPerfettoTraceSavedIndicator(packageName, activityName, version)
-        + "(.*[.]perfetto_trace[.]pb)\n.*", Pattern.DOTALL);
-
-    return retryWithTimeout(TIMEOUT, () -> {
-      try {
-        String log = timestamp.getLogcatAfter();
-        Matcher m = p.matcher(log);
-        Log.d(TAG, "Tries to find perfetto trace...");
-        if (!m.matches()) {
-          Log.i(TAG, "Cannot find perfetto trace saved in log.");
-          return false;
-        }
-        String filePath = m.group(1);
-        Log.i(TAG, "Perfetto trace is saved to " + filePath);
-        return true;
-      } catch(Exception e) {
-        Log.e(TAG, e.getMessage());
-        return false;
-      }
-   });
-  }
-
-  private String getPerfettoTraceSavedIndicator(
-      String packageName, String activityName, long version) {
-    return String.format(
-        "Perfetto TraceBuffer saved to file: /data/misc/iorapd/%s/%d/%s/raw_traces/",
-        packageName, version, activityName);
-  }
-
-  /**
-   * Waits for the prefetching log in the logcat.
-   *
-   * <p> When prefetching works, the perfetto traces should not be collected. </p>
-   */
-  private boolean waitForPrefetchingFromLogcat(
-      String packageName, String activityName, long version, LogcatTimestamp timestamp)
-      throws Exception {
-    Pattern p = Pattern.compile(
-    ".*" + getReadaheadIndicator(packageName, activityName, version) +
-    ".*Total File Paths=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n"
-        + ".*Total Entries=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n"
-        + ".*Total Bytes=(\\d+) \\(good: (\\d+[.]?\\d*)%\\).*",
-    Pattern.DOTALL);
-
-    return retryWithTimeout(TIMEOUT, () -> {
-      try {
-        String log = timestamp.getLogcatAfter();
-        Matcher m = p.matcher(log);
-        if (!m.matches()) {
-          Log.i(TAG, "Cannot find readahead log.");
-          return false;
-        }
-
-        int totalFilePath = Integer.parseInt(m.group(1));
-        float totalFilePathGoodRate = Float.parseFloat(m.group(2)) / 100;
-        int totalEntries = Integer.parseInt(m.group(3));
-        float totalEntriesGoodRate = Float.parseFloat(m.group(4)) / 100;
-        int totalBytes = Integer.parseInt(m.group(5));
-        float totalBytesGoodRate = Float.parseFloat(m.group(6)) / 100;
-
-        Log.i(TAG, String.format(
-            "totalFilePath: %d (good %.2f) totalEntries: %d (good %.2f) totalBytes: %d (good %.2f)",
-            totalFilePath, totalFilePathGoodRate, totalEntries, totalEntriesGoodRate, totalBytes,
-            totalBytesGoodRate));
-
-        return totalFilePath > 0 &&
-          totalEntries > 0 &&
-          totalBytes > 0 &&
-          totalFilePathGoodRate > 0.5 &&
-          totalEntriesGoodRate > 0.5 &&
-          totalBytesGoodRate > 0.5;
-      } catch(Exception e) {
-        return false;
-      }
-   });
-  }
-
-  private static String getReadaheadIndicator(
-      String packageName, String activityName, long version) {
-    return String.format(
-        "Description = /data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb",
-        packageName, version, activityName);
-  }
-
-  /** Retry until timeout. */
-  private boolean retryWithTimeout(Duration timeout, BooleanSupplier supplier) throws Exception {
-    long totalSleepTimeSeconds = 0L;
-    long sleepIntervalSeconds = 2L;
-    while (true) {
-      if (supplier.getAsBoolean()) {
-        return true;
-      }
-      TimeUnit.SECONDS.sleep(sleepIntervalSeconds);
-      totalSleepTimeSeconds += sleepIntervalSeconds;
-      if (totalSleepTimeSeconds > timeout.getSeconds()) {
-        return false;
-      }
-    }
-  }
-
-  /**
-   * Executes command in adb shell via a tmp file.
-   *
-   * <p> This should be run as root.</p>
-   */
-  private static String executeShellCommandViaTmpFile(String cmd) throws Exception {
-    Log.i(TAG, "Execute via tmp file: " + cmd);
-    Path tmp = null;
-    try {
-      tmp = Files.createTempFile(/*prefix=*/null, /*suffix=*/".sh");
-      Files.write(tmp, cmd.getBytes(StandardCharsets.UTF_8));
-      tmp.toFile().setExecutable(true);
-      return UiDevice.getInstance(
-          InstrumentationRegistry.getInstrumentation()).
-          executeShellCommand(tmp.toString());
-    } finally {
-      if (tmp != null) {
-        Files.delete(tmp);
-      }
-    }
-  }
-
-  /**
-   * Executes command in adb shell.
-   *
-   * <p> This should be run as root.</p>
-   */
-  private static String executeShellCommand(String cmd) throws Exception {
-    Log.i(TAG, "Execute: " + cmd);
-    return UiDevice.getInstance(
-        InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
-  }
-
-  static class LogcatTimestamp {
-    private String epochTime;
-
-    public LogcatTimestamp() throws Exception{
-      long currentTimeMillis = System.currentTimeMillis();
-      epochTime = String.format(
-          "%d.%03d", currentTimeMillis/1000, currentTimeMillis%1000);
-      Log.i(TAG, "Current logcat timestamp is " + epochTime);
-    }
-
-    // For example, 1585264100.000
-    public String getEpochTime() {
-      return epochTime;
-    }
-
-    // Gets the logcat after this epoch time.
-    public String getLogcatAfter() throws Exception {
-      return executeShellCommandViaTmpFile(
-          "logcat -v epoch -t '" + epochTime + "'");
-    }
-  }
-}
-
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
deleted file mode 100644
index 1d38f4c..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Provide a hint to iorapd that an activity has transitioned state.<br /><br />
- *
- * Knowledge of when an activity starts/stops can be used by iorapd to increase system
- * performance (e.g. by launching perfetto tracing to record an io profile, or by
- * playing back an ioprofile via readahead) over the long run.<br /><br />
- *
- * /@see com.google.android.startop.iorap.IIorap#onActivityHintEvent<br /><br />
- *
- * Once an activity hint is in {@link #TYPE_STARTED} it must transition to another type.
- * All other states could be terminal, see below: <br /><br />
- *
- * <pre>
- *
- *          ┌──────────────────────────────────────┐
- *          │                                      ▼
- *        ┌─────────┐     ╔════════════════╗     ╔═══════════╗
- *    ──▶ │ STARTED │ ──▶ ║   COMPLETED    ║ ──▶ ║ CANCELLED ║
- *        └─────────┘     ╚════════════════╝     ╚═══════════╝
- *                          │
- *                          │
- *                          ▼
- *                        ╔════════════════╗
- *                        ║ POST_COMPLETED ║
- *                        ╚════════════════╝
- *
- * </pre> <!-- system/iorap/docs/binder/ActivityHint.dot -->
- *
- * @hide
- */
-public class ActivityHintEvent implements Parcelable {
-
-    public static final int TYPE_STARTED = 0;
-    public static final int TYPE_CANCELLED = 1;
-    public static final int TYPE_COMPLETED = 2;
-    public static final int TYPE_POST_COMPLETED = 3;
-    private static final int TYPE_MAX = TYPE_POST_COMPLETED;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_STARTED,
-            TYPE_CANCELLED,
-            TYPE_COMPLETED,
-            TYPE_POST_COMPLETED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-    public final ActivityInfo activityInfo;
-
-    public ActivityHintEvent(@Type int type, ActivityInfo activityInfo) {
-        this.type = type;
-        this.activityInfo = activityInfo;
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(activityInfo, "activityInfo");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{type: %d, activityInfo: %s}", type, activityInfo);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof ActivityHintEvent) {
-            return equals((ActivityHintEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(ActivityHintEvent other) {
-        return type == other.type &&
-                Objects.equals(activityInfo, other.activityInfo);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        activityInfo.writeToParcel(out, flags);
-    }
-
-    private ActivityHintEvent(Parcel in) {
-        this.type = in.readInt();
-        this.activityInfo = ActivityInfo.CREATOR.createFromParcel(in);
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<ActivityHintEvent> CREATOR
-            = new Parcelable.Creator<ActivityHintEvent>() {
-        public ActivityHintEvent createFromParcel(Parcel in) {
-            return new ActivityHintEvent(in);
-        }
-
-        public ActivityHintEvent[] newArray(int size) {
-            return new ActivityHintEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
deleted file mode 100644
index f47a42c..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import java.util.Objects;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * Provide minimal information for launched activities to iorap.<br /><br />
- *
- * This uniquely identifies a system-wide activity by providing the {@link #packageName} and
- * {@link #activityName}.
- *
- * @see ActivityHintEvent
- * @see AppIntentEvent
- *
- * @hide
- */
-public class ActivityInfo implements Parcelable {
-
-    /** The name of the package, for example {@code com.android.calculator}. */
-    public final String packageName;
-    /** The name of the activity, for example {@code .activities.activity.MainActivity} */
-    public final String activityName;
-
-    public ActivityInfo(String packageName, String activityName) {
-        this.packageName = packageName;
-        this.activityName = activityName;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        Objects.requireNonNull(packageName, "packageName");
-        Objects.requireNonNull(activityName, "activityName");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{packageName: %s, activityName: %s}", packageName, activityName);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof ActivityInfo) {
-            return equals((ActivityInfo) other);
-        }
-        return false;
-    }
-
-    private boolean equals(ActivityInfo other) {
-        return Objects.equals(packageName, other.packageName) &&
-                Objects.equals(activityName, other.activityName);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(packageName);
-        out.writeString(activityName);
-    }
-
-    private ActivityInfo(Parcel in) {
-        packageName = in.readString();
-        activityName = in.readString();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<ActivityInfo> CREATOR
-            = new Parcelable.Creator<ActivityInfo>() {
-        public ActivityInfo createFromParcel(Parcel in) {
-            return new ActivityInfo(in);
-        }
-
-        public ActivityInfo[] newArray(int size) {
-            return new ActivityInfo[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
deleted file mode 100644
index 1cd37b5..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Notifications for iorapd specifying when a system-wide intent defaults change.<br /><br />
- *
- * Intent defaults provide a mechanism for an app to register itself as an automatic handler.
- * For example the camera app might be registered as the default handler for
- * {@link android.provider.MediaStore#INTENT_ACTION_STILL_IMAGE_CAMERA} intent. Subsequently,
- * if an arbitrary other app requests for a still image camera photo to be taken, the system
- * will launch the respective default camera app to be launched to handle that request.<br /><br />
- *
- * In some cases iorapd might need to know default intents, e.g. for boot-time pinning of
- * applications that resolve from the default intent. If the application would now be resolved
- * differently, iorapd would unpin the old application and pin the new application.<br /><br />
- *
- * @hide
- */
-public class AppIntentEvent implements Parcelable {
-
-    /** @see android.content.Intent#CATEGORY_DEFAULT */
-    public static final int TYPE_DEFAULT_INTENT_CHANGED = 0;
-    private static final int TYPE_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_DEFAULT_INTENT_CHANGED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    public final ActivityInfo oldActivityInfo;
-    public final ActivityInfo newActivityInfo;
-
-    // TODO: Probably need the corresponding action here as well.
-
-    public static AppIntentEvent createDefaultIntentChanged(ActivityInfo oldActivityInfo,
-            ActivityInfo newActivityInfo) {
-        return new AppIntentEvent(TYPE_DEFAULT_INTENT_CHANGED, oldActivityInfo,
-                newActivityInfo);
-    }
-
-    private AppIntentEvent(@Type int type, ActivityInfo oldActivityInfo,
-            ActivityInfo newActivityInfo) {
-        this.type = type;
-        this.oldActivityInfo = oldActivityInfo;
-        this.newActivityInfo = newActivityInfo;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(oldActivityInfo, "oldActivityInfo");
-        Objects.requireNonNull(oldActivityInfo, "newActivityInfo");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{oldActivityInfo: %s, newActivityInfo: %s}", oldActivityInfo,
-                newActivityInfo);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof AppIntentEvent) {
-            return equals((AppIntentEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(AppIntentEvent other) {
-        return type == other.type &&
-                Objects.equals(oldActivityInfo, other.oldActivityInfo) &&
-                Objects.equals(newActivityInfo, other.newActivityInfo);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        oldActivityInfo.writeToParcel(out, flags);
-        newActivityInfo.writeToParcel(out, flags);
-    }
-
-    private AppIntentEvent(Parcel in) {
-        this.type = in.readInt();
-        this.oldActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
-        this.newActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<AppIntentEvent> CREATOR
-            = new Parcelable.Creator<AppIntentEvent>() {
-        public AppIntentEvent createFromParcel(Parcel in) {
-            return new AppIntentEvent(in);
-        }
-
-        public AppIntentEvent[] newArray(int size) {
-            return new AppIntentEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
deleted file mode 100644
index 8263e0a..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.annotation.LongDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
-import com.android.server.wm.ActivityMetricsLaunchObserver.Temperature;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Provide a hint to iorapd that an app launch sequence has transitioned state.<br /><br />
- *
- * Knowledge of when an activity starts/stops can be used by iorapd to increase system
- * performance (e.g. by launching perfetto tracing to record an io profile, or by
- * playing back an ioprofile via readahead) over the long run.<br /><br />
- *
- * /@see com.google.android.startop.iorap.IIorap#onAppLaunchEvent <br /><br />
- * @see com.android.server.wm.ActivityMetricsLaunchObserver
- *      ActivityMetricsLaunchObserver for the possible event states.
- * @hide
- */
-public abstract class AppLaunchEvent implements Parcelable {
-    @LongDef
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SequenceId {}
-
-    public final @SequenceId
-    long sequenceId;
-
-    protected AppLaunchEvent(@SequenceId long sequenceId) {
-        this.sequenceId = sequenceId;
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other instanceof AppLaunchEvent) {
-            return equals((AppLaunchEvent) other);
-        }
-        return false;
-    }
-
-    protected boolean equals(AppLaunchEvent other) {
-        return sequenceId == other.sequenceId;
-    }
-
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() +
-                "{" + "sequenceId=" + Long.toString(sequenceId) +
-                toStringBody() + "}";
-    }
-
-    protected String toStringBody() { return ""; };
-
-    // List of possible variants:
-
-    public static final class IntentStarted extends AppLaunchEvent {
-        @NonNull
-        public final Intent intent;
-        public final long timestampNs;
-
-        public IntentStarted(@SequenceId long sequenceId,
-                             Intent intent,
-                             long timestampNs) {
-            super(sequenceId);
-            this.intent = intent;
-            this.timestampNs = timestampNs;
-
-            Objects.requireNonNull(intent, "intent");
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof IntentStarted) {
-                return intent.equals(((IntentStarted)other).intent) &&
-                       timestampNs == ((IntentStarted)other).timestampNs &&
-                       super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return ", intent=" + intent.toString() +
-                   " , timestampNs=" + Long.toString(timestampNs);
-        }
-
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-            super.writeToParcelImpl(p, flags);
-            IntentProtoParcelable.write(p, intent, flags);
-            p.writeLong(timestampNs);
-        }
-
-        IntentStarted(Parcel p) {
-            super(p);
-            intent = IntentProtoParcelable.create(p);
-            timestampNs = p.readLong();
-        }
-    }
-
-    public static final class IntentFailed extends AppLaunchEvent {
-        public IntentFailed(@SequenceId long sequenceId) {
-            super(sequenceId);
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof IntentFailed) {
-                return super.equals(other);
-            }
-            return false;
-        }
-
-        IntentFailed(Parcel p) {
-            super(p);
-        }
-    }
-
-    public static abstract class BaseWithActivityRecordData extends AppLaunchEvent {
-        public final @NonNull
-        @ActivityRecordProto byte[] activityRecordSnapshot;
-
-        protected BaseWithActivityRecordData(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot) {
-            super(sequenceId);
-            activityRecordSnapshot = snapshot;
-
-            Objects.requireNonNull(snapshot, "snapshot");
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof BaseWithActivityRecordData) {
-                return (Arrays.equals(activityRecordSnapshot,
-                      ((BaseWithActivityRecordData)other).activityRecordSnapshot)) &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return ", " + new String(activityRecordSnapshot);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags);
-        }
-
-        BaseWithActivityRecordData(Parcel p) {
-            super(p);
-            activityRecordSnapshot = ActivityRecordProtoParcelable.create(p);
-        }
-    }
-
-    public static final class ActivityLaunched extends BaseWithActivityRecordData {
-        public final @ActivityMetricsLaunchObserver.Temperature
-        int temperature;
-
-        public ActivityLaunched(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot, 
-                @ActivityMetricsLaunchObserver.Temperature int temperature) {
-            super(sequenceId, snapshot);
-            this.temperature = temperature;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ActivityLaunched) {
-                return temperature == ((ActivityLaunched)other).temperature &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", temperature=" + Integer.toString(temperature);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           p.writeInt(temperature);
-        }
-
-        ActivityLaunched(Parcel p) {
-            super(p);
-            temperature = p.readInt();
-        }
-    }
-
-    public static final class ActivityLaunchFinished extends BaseWithActivityRecordData {
-        public final long timestampNs;
-
-        public ActivityLaunchFinished(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot,
-                long timestampNs) {
-            super(sequenceId, snapshot);
-            this.timestampNs = timestampNs;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ActivityLaunchFinished) {
-                return timestampNs == ((ActivityLaunchFinished)other).timestampNs &&
-                       super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           p.writeLong(timestampNs);
-        }
-
-        ActivityLaunchFinished(Parcel p) {
-            super(p);
-            timestampNs = p.readLong();
-        }
-    }
-
-     public static class ActivityLaunchCancelled extends AppLaunchEvent {
-        public final @Nullable @ActivityRecordProto byte[] activityRecordSnapshot;
-
-        public ActivityLaunchCancelled(@SequenceId long sequenceId,
-                @Nullable @ActivityRecordProto byte[] snapshot) {
-            super(sequenceId);
-            activityRecordSnapshot = snapshot;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ActivityLaunchCancelled) {
-                return Arrays.equals(activityRecordSnapshot,
-                    ((ActivityLaunchCancelled)other).activityRecordSnapshot) &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", " + new String(activityRecordSnapshot);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           if (activityRecordSnapshot != null) {
-               p.writeBoolean(true);
-               ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags);
-           } else {
-               p.writeBoolean(false);
-           }
-        }
-
-        ActivityLaunchCancelled(Parcel p) {
-            super(p);
-            if (p.readBoolean()) {
-                activityRecordSnapshot = ActivityRecordProtoParcelable.create(p);
-            } else {
-                activityRecordSnapshot = null;
-            }
-        }
-    }
-
-    public static final class ReportFullyDrawn extends BaseWithActivityRecordData {
-        public final long timestampNs;
-
-        public ReportFullyDrawn(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot,
-                long timestampNs) {
-            super(sequenceId, snapshot);
-            this.timestampNs = timestampNs;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ReportFullyDrawn) {
-                return timestampNs == ((ReportFullyDrawn)other).timestampNs &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           p.writeLong(timestampNs);
-        }
-
-        ReportFullyDrawn(Parcel p) {
-            super(p);
-            timestampNs = p.readLong();
-        }
-    }
-
-    @Override
-    public @ContentsFlags int describeContents() { return 0; }
-
-    @Override
-    public void writeToParcel(Parcel p, @WriteFlags int flags) {
-        p.writeInt(getTypeIndex());
-
-        writeToParcelImpl(p, flags);
-    }
-
-
-    public static Creator<AppLaunchEvent> CREATOR =
-            new Creator<AppLaunchEvent>() {
-        @Override
-        public AppLaunchEvent createFromParcel(Parcel source) {
-            int typeIndex = source.readInt();
-
-            Class<?> kls = getClassFromTypeIndex(typeIndex);
-            if (kls == null) {
-                throw new IllegalArgumentException("Invalid type index: " + typeIndex);
-            }
-
-            try {
-                return (AppLaunchEvent) kls.getConstructor(Parcel.class).newInstance(source);
-            } catch (InstantiationException e) {
-                throw new AssertionError(e);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError(e);
-            } catch (InvocationTargetException e) {
-                throw new AssertionError(e);
-            } catch (NoSuchMethodException e) {
-                throw new AssertionError(e);
-            }
-        }
-
-        @Override
-        public AppLaunchEvent[] newArray(int size) {
-            return new AppLaunchEvent[0];
-        }
-    };
-
-    protected void writeToParcelImpl(Parcel p, int flags) {
-        p.writeLong(sequenceId);
-    }
-
-    protected AppLaunchEvent(Parcel p) {
-        sequenceId = p.readLong();
-    }
-
-    private int getTypeIndex() {
-        for (int i = 0; i < sTypes.length; ++i) {
-            if (sTypes[i].equals(this.getClass())) {
-                return i;
-            }
-        }
-        throw new AssertionError("sTypes did not include this type: " + this.getClass());
-    }
-
-    private static @Nullable Class<?> getClassFromTypeIndex(int typeIndex) {
-        if (typeIndex >= 0 && typeIndex < sTypes.length) {
-            return sTypes[typeIndex];
-        }
-        return null;
-    }
-
-    // Index position matters: It is used to encode the specific type in parceling.
-    // Keep up-to-date with C++ side.
-    private static Class<?>[] sTypes = new Class[] {
-            IntentStarted.class,
-            IntentFailed.class,
-            ActivityLaunched.class,
-            ActivityLaunchFinished.class,
-            ActivityLaunchCancelled.class,
-            ReportFullyDrawn.class,
-    };
-
-    public static class ActivityRecordProtoParcelable {
-        public static void write(Parcel p, @ActivityRecordProto byte[] activityRecordSnapshot,
-                int flags) {
-            p.writeByteArray(activityRecordSnapshot);
-        }
-
-        public static @ActivityRecordProto byte[] create(Parcel p) {
-            byte[] data = p.createByteArray();
-
-            return data;
-        }
-    }
-
-    public static class IntentProtoParcelable {
-        private static final int INTENT_PROTO_CHUNK_SIZE = 1024;
-
-        public static void write(Parcel p, @NonNull Intent intent, int flags) {
-            // There does not appear to be a way to 'reset' a ProtoOutputBuffer stream,
-            // so create a new one every time.
-            final ProtoOutputStream protoOutputStream =
-                    new ProtoOutputStream(INTENT_PROTO_CHUNK_SIZE);
-            // Write this data out as the top-most IntentProto (i.e. it is not a sub-object).
-            intent.dumpDebug(protoOutputStream);
-            final byte[] bytes = protoOutputStream.getBytes();
-
-            p.writeByteArray(bytes);
-        }
-
-        // TODO: Should be mockable for testing?
-        // We cannot deserialize in the platform because we don't have a 'readFromProto'
-        // code.
-        public static @NonNull Intent create(Parcel p) {
-            // This will "read" the correct amount of data, but then we discard it.
-            byte[] data = p.createByteArray();
-
-            // Never called by real code in a platform, this binder API is implemented only in C++.
-            return new Intent("<cannot deserialize IntentProto>");
-        }
-    }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java b/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java
deleted file mode 100644
index 34aedd7..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.android.startop.iorap;
-
-/**
- * Convenience short-hand to throw {@link IllegalAccessException} when the arguments
- * are out-of-range.
- */
-public class CheckHelpers {
-    /** @throws IllegalAccessException if {@param type} is not in {@code [0..maxValue]} */
-    public static void checkTypeInRange(int type, int maxValue) {
-        if (type < 0) {
-            throw new IllegalArgumentException(
-                    String.format("type must be non-negative (value=%d)", type));
-        }
-        if (type > maxValue) {
-            throw new IllegalArgumentException(
-                    String.format("type out of range (value=%d, max=%d)", type, maxValue));
-        }
-    }
-
-    /** @throws IllegalAccessException if {@param state} is not in {@code [0..maxValue]} */
-    public static void checkStateInRange(int state, int maxValue) {
-        if (state < 0) {
-            throw new IllegalArgumentException(
-                    String.format("state must be non-negative (value=%d)", state));
-        }
-        if (state > maxValue) {
-            throw new IllegalArgumentException(
-                    String.format("state out of range (value=%d, max=%d)", state, maxValue));
-        }
-    }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java b/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java
deleted file mode 100644
index 72c5eaa..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java
+++ /dev/null
@@ -1,114 +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.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Notifications for iorapd specifying when a package is updated by dexopt service.<br /><br />
- *
- * @hide
- */
-public class DexOptEvent implements Parcelable {
-    public static final int TYPE_PACKAGE_UPDATE = 0;
-    private static final int TYPE_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_PACKAGE_UPDATE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-    public final String packageName;
-
-    @NonNull
-    public static DexOptEvent createPackageUpdate(String packageName) {
-        return new DexOptEvent(TYPE_PACKAGE_UPDATE, packageName);
-    }
-
-    private DexOptEvent(@Type int type, String packageName) {
-        this.type = type;
-        this.packageName = packageName;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(packageName, "packageName");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{DexOptEvent: packageName: %s}", packageName);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof DexOptEvent) {
-            return equals((DexOptEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(DexOptEvent other) {
-        return packageName.equals(other.packageName);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        out.writeString(packageName);
-    }
-
-    private DexOptEvent(Parcel in) {
-        this.type = in.readInt();
-        this.packageName = in.readString();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<DexOptEvent> CREATOR
-            = new Parcelable.Creator<DexOptEvent>() {
-        public DexOptEvent createFromParcel(Parcel in) {
-            return new DexOptEvent(in);
-        }
-
-        public DexOptEvent[] newArray(int size) {
-            return new DexOptEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java
deleted file mode 100644
index dcaff26..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Intent;
-import android.util.Log;
-
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-
-import java.io.StringWriter;
-import java.io.PrintWriter;
-
-/**
- * A validator to check the correctness of event sequence during app startup.
- *
- * <p> A valid state transition of event sequence is shown as the following:
- *
- * <pre>
- *
- *                                +--------------------+
- *                                |                    |
- *                                |        INIT        |
- *                                |                    |
- *                                +--------------------+
- *                                          |
- *                                          |
- *                                          ↓
- *                                +--------------------+
- *                                |                    |
- *            +-------------------|   INTENT_STARTED   | ←--------------------------------+
- *            |                   |                    |                                  |
- *            |                   +--------------------+                                  |
- *            |                             |                                             |
- *            |                             |                                             |
- *            ↓                             ↓                                             |
- * +--------------------+         +--------------------+                                  |
- * |                    |         |                    |                                  |
- * |   INTENT_FAILED    |         | ACTIVITY_LAUNCHED  |------------------+               |
- * |                    |         |                    |                  |               |
- * +--------------------+         +--------------------+                  |               |
- *            |                              |                            |               |
- *            |                              ↓                            ↓               |
- *            |                   +--------------------+       +--------------------+     |
- *            |                   |                    |       |                    |     |
- *            +------------------ |  ACTIVITY_FINISHED |       | ACTIVITY_CANCELLED |     |
- *            |                   |                    |       |                    |     |
- *            |                   +--------------------+       +--------------------+     |
- *            |                              |                            |               |
- *            |                              |                            |               |
- *            |                              ↓                            |               |
- *            |                   +--------------------+                  |               |
- *            |                   |                    |                  |               |
- *            |                   | REPORT_FULLY_DRAWN |                  |               |
- *            |                   |                    |                  |               |
- *            |                   +--------------------+                  |               |
- *            |                              |                            |               |
- *            |                              |                            |               |
- *            |                              ↓                            |               |
- *            |                   +--------------------+                  |               |
- *            |                   |                    |                  |               |
- *            +-----------------→ |        END         |←-----------------+               |
- *                                |                    |                                  |
- *                                +--------------------+                                  |
- *                                           |                                            |
- *                                           |                                            |
- *                                           |                                            |
- *                                           +---------------------------------------------
- *
- * <p> END is not a real state in implementation. All states that points to END directly
- * could transition to INTENT_STARTED.
- *
- * <p> If any bad transition happened, the state becomse UNKNOWN. The UNKNOWN state
- * could be accumulated, because during the UNKNOWN state more IntentStarted may
- * be triggered. To recover from UNKNOWN to INIT, all the accumualted IntentStarted
- * should termniate.
- *
- * <p> During UNKNOWN state, each IntentStarted increases the accumulation, and any of
- * IntentFailed, ActivityLaunchCancelled and ActivityFinished decreases the accumulation.
- * ReportFullyDrawn doesn't impact the accumulation.
- */
-public class EventSequenceValidator implements ActivityMetricsLaunchObserver {
-  static final String TAG = "EventSequenceValidator";
-  /** $> adb shell 'setprop log.tag.EventSequenceValidator VERBOSE' */
-  public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-  private State state = State.INIT;
-  private long accIntentStartedEvents = 0;
-
-  @Override
-  public void onIntentStarted(@NonNull Intent intent, long timestampNs) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("IntentStarted during UNKNOWN. " + intent);
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    if (state != State.INIT &&
-        state != State.INTENT_FAILED &&
-        state != State.ACTIVITY_CANCELLED &&
-        state != State.ACTIVITY_FINISHED &&
-        state != State.REPORT_FULLY_DRAWN) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.INTENT_STARTED));
-      incAccIntentStartedEvents();
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_STARTED));
-    state = State.INTENT_STARTED;
-  }
-
-  @Override
-  public void onIntentFailed() {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onIntentFailed during UNKNOWN.");
-      decAccIntentStartedEvents();
-      return;
-    }
-    if (state != State.INTENT_STARTED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.INTENT_FAILED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_FAILED));
-    state = State.INTENT_FAILED;
-  }
-
-  @Override
-  public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity,
-      @Temperature int temperature) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onActivityLaunched during UNKNOWN.");
-      return;
-    }
-    if (state != State.INTENT_STARTED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.ACTIVITY_LAUNCHED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_LAUNCHED));
-    state = State.ACTIVITY_LAUNCHED;
-  }
-
-  @Override
-  public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onActivityLaunchCancelled during UNKNOWN.");
-      decAccIntentStartedEvents();
-      return;
-    }
-    if (state != State.ACTIVITY_LAUNCHED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.ACTIVITY_CANCELLED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_CANCELLED));
-    state = State.ACTIVITY_CANCELLED;
-  }
-
-  @Override
-  public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity,
-      long timestampNs) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onActivityLaunchFinished during UNKNOWN.");
-      decAccIntentStartedEvents();
-      return;
-    }
-
-    if (state != State.ACTIVITY_LAUNCHED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.ACTIVITY_FINISHED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_FINISHED));
-    state = State.ACTIVITY_FINISHED;
-  }
-
-  @Override
-  public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity,
-      long timestampNs) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onReportFullyDrawn during UNKNOWN.");
-      return;
-    }
-    if (state == State.INIT) {
-      return;
-    }
-
-    if (state != State.ACTIVITY_FINISHED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.REPORT_FULLY_DRAWN));
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.REPORT_FULLY_DRAWN));
-    state = State.REPORT_FULLY_DRAWN;
-  }
-
-  enum State {
-    INIT,
-    INTENT_STARTED,
-    INTENT_FAILED,
-    ACTIVITY_LAUNCHED,
-    ACTIVITY_CANCELLED,
-    ACTIVITY_FINISHED,
-    REPORT_FULLY_DRAWN,
-    UNKNOWN,
-  }
-
-  private void incAccIntentStartedEvents() {
-    if (accIntentStartedEvents < 0) {
-      throw new AssertionError("The number of unknowns cannot be negative");
-    }
-    if (accIntentStartedEvents == 0) {
-      state = State.UNKNOWN;
-    }
-    ++accIntentStartedEvents;
-    Log.i(TAG,
-        String.format("inc AccIntentStartedEvents to %d", accIntentStartedEvents));
-  }
-
-  private void decAccIntentStartedEvents() {
-    if (accIntentStartedEvents <= 0) {
-      throw new AssertionError("The number of unknowns cannot be negative");
-    }
-    if(accIntentStartedEvents == 1) {
-      state = State.INIT;
-    }
-    --accIntentStartedEvents;
-    Log.i(TAG,
-        String.format("dec AccIntentStartedEvents to %d", accIntentStartedEvents));
-  }
-
-  private void logWarningWithStackTrace(String log) {
-    if (DEBUG) {
-      StringWriter sw = new StringWriter();
-      PrintWriter pw = new PrintWriter(sw);
-      new Throwable("EventSequenceValidator#getStackTrace").printStackTrace(pw);
-      Log.wtf(TAG, String.format("%s\n%s", log, sw));
-    }
-  }
-}
-
diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
deleted file mode 100644
index 77046f2..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
+++ /dev/null
@@ -1,806 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-// TODO: rename to com.android.server.startop.iorap
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.DeviceConfig;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.IoThread;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-import com.android.server.pm.BackgroundDexOptService;
-import com.android.server.pm.PackageManagerService;
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
-import com.android.server.wm.ActivityTaskManagerInternal;
-
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.BooleanSupplier;
-
-/**
- * System-server-local proxy into the {@code IIorap} native service.
- */
-public class IorapForwardingService extends SystemService {
-
-    public static final String TAG = "IorapForwardingService";
-    /** $> adb shell 'setprop log.tag.IorapForwardingService VERBOSE' */
-    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    /** $> adb shell 'setprop ro.iorapd.enable true' */
-    private static boolean IS_ENABLED = SystemProperties.getBoolean("ro.iorapd.enable", true);
-    /** $> adb shell 'setprop iorapd.forwarding_service.wtf_crash true' */
-    private static boolean WTF_CRASH = SystemProperties.getBoolean(
-            "iorapd.forwarding_service.wtf_crash", false);
-    private static final Duration TIMEOUT = Duration.ofSeconds(600L);
-
-    // "Unique" job ID from the service name. Also equal to 283673059.
-    public static final int JOB_ID_IORAPD = encodeEnglishAlphabetStringIntoInt("iorapd");
-    // Run every 24 hours.
-    public static final long JOB_INTERVAL_MS = TimeUnit.HOURS.toMillis(24);
-
-    private IIorap mIorapRemote;
-    private final Object mLock = new Object();
-    /** Handle onBinderDeath by periodically trying to reconnect. */
-    private final Handler mHandler =
-            new BinderConnectionHandler(IoThread.getHandler().getLooper());
-
-    private volatile IorapdJobService mJobService;  // Write-once (null -> non-null forever).
-    private volatile static IorapForwardingService sSelfService;  // Write once (null -> non-null).
-
-
-    /**
-     * Atomics set to true if the JobScheduler requests an abort.
-     */
-    private final AtomicBoolean mAbortIdleCompilation = new AtomicBoolean(false);
-
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public IorapForwardingService(Context context) {
-        super(context);
-
-        if (DEBUG) {
-            Log.v(TAG, "IorapForwardingService (Context=" + context.toString() + ")");
-        }
-
-        if (sSelfService != null) {
-            throw new AssertionError("only one service instance allowed");
-        }
-        sSelfService = this;
-    }
-
-    //<editor-fold desc="Providers">
-    /*
-     * Providers for external dependencies:
-     * - These are marked as protected to allow tests to inject different values via mocks.
-     */
-
-    @VisibleForTesting
-    protected ActivityMetricsLaunchObserverRegistry provideLaunchObserverRegistry() {
-        ActivityTaskManagerInternal amtInternal =
-                LocalServices.getService(ActivityTaskManagerInternal.class);
-        ActivityMetricsLaunchObserverRegistry launchObserverRegistry =
-                amtInternal.getLaunchObserverRegistry();
-        return launchObserverRegistry;
-    }
-
-    @VisibleForTesting
-    protected IIorap provideIorapRemote() {
-        IIorap iorap;
-        try {
-            iorap = IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"));
-        } catch (ServiceManager.ServiceNotFoundException e) {
-            Log.w(TAG, e.getMessage());
-            return null;
-        }
-
-        try {
-            iorap.asBinder().linkToDeath(provideDeathRecipient(), /*flags*/0);
-        } catch (RemoteException e) {
-            handleRemoteError(e);
-            return null;
-        }
-
-        return iorap;
-    }
-
-    @VisibleForTesting
-    protected DeathRecipient provideDeathRecipient() {
-        return new DeathRecipient() {
-            @Override
-            public void binderDied() {
-                Log.w(TAG, "iorapd has died");
-                retryConnectToRemoteAndConfigure(/*attempts*/0);
-
-                if (mJobService != null) {
-                    mJobService.onIorapdDisconnected();
-                }
-            }
-        };
-    }
-
-    @VisibleForTesting
-    protected boolean isIorapEnabled() {
-        // These two mendel flags should match those in iorapd native process
-        // system/iorapd/src/common/property.h
-        boolean isTracingEnabled =
-            getMendelFlag("iorap_perfetto_enable", "iorapd.perfetto.enable", false);
-        boolean isReadAheadEnabled =
-            getMendelFlag("iorap_readahead_enable", "iorapd.readahead.enable", false);
-        // Same as the property in iorapd.rc -- disabling this will mean the 'iorapd' binder process
-        // never comes up, so all binder connections will fail indefinitely.
-        return IS_ENABLED && (isTracingEnabled || isReadAheadEnabled);
-    }
-
-    private boolean getMendelFlag(String mendelFlag, String sysProperty, boolean defaultValue) {
-        // TODO(yawanng) use DeviceConfig to get mendel property.
-        // DeviceConfig doesn't work and the reason is not clear.
-        // Provider service is already up before IORapForwardService.
-        String mendelProperty = "persist.device_config."
-            + DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT
-            + "."
-            + mendelFlag;
-        return SystemProperties.getBoolean(mendelProperty,
-            SystemProperties.getBoolean(sysProperty, defaultValue));
-    }
-
-    //</editor-fold>
-
-    @Override
-    public void onStart() {
-        if (DEBUG) {
-            Log.v(TAG, "onStart");
-        }
-
-        retryConnectToRemoteAndConfigure(/*attempts*/0);
-    }
-
-    @Override
-    public void onBootPhase(int phase) {
-        if (phase == PHASE_BOOT_COMPLETED) {
-            if (DEBUG) {
-                Log.v(TAG, "onBootPhase(PHASE_BOOT_COMPLETED)");
-            }
-
-            if (isIorapEnabled()) {
-                // Set up a recurring background job. This has to be done in a later phase since it
-                // has a dependency the job scheduler.
-                //
-                // Doing this too early can result in a ServiceNotFoundException for 'jobservice'
-                // or a null reference for #getSystemService(JobScheduler.class)
-                mJobService = new IorapdJobService(getContext());
-            }
-        }
-    }
-
-    private class BinderConnectionHandler extends Handler {
-        public BinderConnectionHandler(android.os.Looper looper) {
-            super(looper);
-        }
-
-        public static final int MESSAGE_BINDER_CONNECT = 0;
-
-        private int mAttempts = 0;
-
-        @Override
-        public void handleMessage(android.os.Message message) {
-           switch (message.what) {
-               case MESSAGE_BINDER_CONNECT:
-                   if (!retryConnectToRemoteAndConfigure(mAttempts)) {
-                       mAttempts++;
-                   } else {
-                       mAttempts = 0;
-                   }
-                   break;
-               default:
-                   throw new AssertionError("Unknown message: " + message.toString());
-           }
-        }
-    }
-
-    /**
-     * Handle iorapd shutdowns and crashes, by attempting to reconnect
-     * until the service is reached again.
-     *
-     * <p>The first connection attempt is synchronous,
-     * subsequent attempts are done by posting delayed tasks to the IoThread.</p>
-     *
-     * @return true if connection succeeded now, or false if it failed now [and needs to requeue].
-     */
-    private boolean retryConnectToRemoteAndConfigure(int attempts) {
-        final int sleepTime = 1000;  // ms
-
-        if (DEBUG) {
-            Log.v(TAG, "retryConnectToRemoteAndConfigure - attempt #" + attempts);
-        }
-
-        if (connectToRemoteAndConfigure()) {
-            return true;
-        }
-
-        // Either 'iorapd' is stuck in a crash loop (ouch!!) or we manually
-        // called 'adb shell stop iorapd' , which means this would loop until it comes back
-        // up.
-        //
-        // TODO: it would be good to get nodified of 'adb shell stop iorapd' to avoid
-        // printing this warning.
-        if (DEBUG) {
-            Log.v(TAG, "Failed to connect to iorapd, is it down? Delay for " + sleepTime);
-        }
-
-        // Use a handler instead of Thread#sleep to avoid backing up the binder thread
-        // when this is called from the death recipient callback.
-        mHandler.sendMessageDelayed(
-                mHandler.obtainMessage(BinderConnectionHandler.MESSAGE_BINDER_CONNECT),
-                sleepTime);
-
-        return false;
-
-        // Log.e(TAG, "Can't connect to iorapd - giving up after " + attempts + " attempts");
-    }
-
-    private boolean connectToRemoteAndConfigure() {
-        synchronized (mLock) {
-            // Synchronize against any concurrent calls to this via the DeathRecipient.
-            return connectToRemoteAndConfigureLocked();
-        }
-    }
-
-    private boolean connectToRemoteAndConfigureLocked() {
-        if (!isIorapEnabled()) {
-            if (DEBUG) {
-                Log.v(TAG, "connectToRemoteAndConfigure - iorapd is disabled, skip rest of work");
-            }
-            // When we see that iorapd is disabled (when system server comes up),
-            // it stays disabled permanently until the next system server reset.
-
-            // TODO: consider listening to property changes as a callback, then we can
-            // be more dynamic about handling enable/disable.
-            return true;
-        }
-
-        // Connect to the native binder service.
-        mIorapRemote = provideIorapRemote();
-        if (mIorapRemote == null) {
-            if (DEBUG) {
-                Log.e(TAG, "connectToRemoteAndConfigure - null iorap remote. check for Log.wtf?");
-            }
-            return false;
-        }
-        invokeRemote(mIorapRemote,
-            (IIorap remote) -> remote.setTaskListener(new RemoteTaskListener()) );
-        registerInProcessListenersLocked();
-
-        Log.i(TAG, "Connected to iorapd native service.");
-
-        return true;
-    }
-
-    private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver();
-    private final EventSequenceValidator mEventSequenceValidator = new EventSequenceValidator();
-    private final DexOptPackagesUpdated mDexOptPackagesUpdated = new DexOptPackagesUpdated();
-    private boolean mRegisteredListeners = false;
-
-    private void registerInProcessListenersLocked() {
-        if (mRegisteredListeners) {
-            // Listeners are registered only once (idempotent operation).
-            //
-            // Today listeners are tolerant of the remote side going away
-            // by handling remote errors.
-            //
-            // We could try to 'unregister' the listener when we get a binder disconnect,
-            // but we'd still have to handle the case of encountering synchronous errors so
-            // it really wouldn't be a win (other than having less log spew).
-            return;
-        }
-
-        // Listen to App Launch Sequence events from ActivityTaskManager,
-        // and forward them to the native binder service.
-        ActivityMetricsLaunchObserverRegistry launchObserverRegistry =
-                provideLaunchObserverRegistry();
-        launchObserverRegistry.registerLaunchObserver(mAppLaunchObserver);
-        launchObserverRegistry.registerLaunchObserver(mEventSequenceValidator);
-
-        BackgroundDexOptService.getService().addPackagesUpdatedListener(
-                mDexOptPackagesUpdated);
-
-
-        mRegisteredListeners = true;
-    }
-
-    private class DexOptPackagesUpdated implements BackgroundDexOptService.PackagesUpdatedListener {
-        @Override
-        public void onPackagesUpdated(ArraySet<String> updatedPackages) {
-            String[] updated = updatedPackages.toArray(new String[0]);
-            for (String packageName : updated) {
-                Log.d(TAG, "onPackagesUpdated: " + packageName);
-                invokeRemote(mIorapRemote,
-                    (IIorap remote) ->
-                        remote.onDexOptEvent(RequestId.nextValueForSequence(),
-                                DexOptEvent.createPackageUpdate(packageName))
-                );
-            }
-        }
-    }
-
-    private class AppLaunchObserver implements ActivityMetricsLaunchObserver {
-        // We add a synthetic sequence ID here to make it easier to differentiate new
-        // launch sequences on the native side.
-        private @AppLaunchEvent.SequenceId long mSequenceId = -1;
-
-        // All callbacks occur on the same background thread. Don't synchronize explicitly.
-
-        @Override
-        public void onIntentStarted(@NonNull Intent intent, long timestampNs) {
-            // #onIntentStarted [is the only transition that] initiates a new launch sequence.
-            ++mSequenceId;
-
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onIntentStarted(%d, %s, %d)",
-                        mSequenceId, intent, timestampNs));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.IntentStarted(mSequenceId, intent, timestampNs))
-            );
-        }
-
-        @Override
-        public void onIntentFailed() {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onIntentFailed(%d)", mSequenceId));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.IntentFailed(mSequenceId))
-            );
-        }
-
-        @Override
-        public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity,
-                @Temperature int temperature) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunched(%d, %s, %d)",
-                        mSequenceId, activity, temperature));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                            new AppLaunchEvent.ActivityLaunched(mSequenceId, activity, temperature))
-            );
-        }
-
-        @Override
-        public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchCancelled(%d, %s)",
-                        mSequenceId, activity));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                            new AppLaunchEvent.ActivityLaunchCancelled(mSequenceId,
-                                    activity)));
-        }
-
-        @Override
-        public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity,
-            long timestampNs) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchFinished(%d, %s, %d)",
-                        mSequenceId, activity, timestampNs));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.ActivityLaunchFinished(mSequenceId,
-                            activity,
-                            timestampNs))
-            );
-        }
-
-        @Override
-        public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity,
-            long timestampNs) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onReportFullyDrawn(%d, %s, %d)",
-                        mSequenceId, activity, timestampNs));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.ReportFullyDrawn(mSequenceId, activity, timestampNs))
-            );
-        }
-    }
-
-    /**
-     * Debugging:
-     *
-     * $> adb shell dumpsys jobscheduler
-     *
-     * Search for 'IorapdJobServiceProxy'.
-     *
-     *   JOB #1000/283673059: 6e54ed android/com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy
-     *   ^    ^                      ^
-     *   (uid, job id)               ComponentName(package/class)
-     *
-     * Forcing the job to be run, ignoring constraints:
-     *
-     * $> adb shell cmd jobscheduler run -f android 283673059
-     *                                      ^        ^
-     *                                      package  job_id
-     *
-     * ------------------------------------------------------------
-     *
-     * This class is instantiated newly by the JobService every time
-     * it wants to run a new job.
-     *
-     * We need to forward invocations to the current running instance of
-     * IorapForwardingService#IorapdJobService.
-     *
-     * Visibility: Must be accessible from android.app.AppComponentFactory
-     */
-    public static class IorapdJobServiceProxy extends JobService {
-
-        public IorapdJobServiceProxy() {
-            getActualIorapdJobService().bindProxy(this);
-        }
-
-
-        @NonNull
-        private IorapdJobService getActualIorapdJobService() {
-            // Can't ever be null, because the guarantee is that the
-            // IorapForwardingService is always running.
-            // We are in the same process as Job Service.
-            return sSelfService.mJobService;
-        }
-
-        // Called by system to start the job.
-        @Override
-        public boolean onStartJob(JobParameters params) {
-            return getActualIorapdJobService().onStartJob(params);
-        }
-
-        // Called by system to prematurely stop the job.
-        @Override
-        public boolean onStopJob(JobParameters params) {
-            return getActualIorapdJobService().onStopJob(params);
-        }
-    }
-
-    private class IorapdJobService extends JobService {
-        private final ComponentName IORAPD_COMPONENT_NAME;
-
-        private final Object mLock = new Object();
-        // Jobs currently running remotely on iorapd.
-        // They were started by the JobScheduler and need to be finished.
-        private final HashMap<RequestId, JobParameters> mRunningJobs = new HashMap<>();
-
-        private final JobInfo IORAPD_JOB_INFO;
-
-        private volatile IorapdJobServiceProxy mProxy;
-
-        public void bindProxy(IorapdJobServiceProxy proxy) {
-            mProxy = proxy;
-        }
-
-        // Create a new job service which immediately schedules a 24-hour idle maintenance mode
-        // background job to execute.
-        public IorapdJobService(Context context) {
-            if (DEBUG) {
-                Log.v(TAG, "IorapdJobService (Context=" + context.toString() + ")");
-            }
-
-            // Schedule the proxy class to be instantiated by the JobScheduler
-            // when it is time to invoke background jobs for IorapForwardingService.
-
-
-            // This also needs a BIND_JOB_SERVICE permission in
-            // frameworks/base/core/res/AndroidManifest.xml
-            IORAPD_COMPONENT_NAME = new ComponentName(context, IorapdJobServiceProxy.class);
-
-            JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_IORAPD, IORAPD_COMPONENT_NAME);
-            builder.setPeriodic(JOB_INTERVAL_MS);
-
-            builder.setRequiresCharging(true);
-            builder.setRequiresDeviceIdle(true);
-
-            builder.setRequiresStorageNotLow(true);
-
-            IORAPD_JOB_INFO = builder.build();
-
-            JobScheduler js = context.getSystemService(JobScheduler.class);
-            js.schedule(IORAPD_JOB_INFO);
-            Log.d(TAG,
-                    "BgJob Scheduled (jobId=" + JOB_ID_IORAPD
-                            + ", interval: " + JOB_INTERVAL_MS + "ms)");
-        }
-
-        // Called by system to start the job.
-        @Override
-        public boolean onStartJob(JobParameters params) {
-            // Tell iorapd to start a background job.
-            Log.d(TAG, "Starting background job: " + params.toString());
-
-            mAbortIdleCompilation.set(false);
-            // PackageManagerService starts before IORap service.
-            PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
-            List<String> pkgs = pm.getAllPackages();
-            runIdleCompilationAsync(params, pkgs);
-            return true;
-        }
-
-        private void runIdleCompilationAsync(final JobParameters params, final List<String> pkgs) {
-            new Thread("IORap_IdleCompilation") {
-                @Override
-                public void run() {
-                    for (int i = 0; i < pkgs.size(); i++) {
-                        String pkg = pkgs.get(i);
-                        if (mAbortIdleCompilation.get()) {
-                            Log.i(TAG, "The idle compilation is aborted");
-                            return;
-                        }
-
-                        // We wait until that job's sequence ID returns to us with 'Completed',
-                        RequestId request;
-                        synchronized (mLock) {
-                            // TODO: would be cleaner if we got the request from the
-                            // 'invokeRemote' function. Better yet, consider
-                            // a Pair<RequestId, Future<TaskResult>> or similar.
-                            request = RequestId.nextValueForSequence();
-                            mRunningJobs.put(request, params);
-                        }
-
-                        Log.i(TAG, String.format("IORap compile package: %s, [%d/%d]",
-                              pkg, i + 1, pkgs.size()));
-                        boolean shouldUpdateVersions = (i == 0);
-                        if (!invokeRemote(mIorapRemote, (IIorap remote) ->
-                                remote.onJobScheduledEvent(request,
-                                        JobScheduledEvent.createIdleMaintenance(
-                                                JobScheduledEvent.TYPE_START_JOB,
-                                                params,
-                                                pkg,
-                                                shouldUpdateVersions)))) {
-                            synchronized (mLock) {
-                                mRunningJobs.remove(request); // Avoid memory leaks.
-                            }
-                        }
-
-                        // Wait until the job is complete and removed from the running jobs.
-                        retryWithTimeout(TIMEOUT, () -> {
-                            synchronized (mLock) {
-                                return !mRunningJobs.containsKey(request);
-                            }
-                        });
-                    }
-
-                    // Finish the job after all packages are compiled.
-                    if (mProxy != null) {
-                        mProxy.jobFinished(params, /*reschedule*/false);
-                    }
-                }
-          }.start();
-        }
-
-        /** Retry until timeout. */
-        private boolean retryWithTimeout(final Duration timeout, BooleanSupplier supplier) {
-            long totalSleepTimeMs = 0L;
-            long sleepIntervalMs = 10L;
-            while (true) {
-                if (supplier.getAsBoolean()) {
-                    return true;
-                }
-                try {
-                    TimeUnit.MILLISECONDS.sleep(sleepIntervalMs);
-                } catch (InterruptedException e) {
-                    Log.e(TAG, e.getMessage());
-                    return false;
-                }
-
-                totalSleepTimeMs += sleepIntervalMs;
-                if (totalSleepTimeMs > timeout.toMillis()) {
-                    return false;
-                }
-            }
-        }
-
-        // Called by system to prematurely stop the job.
-        @Override
-        public boolean onStopJob(JobParameters params) {
-            // As this is unexpected behavior, print a warning.
-            Log.w(TAG, "onStopJob(params=" + params.toString() + ")");
-            mAbortIdleCompilation.set(true);
-
-            // Yes, retry the job at a later time no matter what.
-            return true;
-        }
-
-        // Listen to *all* task completes for all requests.
-        // The majority of these might be unrelated to background jobs.
-        public void onIorapdTaskCompleted(RequestId requestId) {
-            JobParameters jobParameters;
-            synchronized (mLock) {
-                jobParameters = mRunningJobs.remove(requestId);
-            }
-
-            // Typical case: This was a task callback unrelated to our jobs.
-            if (jobParameters == null) {
-                return;
-            }
-
-            if (DEBUG) {
-                Log.v(TAG,
-                        String.format("IorapdJobService#onIorapdTaskCompleted(%s), found params=%s",
-                                requestId, jobParameters));
-            }
-
-            Log.d(TAG, "Finished background job: " + jobParameters.toString());
-        }
-
-        public void onIorapdDisconnected() {
-            synchronized (mLock) {
-                mRunningJobs.clear();
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, String.format("IorapdJobService#onIorapdDisconnected"));
-            }
-
-            // TODO: should we try to resubmit all incomplete jobs after it's reconnected?
-        }
-    }
-
-    private class RemoteTaskListener extends ITaskListener.Stub {
-        @Override
-        public void onProgress(RequestId requestId, TaskResult result) throws RemoteException {
-            if (DEBUG) {
-                Log.v(TAG,
-                        String.format("RemoteTaskListener#onProgress(%s, %s)", requestId, result));
-            }
-
-            // TODO: implement rest.
-        }
-
-        @Override
-        public void onComplete(RequestId requestId, TaskResult result) throws RemoteException {
-            if (DEBUG) {
-                Log.v(TAG,
-                        String.format("RemoteTaskListener#onComplete(%s, %s)", requestId, result));
-            }
-
-            if (mJobService != null) {
-                mJobService.onIorapdTaskCompleted(requestId);
-            }
-
-            // TODO: implement rest.
-        }
-    }
-
-    /** Allow passing lambdas to #invokeRemote */
-    private interface RemoteRunnable {
-        // TODO: run(RequestId) ?
-        void run(IIorap iorap) throws RemoteException;
-    }
-
-    // Always pass in the iorap directly here to avoid data race.
-    private static boolean invokeRemote(IIorap iorap, RemoteRunnable r) {
-       if (iorap == null) {
-         Log.w(TAG, "IIorap went to null in this thread, drop invokeRemote.");
-         return false;
-       }
-       try {
-           r.run(iorap);
-           return true;
-       } catch (RemoteException e) {
-           // This could be a logic error (remote side returning error), which we need to fix.
-           //
-           // This could also be a DeadObjectException in which case its probably just iorapd
-           // being manually restarted.
-           //
-           // Don't make any assumption, since DeadObjectException could also mean iorapd crashed
-           // unexpectedly.
-           //
-           // DeadObjectExceptions are recovered from using DeathRecipient and #linkToDeath.
-           handleRemoteError(e);
-           return false;
-       }
-    }
-
-    private static void handleRemoteError(Throwable t) {
-        if (WTF_CRASH) {
-            // In development modes, we just want to crash.
-            throw new AssertionError("unexpected remote error", t);
-        } else {
-            // Log to wtf which gets sent to dropbox, and in system_server this does not crash.
-            Log.wtf(TAG, t);
-        }
-    }
-
-    // Encode A-Z bitstring into bits. Every character is bits.
-    // Characters outside of the range [a,z] are considered out of range.
-    //
-    // The least significant bits hold the last character.
-    // First 2 bits are left as 0.
-    private static int encodeEnglishAlphabetStringIntoInt(String name) {
-        int value = 0;
-
-        final int CHARS_PER_INT = 6;
-        final int BITS_PER_CHAR = 5;
-        // Note: 2 top bits are unused, this also means our values are non-negative.
-        final char CHAR_LOWER = 'a';
-        final char CHAR_UPPER = 'z';
-
-        if (name.length() > CHARS_PER_INT) {
-            throw new IllegalArgumentException(
-                    "String too long. Cannot encode more than 6 chars: " + name);
-        }
-
-        for (int i = 0; i < name.length(); ++i) {
-           char c = name.charAt(i);
-
-           if (c < CHAR_LOWER || c > CHAR_UPPER) {
-               throw new IllegalArgumentException("String has out-of-range [a-z] chars: " + name);
-           }
-
-           // Avoid sign extension during promotion.
-           int cur_value = (c & 0xFFFF) - (CHAR_LOWER & 0xFFFF);
-           if (cur_value >= (1 << BITS_PER_CHAR)) {
-               throw new AssertionError("wtf? i=" + i + ", name=" + name);
-           }
-
-           value = value << BITS_PER_CHAR;
-           value = value | cur_value;
-        }
-
-        return value;
-    }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java b/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
deleted file mode 100644
index b91dd71..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.app.job.JobParameters;
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward JobService events to iorapd. <br /><br />
- *
- * iorapd sometimes need to use background jobs. Forwarding these events to iorapd
- * notifies iorapd when it is an opportune time to execute these background jobs.
- *
- * @hide
- */
-public class JobScheduledEvent implements Parcelable {
-
-    /** JobService#onJobStarted */
-    public static final int TYPE_START_JOB = 0;
-    /** JobService#onJobStopped */
-    public static final int TYPE_STOP_JOB = 1;
-    private static final int TYPE_MAX = 1;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_START_JOB,
-            TYPE_STOP_JOB,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    /** @see JobParameters#getJobId() */
-    public final int jobId;
-
-    public final String packageName;
-
-    public final boolean shouldUpdateVersions;
-
-    /** Device is 'idle' and it's charging (plugged in). */
-    public static final int SORT_IDLE_MAINTENANCE = 0;
-    private static final int SORT_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "SORT_" }, value = {
-            SORT_IDLE_MAINTENANCE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Sort {}
-
-    /**
-     * Roughly corresponds to the {@code extras} fields in a JobParameters.
-     */
-    @Sort public final int sort;
-
-    /**
-     * Creates a {@link #SORT_IDLE_MAINTENANCE} event from the type and job parameters.
-     *
-     * Only the job ID is retained from {@code jobParams}, all other param info is dropped.
-     */
-    @NonNull
-    public static JobScheduledEvent createIdleMaintenance(
-        @Type int type, JobParameters jobParams, String packageName, boolean shouldUpdateVersions) {
-        return new JobScheduledEvent(
-            type, jobParams.getJobId(), SORT_IDLE_MAINTENANCE, packageName, shouldUpdateVersions);
-    }
-
-    private JobScheduledEvent(@Type int type,
-                              int jobId,
-                              @Sort int sort,
-                              String packageName,
-                              boolean shouldUpdateVersions) {
-        this.type = type;
-        this.jobId = jobId;
-        this.sort = sort;
-        this.packageName = packageName;
-        this.shouldUpdateVersions = shouldUpdateVersions;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        // No check for 'jobId': any int is valid.
-        CheckHelpers.checkTypeInRange(sort, SORT_MAX);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof JobScheduledEvent) {
-            return equals((JobScheduledEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(JobScheduledEvent other) {
-        return type == other.type &&
-                jobId == other.jobId &&
-                sort == other.sort &&
-                packageName.equals(other.packageName) &&
-                shouldUpdateVersions == other.shouldUpdateVersions;
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-            "{type: %d, jobId: %d, sort: %d, packageName: %s, shouldUpdateVersions %b}",
-            type, jobId, sort, packageName, shouldUpdateVersions);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        out.writeInt(jobId);
-        out.writeInt(sort);
-        out.writeString(packageName);
-        out.writeBoolean(shouldUpdateVersions);
-
-        // We do not parcel the entire JobParameters here because there is no C++ equivalent
-        // of that class [which the iorapd side of the binder interface requires].
-    }
-
-    private JobScheduledEvent(Parcel in) {
-        this.type = in.readInt();
-        this.jobId = in.readInt();
-        this.sort = in.readInt();
-        this.packageName = in.readString();
-        this.shouldUpdateVersions = in.readBoolean();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<JobScheduledEvent> CREATOR
-            = new Parcelable.Creator<JobScheduledEvent>() {
-        public JobScheduledEvent createFromParcel(Parcel in) {
-            return new JobScheduledEvent(in);
-        }
-
-        public JobScheduledEvent[] newArray(int size) {
-            return new JobScheduledEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java b/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
deleted file mode 100644
index aa4eea7..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.net.Uri;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Forward package manager events to iorapd. <br /><br />
- *
- * Knowing when packages are modified by the system are a useful tidbit to help with performance:
- * for example when a package is replaced, it could be a hint used to invalidate any collected
- * io profiles used for prefetching or pinning.
- *
- * @hide
- */
-public class PackageEvent implements Parcelable {
-
-    /** @see android.content.Intent#ACTION_PACKAGE_REPLACED */
-    public static final int TYPE_REPLACED = 0;
-    private static final int TYPE_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_REPLACED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    /** The path that a package is installed in, for example {@code /data/app/.../base.apk}. */
-    public final Uri packageUri;
-    /** The name of the package, for example {@code com.android.calculator}. */
-    public final String packageName;
-
-    @NonNull
-    public static PackageEvent createReplaced(Uri packageUri, String packageName) {
-        return new PackageEvent(TYPE_REPLACED, packageUri, packageName);
-    }
-
-    private PackageEvent(@Type int type, Uri packageUri, String packageName) {
-        this.type = type;
-        this.packageUri = packageUri;
-        this.packageName = packageName;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(packageUri, "packageUri");
-        Objects.requireNonNull(packageName, "packageName");
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof PackageEvent) {
-            return equals((PackageEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(PackageEvent other) {
-        return type == other.type &&
-                Objects.equals(packageUri, other.packageUri) &&
-                Objects.equals(packageName, other.packageName);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{packageUri: %s, packageName: %s}", packageUri, packageName);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        packageUri.writeToParcel(out, flags);
-        out.writeString(packageName);
-    }
-
-    private PackageEvent(Parcel in) {
-        this.type = in.readInt();
-        this.packageUri = Uri.CREATOR.createFromParcel(in);
-        this.packageName = in.readString();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<PackageEvent> CREATOR
-            = new Parcelable.Creator<PackageEvent>() {
-        public PackageEvent createFromParcel(Parcel in) {
-            return new PackageEvent(in);
-        }
-
-        public PackageEvent[] newArray(int size) {
-            return new PackageEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java b/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
deleted file mode 100644
index 503e1c6..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.NonNull;
-
-/**
- * Uniquely identify an {@link com.google.android.startop.iorap.IIorap} method invocation,
- * used for asynchronous callbacks by the server. <br /><br />
- *
- * As all system server binder calls must be {@code oneway}, this means all invocations
- * into {@link com.google.android.startop.iorap.IIorap} are non-blocking. The request ID
- * exists to associate all calls with their respective callbacks in
- * {@link com.google.android.startop.iorap.ITaskListener}.
- *
- * @see com.google.android.startop.iorap.IIorap
- *
- * @hide
- */
-public class RequestId implements Parcelable {
-
-    public final long requestId;
-
-    private static Object mLock = new Object();
-    private static long mNextRequestId = 0;
-
-    /**
-     * Create a monotonically increasing request ID.<br /><br />
-     *
-     * It is invalid to re-use the same request ID for multiple method calls on
-     * {@link com.google.android.startop.iorap.IIorap}; a new request ID must be created
-     * each time.
-     */
-    @NonNull public static RequestId nextValueForSequence() {
-        long currentRequestId;
-        synchronized (mLock) {
-            currentRequestId = mNextRequestId;
-            ++mNextRequestId;
-        }
-        return new RequestId(currentRequestId);
-    }
-
-    private RequestId(long requestId) {
-        this.requestId = requestId;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        if (requestId < 0) {
-            throw new IllegalArgumentException("request id must be non-negative");
-        }
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{requestId: %d}", requestId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Long.hashCode(requestId);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof RequestId) {
-            return equals((RequestId) other);
-        }
-        return false;
-    }
-
-    private boolean equals(RequestId other) {
-        return requestId == other.requestId;
-    }
-
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeLong(requestId);
-    }
-
-    private RequestId(Parcel in) {
-        requestId = in.readLong();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<RequestId> CREATOR
-            = new Parcelable.Creator<RequestId>() {
-        public RequestId createFromParcel(Parcel in) {
-            return new RequestId(in);
-        }
-
-        public RequestId[] newArray(int size) {
-            return new RequestId[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
deleted file mode 100644
index 75d47f9..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward system service events to iorapd.
- *
- * @see com.android.server.SystemService
- *
- * @hide
- */
-public class SystemServiceEvent implements Parcelable {
-
-    /** @see com.android.server.SystemService#onBootPhase */
-    public static final int TYPE_BOOT_PHASE = 0;
-    /** @see com.android.server.SystemService#onStart */
-    public static final int TYPE_START = 1;
-    private static final int TYPE_MAX = TYPE_START;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_BOOT_PHASE,
-            TYPE_START,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    // TODO: do we want to pass the exact build phase enum?
-
-    public SystemServiceEvent(@Type int type) {
-        this.type = type;
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{type: %d}", type);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof SystemServiceEvent) {
-            return equals((SystemServiceEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(SystemServiceEvent other) {
-        return type == other.type;
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-    }
-
-    private SystemServiceEvent(Parcel in) {
-        this.type = in.readInt();
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<SystemServiceEvent> CREATOR
-            = new Parcelable.Creator<SystemServiceEvent>() {
-        public SystemServiceEvent createFromParcel(Parcel in) {
-            return new SystemServiceEvent(in);
-        }
-
-        public SystemServiceEvent[] newArray(int size) {
-            return new SystemServiceEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
deleted file mode 100644
index 2e7bafe..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward user events to iorapd.<br /><br />
- *
- * Knowledge of the logged-in user is reserved to be used to set-up appropriate policies
- * by iorapd (e.g. to handle user default pinned applications changing).
- *
- * @see com.android.server.SystemService
- *
- * @hide
- */
-public class SystemServiceUserEvent implements Parcelable {
-
-    /** @see com.android.server.SystemService#onUserStarting */
-    public static final int TYPE_START_USER = 0;
-    /** @see com.android.server.SystemService#onUserUnlocking */
-    public static final int TYPE_UNLOCK_USER = 1;
-    /** @see com.android.server.SystemService#onUserSwitching*/
-    public static final int TYPE_SWITCH_USER = 2;
-    /** @see com.android.server.SystemService#onUserStopping */
-    public static final int TYPE_STOP_USER = 3;
-    /** @see com.android.server.SystemService#onUserStopped */
-    public static final int TYPE_CLEANUP_USER = 4;
-    private static final int TYPE_MAX = TYPE_CLEANUP_USER;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_START_USER,
-            TYPE_UNLOCK_USER,
-            TYPE_SWITCH_USER,
-            TYPE_STOP_USER,
-            TYPE_CLEANUP_USER,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-    public final int userHandle;
-
-    public SystemServiceUserEvent(@Type int type, int userHandle) {
-        this.type = type;
-        this.userHandle = userHandle;
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        if (userHandle < 0) {
-            throw new IllegalArgumentException("userHandle must be non-negative");
-        }
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{type: %d, userHandle: %d}", type, userHandle);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof SystemServiceUserEvent) {
-            return equals((SystemServiceUserEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(SystemServiceUserEvent other) {
-        return type == other.type &&
-                userHandle == other.userHandle;
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        out.writeInt(userHandle);
-    }
-
-    private SystemServiceUserEvent(Parcel in) {
-        this.type = in.readInt();
-        this.userHandle = in.readInt();
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<SystemServiceUserEvent> CREATOR
-            = new Parcelable.Creator<SystemServiceUserEvent>() {
-        public SystemServiceUserEvent createFromParcel(Parcel in) {
-            return new SystemServiceUserEvent(in);
-        }
-
-        public SystemServiceUserEvent[] newArray(int size) {
-            return new SystemServiceUserEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java b/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
deleted file mode 100644
index b5fd6d8..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Result data accompanying a request for {@link com.google.android.startop.iorap.ITaskListener}
- * callbacks.<br /><br />
- *
- * Following {@link com.google.android.startop.iorap.IIorap} method invocation,
- * iorapd will issue in-order callbacks for that corresponding {@link RequestId}.<br /><br />
- *
- * State transitions are as follows: <br /><br />
- *
- * <pre>
- *          ┌─────────────────────────────┐
- *          │                             ▼
- *        ┌───────┐     ┌─────────┐     ╔═══════════╗
- *    ──▶ │ BEGAN │ ──▶ │ ONGOING │ ──▶ ║ COMPLETED ║
- *        └───────┘     └─────────┘     ╚═══════════╝
- *          │             │
- *          │             │
- *          ▼             │
- *        ╔═══════╗       │
- *    ──▶ ║ ERROR ║ ◀─────┘
- *        ╚═══════╝
- *
- * </pre> <!-- system/iorap/docs/binder/TaskResult.dot -->
- *
- * @hide
- */
-public class TaskResult implements Parcelable {
-
-    public static final int STATE_BEGAN = 0;
-    public static final int STATE_ONGOING = 1;
-    public static final int STATE_COMPLETED = 2;
-    public static final int STATE_ERROR = 3;
-    private static final int STATE_MAX = STATE_ERROR;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "STATE_" }, value = {
-            STATE_BEGAN,
-            STATE_ONGOING,
-            STATE_COMPLETED,
-            STATE_ERROR,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface State {}
-
-    @State public final int state;
-
-    @Override
-    public String toString() {
-        return String.format("{state: %d}", state);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof TaskResult) {
-            return equals((TaskResult) other);
-        }
-        return false;
-    }
-
-    private boolean equals(TaskResult other) {
-        return state == other.state;
-    }
-
-    public TaskResult(@State int state) {
-        this.state = state;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkStateInRange(state, STATE_MAX);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(state);
-    }
-
-    private TaskResult(Parcel in) {
-        state = in.readInt();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<TaskResult> CREATOR
-            = new Parcelable.Creator<TaskResult>() {
-        public TaskResult createFromParcel(Parcel in) {
-            return new TaskResult(in);
-        }
-
-        public TaskResult[] newArray(int size) {
-            return new TaskResult[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/stress/main_memory.cc b/startop/iorap/stress/main_memory.cc
deleted file mode 100644
index 1f26861..0000000
--- a/startop/iorap/stress/main_memory.cc
+++ /dev/null
@@ -1,126 +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.
-//
-
-#include <chrono>
-#include <fstream>
-#include <iostream>
-#include <random>
-#include <string>
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#include <android-base/parseint.h>
-
-static constexpr size_t kBytesPerMb = 1048576;
-const size_t kMemoryAllocationSize = 2 * 1024 * kBytesPerMb;
-
-#define USE_MLOCKALL 0
-
-std::string GetProcessStatus(const char* key) {
-  // Build search pattern of key and separator.
-  std::string pattern(key);
-  pattern.push_back(':');
-
-  // Search for status lines starting with pattern.
-  std::ifstream fs("/proc/self/status");
-  std::string line;
-  while (std::getline(fs, line)) {
-    if (strncmp(pattern.c_str(), line.c_str(), pattern.size()) == 0) {
-      // Skip whitespace in matching line (if any).
-      size_t pos = line.find_first_not_of(" \t", pattern.size());
-      if (pos == std::string::npos) {
-        break;
-      }
-      return std::string(line, pos);
-    }
-  }
-  return "<unknown>";
-}
-
-int main(int argc, char** argv) {
-  size_t allocationSize = 0;
-  if (argc >= 2) {
-    if (!android::base::ParseUint(argv[1], /*out*/&allocationSize)) {
-      std::cerr << "Failed to parse the allocation size (must be 0,MAX_SIZE_T)" << std::endl;
-      return 1;
-    }
-  } else {
-    allocationSize = kMemoryAllocationSize;
-  }
-
-  void* mem = malloc(allocationSize);
-  if (mem == nullptr) {
-    std::cerr << "Malloc failed" << std::endl;
-    return 1;
-  }
-
-  volatile int* imem = static_cast<int *>(mem);  // don't optimize out memory usage
-
-  size_t imemCount = allocationSize / sizeof(int);
-
-  std::cout << "Allocated " << allocationSize << " bytes" << std::endl;
-
-  auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
-  std::mt19937 mt_rand(seed);
-
-  size_t randPrintCount = 10;
-
-  // Write random numbers:
-  // * Ensures each page is resident
-  // * Avoids zeroed out pages (zRAM)
-  // * Avoids same-page merging
-  for (size_t i = 0; i < imemCount; ++i) {
-    imem[i] = mt_rand();
-
-    if (i < randPrintCount) {
-      std::cout << "Generated random value: " << imem[i] << std::endl;
-    }
-  }
-
-#if USE_MLOCKALL
-  /*
-   * Lock all pages from the address space of this process.
-   */
-  if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
-    std::cerr << "Mlockall failed" << std::endl;
-    return 1;
-  }
-#else
-  // Use mlock because of the predictable VmLck size.
-  // Using mlockall tends to bring in anywhere from 2-2.5GB depending on the device.
-  if (mlock(mem, allocationSize) != 0) {
-    std::cerr << "Mlock failed" << std::endl;
-    return 1;
-  }
-#endif
-
-  // Validate memory is actually resident and locked with:
-  // $> cat /proc/$(pidof iorap.stress.memory)/status | grep VmLck
-  std::cout << "Locked memory (VmLck) = " << GetProcessStatus("VmLck") << std::endl;
-
-  std::cout << "Press any key to terminate" << std::endl;
-  int any_input;
-  std::cin >> any_input;
-
-  std::cout << "Terminating..." << std::endl;
-
-  munlockall();
-  free(mem);
-
-  return 0;
-}
diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp
deleted file mode 100644
index ad3d001..0000000
--- a/startop/iorap/tests/Android.bp
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (C) 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// TODO: once b/80095087 is fixed, rewrite this back to android_test
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library {
-    name: "libiorap-java-test-lib",
-    srcs: ["src/**/*.kt"],
-    static_libs: [
-        // Non-test dependencies
-        // library under test
-        "services.startop.iorap",
-        // need the system_server code to be on the classpath,
-        "services.core",
-        // Test Dependencies
-        // test android dependencies
-        "platform-test-annotations",
-        "androidx.test.rules",
-        // test framework dependencies
-        "mockito-target-inline-minus-junit4",
-        // "mockito-target-minus-junit4",
-        // Mockito also requires JNI (see Android.mk)
-        // and android:debuggable=true (see AndroidManifest.xml)
-        "truth-prebuilt",
-    ],
-    // sdk_version: "current",
-    // certificate: "platform",
-    libs: [
-        "android.test.base",
-        "android.test.runner",
-    ],
-    // test_suites: ["device-tests"],
-}
-
-android_test {
-    name: "libiorap-java-tests",
-    dxflags: ["--multi-dex"],
-    test_suites: ["device-tests"],
-    static_libs: ["libiorap-java-test-lib"],
-    compile_multilib: "both",
-    jni_libs: [
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-        "libmultiplejvmtiagentsinterferenceagent",
-    ],
-    libs: [
-        "android.test.base",
-        "android.test.runner",
-    ],
-    // Use private APIs
-    certificate: "platform",
-    platform_apis: true,
-}
diff --git a/startop/iorap/tests/AndroidManifest.xml b/startop/iorap/tests/AndroidManifest.xml
deleted file mode 100644
index b967e72..0000000
--- a/startop/iorap/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<!--suppress AndroidUnknownAttribute -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.google.android.startop.iorap.tests"
-    android:sharedUserId="com.google.android.startop.iorap.tests"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <!--suppress AndroidDomInspection -->
-    <instrumentation
-        android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.google.android.startop.iorap.tests" />
-
-      <!--
-       'debuggable=true' is required to properly load mockito jvmti dependencies,
-         otherwise it gives the following error at runtime:
-
-       Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
-       Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-</manifest>
diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml
deleted file mode 100644
index 6102c44..0000000
--- a/startop/iorap/tests/AndroidTest.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<configuration description="Runs libiorap-java-tests.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-instrumentation" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="libiorap-java-tests.apk" />
-    </target_preparer>
-
-    <!--
-      Our IIorapIntegrationTest.kt requires setlinux to be disabled:
-      it connects to the iorapd binder service but this requires selinux permissions:
-
-      avc:  denied  { find } for service=iorapd pid=2738 uid=10050
-        scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:iorapd_service:s0
-        tclass=service_manager permissive=0
-    -->
-    <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer">
-    </target_preparer>
-
-    <!-- do not use DeviceSetup#set-property because it reboots the device b/136200738.
-         furthermore the changes in /data/local.prop don't actually seem to get picked up.
-    -->
-    <target_preparer
-        class="com.android.tradefed.targetprep.DeviceSetup">
-        <!-- we need this magic flag, otherwise it always reboots and breaks the selinux -->
-        <option name="force-skip-system-props" value="true" />
-
-        <!-- Crash instead of using Log.wtf within the system_server iorap code. -->
-        <option name="run-command" value="setprop iorapd.forwarding_service.wtf_crash true" />
-        <!-- IIorapd has fake behavior: it doesn't do anything but reply with 'DONE' status -->
-        <option name="run-command" value="setprop iorapd.binder.fake true" />
-
-        <!-- iorapd does not pick up the above changes until we restart it -->
-        <option name="run-command" value="stop iorapd" />
-        <option name="run-command" value="start iorapd" />
-        <!-- give it some time to restart the service; otherwise the first unit test might fail -->
-        <option name="run-command" value="sleep 1" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.google.android.startop.iorap.tests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-    </test>
-
-    <!-- using DeviceSetup again does not work. we simply leave the device in a semi-bad
-         state. there is no way to clean this up as far as I know.
-         -->
-
-</configuration>
-
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt
deleted file mode 100644
index 51e407d..0000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.google.android.startop.iorap
-
-import android.content.Intent;
-import android.net.Uri
-import android.os.Parcel
-import android.os.Parcelable
-import androidx.test.filters.SmallTest
-import com.google.android.startop.iorap.AppLaunchEvent;
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunched
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchCancelled
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchFinished
-import com.google.android.startop.iorap.AppLaunchEvent.IntentStarted;
-import com.google.android.startop.iorap.AppLaunchEvent.IntentFailed;
-import com.google.android.startop.iorap.AppLaunchEvent.ReportFullyDrawn
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-
-/**
- * Basic unit tests to test all of the [AppLaunchEvent]s in [com.google.android.startop.iorap].
- */
-@SmallTest
-class AppLaunchEventTest {
-  /**
-   * Test for IntentStarted.
-   */
-  @Test
-  fun testIntentStarted() {
-    var intent = Intent()
-    val valid = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L)
-    val copy = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L)
-    val noneCopy1 = IntentStarted(/* sequenceId= */1L, intent, /* timestampNs= */ 1L)
-    val noneCopy2 = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 2L)
-    val noneCopy3 = IntentStarted(/* sequenceId= */2L, Intent(), /* timestampNs= */ 1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("IntentStarted{sequenceId=2, intent=Intent {  } , timestampNs=1}")
-  }
-
-  /**
-   * Test for IntentFailed.
-   */
-  @Test
-  fun testIntentFailed() {
-    val valid = IntentFailed(/* sequenceId= */2L)
-    val copy = IntentFailed(/* sequenceId= */2L)
-    val noneCopy = IntentFailed(/* sequenceId= */1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("IntentFailed{sequenceId=2}")
-  }
-
-  /**
-   * Test for ActivityLaunched.
-   */
-  @Test
-  fun testActivityLaunched() {
-    //var activityRecord =
-    val valid = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(),
-      /* temperature= */ 0)
-    val copy = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(),
-      /* temperature= */ 0)
-    val noneCopy1 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(),
-      /* temperature= */ 0)
-    val noneCopy2 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(),
-      /* temperature= */ 1)
-    val noneCopy3 = ActivityLaunched(/* sequenceId= */1L, "test1".toByteArray(),
-      /* temperature= */ 0)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ActivityLaunched{sequenceId=2, test, temperature=0}")
-  }
-
-
-  /**
-   * Test for ActivityLaunchFinished.
-   */
-  @Test
-  fun testActivityLaunchFinished() {
-    val valid = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val copy = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy1 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy2 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 2L)
-    val noneCopy3 = ActivityLaunchFinished(/* sequenceId= */2L, "test1".toByteArray(),
-      /* timestampNs= */ 1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ActivityLaunchFinished{sequenceId=2, test, timestampNs=1}")
-  }
-
-  /**
-   * Test for ActivityLaunchCancelled.
-   */
-  @Test
-  fun testActivityLaunchCancelled() {
-    val valid = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray())
-    val copy = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray())
-    val noneCopy1 = ActivityLaunchCancelled(/* sequenceId= */1L, "test".toByteArray())
-    val noneCopy2 = ActivityLaunchCancelled(/* sequenceId= */2L, "test1".toByteArray())
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ActivityLaunchCancelled{sequenceId=2, test}")
-  }
-
-  /**
-   * Test for ReportFullyDrawn.
-   */
-  @Test
-  fun testReportFullyDrawn() {
-    val valid = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L)
-    val copy = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L)
-    val noneCopy1 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy2 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy3 = ReportFullyDrawn(/* sequenceId= */2L, "test1".toByteArray(),
-      /* timestampNs= */ 1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ReportFullyDrawn{sequenceId=2, test, timestampNs=1}")
-  }
-}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
deleted file mode 100644
index 18c2491..0000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.google.android.startop.iorap
-
-import android.net.Uri
-import android.os.ServiceManager
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.MediumTest
-import org.junit.Test
-import org.mockito.Mockito.argThat
-import org.mockito.Mockito.eq
-import org.mockito.Mockito.inOrder
-import org.mockito.Mockito.spy
-import org.mockito.Mockito.timeout
-
-// @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it")
-@MediumTest
-@FlakyTest(bugId = 149098310) // Failing on cuttlefish with SecurityException.
-class IIorapIntegrationTest {
-    /**
-     * @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found
-     */
-    private val iorapService: IIorap by lazy {
-        // TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply.
-        IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"))
-
-        // Use 'adb shell setenforce 0' otherwise this whole test fails,
-        // because the servicemanager is not allowed to hand out the binder token for iorapd.
-
-        // TODO: implement the selinux policies for iorapd.
-    }
-
-    // A dummy binder stub implementation is required to use with mockito#spy.
-    // Mockito overrides the methods at runtime and tracks how methods were invoked.
-    open class DummyTaskListener : ITaskListener.Stub() {
-        // Note: make parameters nullable to avoid the kotlin IllegalStateExceptions
-        // from using the mockito matchers (eq, argThat, etc).
-        override fun onProgress(requestId: RequestId?, result: TaskResult?) {
-        }
-
-        override fun onComplete(requestId: RequestId?, result: TaskResult?) {
-        }
-    }
-
-    private fun testAnyMethod(func: (RequestId) -> Unit) {
-        val taskListener = spy(DummyTaskListener())!!
-
-        // FIXME: b/149098310
-        return
-
-        try {
-            iorapService.setTaskListener(taskListener)
-            // Note: Binder guarantees total order for oneway messages sent to the same binder
-            // interface, so we don't need any additional blocking here before sending later calls.
-
-            // Every new method call should have a unique request id.
-            val requestId = RequestId.nextValueForSequence()!!
-
-            // Apply the specific function under test.
-            func(requestId)
-
-            // Typical mockito behavior is to allow any-order callbacks, but we want to test order.
-            val inOrder = inOrder(taskListener)
-
-            // The "stub" behavior of iorapd is that every request immediately gets a response of
-            //   BEGAN,ONGOING,COMPLETED
-            inOrder.verify(taskListener, timeout(100))
-                .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN })
-            inOrder.verify(taskListener, timeout(100))
-                .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING })
-            inOrder.verify(taskListener, timeout(100))
-                .onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED })
-            inOrder.verifyNoMoreInteractions()
-        } finally {
-            // iorapService.setTaskListener(null)
-            // FIXME: null is broken, C++ side sees a non-null object.
-        }
-    }
-
-    @Test
-    fun testOnPackageEvent() {
-        // FIXME (b/137134253): implement PackageEvent parsing on the C++ side.
-        // This is currently (silently: b/137135024) failing because IIorap is 'oneway' and the
-        // C++ PackageEvent un-parceling fails since its not implemented fully.
-        /*
-        testAnyMethod { requestId : RequestId ->
-            iorapService.onPackageEvent(requestId,
-                    PackageEvent.createReplaced(
-                            Uri.parse("https://www.google.com"), "com.fake.package"))
-        }
-        */
-    }
-
-    @Test
-    fun testOnAppIntentEvent() {
-        testAnyMethod { requestId: RequestId ->
-            iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged(
-                    ActivityInfo("dont care", "dont care"),
-                    ActivityInfo("dont care 2", "dont care 2")))
-        }
-    }
-
-    @Test
-    fun testOnAppLaunchEvent() {
-        testAnyMethod { requestId : RequestId ->
-            iorapService.onAppLaunchEvent(requestId, AppLaunchEvent.IntentFailed(/*sequenceId*/123))
-        }
-    }
-
-    @Test
-    fun testOnSystemServiceEvent() {
-        testAnyMethod { requestId: RequestId ->
-            iorapService.onSystemServiceEvent(requestId,
-                    SystemServiceEvent(SystemServiceEvent.TYPE_START))
-        }
-    }
-
-    @Test
-    fun testOnSystemServiceUserEvent() {
-        testAnyMethod { requestId: RequestId ->
-            iorapService.onSystemServiceUserEvent(requestId,
-                    SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 0))
-        }
-    }
-}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
deleted file mode 100644
index 150577a..0000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package com.google.android.startop.iorap
-
-import android.net.Uri
-import android.os.Parcel
-import android.os.Parcelable
-import androidx.test.filters.SmallTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import com.google.common.truth.Truth.assertThat
-import org.junit.runners.Parameterized
-
-/**
- * Basic unit tests to ensure that all of the [Parcelable]s in [com.google.android.startop.iorap]
- * have a valid-conforming interface implementation.
- */
-@SmallTest
-@RunWith(Parameterized::class)
-class ParcelablesTest<T : Parcelable>(private val inputData: InputData<T>) {
-    companion object {
-        private val initialRequestId = RequestId.nextValueForSequence()!!
-
-        @JvmStatic
-        @Parameterized.Parameters
-        fun data() = listOf(
-                InputData(
-                        newActivityInfo(),
-                        newActivityInfo(),
-                        ActivityInfo("some package", "some other activity")),
-                InputData(
-                        ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
-                        ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
-                        ActivityHintEvent(ActivityHintEvent.TYPE_POST_COMPLETED,
-                                newActivityInfo())),
-                InputData(
-                        AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
-                                newActivityInfoOther()),
-                        AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
-                                newActivityInfoOther()),
-                        AppIntentEvent.createDefaultIntentChanged(newActivityInfoOther(),
-                                newActivityInfo())),
-                InputData(
-                        PackageEvent.createReplaced(newUri(), "some package"),
-                        PackageEvent.createReplaced(newUri(), "some package"),
-                        PackageEvent.createReplaced(newUri(), "some other package")
-                ),
-                InputData(initialRequestId, cloneRequestId(initialRequestId),
-                        RequestId.nextValueForSequence()),
-                InputData(
-                        SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
-                        SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
-                        SystemServiceEvent(SystemServiceEvent.TYPE_START)),
-                InputData(
-                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
-                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
-                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_CLEANUP_USER, 12345)),
-                InputData(
-                        TaskResult(TaskResult.STATE_COMPLETED),
-                        TaskResult(TaskResult.STATE_COMPLETED),
-                        TaskResult(TaskResult.STATE_ONGOING))
-        )
-
-        private fun newActivityInfo(): ActivityInfo {
-            return ActivityInfo("some package", "some activity")
-        }
-
-        private fun newActivityInfoOther(): ActivityInfo {
-            return ActivityInfo("some package 2", "some activity 2")
-        }
-
-        private fun newUri(): Uri {
-            return Uri.parse("https://www.google.com")
-        }
-
-        private fun cloneRequestId(requestId: RequestId): RequestId {
-            val constructor = requestId::class.java.declaredConstructors[0]
-            constructor.isAccessible = true
-            return constructor.newInstance(requestId.requestId) as RequestId
-        }
-    }
-
-    /**
-     * Test for [Object.equals] implementation.
-     */
-    @Test
-    fun testEquality() {
-        assertThat(inputData.valid).isEqualTo(inputData.valid)
-        assertThat(inputData.valid).isEqualTo(inputData.validCopy)
-        assertThat(inputData.valid).isNotEqualTo(inputData.validOther)
-    }
-
-    /**
-     * Test for [Parcelable] implementation.
-     */
-    @Test
-    fun testParcelRoundTrip() {
-        // calling writeToParcel and then T::CREATOR.createFromParcel would return the same data.
-        val assertParcels = { it: T, data: InputData<T> ->
-            val parcel = Parcel.obtain()
-            it.writeToParcel(parcel, 0)
-            parcel.setDataPosition(0) // future reads will see all previous writes.
-            assertThat(it).isEqualTo(data.createFromParcel(parcel))
-            parcel.recycle()
-        }
-
-        assertParcels(inputData.valid, inputData)
-        assertParcels(inputData.validCopy, inputData)
-        assertParcels(inputData.validOther, inputData)
-    }
-
-    data class InputData<T : Parcelable>(val valid: T, val validCopy: T, val validOther: T) {
-        val kls = valid.javaClass
-        init {
-            assertThat(valid).isNotSameInstanceAs(validCopy)
-            // Don't use isInstanceOf because of phantom warnings in intellij about Class!
-            assertThat(validCopy.javaClass).isEqualTo(valid.javaClass)
-            assertThat(validOther.javaClass).isEqualTo(valid.javaClass)
-        }
-
-        fun createFromParcel(parcel: Parcel): T {
-            val field = kls.getDeclaredField("CREATOR")
-            val creator = field.get(null) as Parcelable.Creator<T>
-
-            return creator.createFromParcel(parcel)
-        }
-    }
-}
diff --git a/startop/scripts/app_startup/analyze_metrics.py b/startop/scripts/app_startup/analyze_metrics.py
deleted file mode 100755
index d74d6f6..0000000
--- a/startop/scripts/app_startup/analyze_metrics.py
+++ /dev/null
@@ -1,457 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Perform statistical analysis on measurements produced by app_startup_runner.py
-
-Install:
-$> sudo apt-get install python3-scipy
-
-Usage:
-$> ./analyze_metrics.py <filename.csv> [<filename2.csv> ...]
-$> ./analyze_metrics.py --help
-"""
-
-import argparse
-import csv
-import itertools
-import os
-import subprocess
-import sys
-import tempfile
-from typing import Any, List, Dict, Iterable, TextIO, Tuple
-
-from scipy import stats as sc
-import numpy as np
-
-
-# These CSV columns are considered labels. Everything after them in the same row are metrics.
-_LABEL_COLUMNS=['packages', 'readaheads', 'compiler_filters']
-# The metric series with the 'cold' readahead is the baseline.
-# All others (warm, jit, etc) are the potential improvements.
-
-#fixme: this should probably be an option
-_BASELINE=('readaheads', 'cold')
-# ignore this for some statistic calculations
-_IGNORE_PAIR=('readaheads', 'warm')
-_PLOT_SUBKEY='readaheads'
-_PLOT_GROUPKEY='packages'
-_PLOT_DATA_INDEX = 0
-_DELTA=50
-_DELTA2=100
-_PVALUE_THRESHOLD=0.10
-_debug = False  # See -d/--debug flag.
-
-def parse_options(argv: List[str] = None):
-  """Parse command line arguments and return an argparse Namespace object."""
-  parser = argparse.ArgumentParser(description="Perform statistical analysis on measurements produced by app_start_runner.py.")
-  parser.add_argument('input_files', metavar='file.csv', nargs='+', help='CSV file produced by app_startup_runner.py')
-
-  parser.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
-  parser.add_argument('-os', '--output-samples', dest='output_samples', default='/dev/null', action='store', help='Store CSV for per-sample data')
-  parser.add_argument('-oc', '--output-comparable', dest='output_comparable', default='/dev/null', action='store', help='Output CSV for comparable against baseline')
-  parser.add_argument('-ocs', '--output-comparable-significant', dest='output_comparable_significant', default='/dev/null', action='store', help='Output CSV for comparable against baseline (significant only)')
-  parser.add_argument('-pt', '--pvalue-threshold', dest='pvalue_threshold', type=float, default=_PVALUE_THRESHOLD, action='store')
-  parser.add_argument('-dt', '--delta-threshold', dest='delta_threshold', type=int, default=_DELTA, action='store')
-
-  return parser.parse_args(argv)
-
-def _debug_print(*args, **kwargs):
-  """Print the args to sys.stderr if the --debug/-d flag was passed in."""
-  global _debug
-  if _debug:
-    print(*args, **kwargs, file=sys.stderr)
-
-def _expand_gen_repr(args):
-  new_args_list = []
-  for i in args:
-    # detect iterable objects that do not have their own override of __str__
-    if hasattr(i, '__iter__'):
-      to_str = getattr(i, '__str__')
-      if to_str.__objclass__ == object:
-        # the repr for a generator is just type+address, expand it out instead.
-        new_args_list.append([_expand_gen_repr([j])[0] for j in i])
-        continue
-    # normal case: uses the built-in to-string
-    new_args_list.append(i)
-  return new_args_list
-
-def _debug_print_gen(*args, **kwargs):
-  """Like _debug_print but will turn any iterable args into a list."""
-  if not _debug:
-    return
-
-  new_args_list = _expand_gen_repr(args)
-  _debug_print(*new_args_list, **kwargs)
-
-def read_headers(input_file: TextIO) -> Tuple[List[str], List[str]]:
-  _debug_print("read_headers for file: ", input_file.name)
-  csv_reader = csv.reader(input_file)
-
-  label_num_columns = len(_LABEL_COLUMNS)
-
-  try:
-    header = next(csv_reader)
-  except StopIteration:
-    header = None
-  _debug_print('header', header)
-
-  if not header:
-    return (None, None)
-
-  labels = header[0:label_num_columns]
-  data = header[label_num_columns:]
-
-  return (labels, data)
-
-def read_labels_and_data(input_file: TextIO) -> Iterable[Tuple[List[str], List[int]]]:
-  _debug_print("print_analysis for file: ", input_file.name)
-  csv_reader = csv.reader(input_file)
-
-  # Skip the header because it doesn't contain any data.
-  # To get the header see read_headers function.
-  try:
-    header = next(csv_reader)
-  except StopIteration:
-    header = None
-
-  label_num_columns = len(_LABEL_COLUMNS)
-
-  for row in csv_reader:
-    if len(row) > 0 and row[0][0] == ';':
-      _debug_print("skip comment line", row)
-      continue
-
-    labels = row[0:label_num_columns]
-    data = [int(i) for i in row[label_num_columns:]]
-
-#    _debug_print("labels:", labels)
-#    _debug_print("data:", data)
-
-    yield (labels, data)
-
-def group_metrics_by_label(it: Iterable[Tuple[List[str], List[int]]]):
-  prev_labels = None
-  data_2d = []
-
-  for label_list, data_list in it:
-    if prev_labels != label_list:
-      if prev_labels:
-#        _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d)
-        yield (prev_labels, data_2d)
-      data_2d = []
-
-    data_2d.append(data_list)
-    prev_labels = label_list
-
-  if prev_labels:
-#    _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d)
-    yield (prev_labels, data_2d)
-
-def data_to_numpy(it: Iterable[Tuple[List[str], List[List[int]]]]) -> Iterable[Tuple[List[str], Any]]:
-  for label_list, data_2d in it:
-    yield (label_list, np.asarray(data_2d, dtype=int))
-
-def iterate_columns(np_data_2d):
-  for col in range(np_data_2d.shape[1]):
-    col_as_array = np_data_2d[:, col]
-    yield col_as_array
-
-def confidence_interval(np_data_2d, percent=0.95):
-  """
-  Given some data [[a,b,c],[d,e,f,]...]
-
-  We assume the same metric is in the column (e.g. [a,d])
-  and that data in the rows (e.g. [b,e]) are separate metric values.
-
-  We then calculate the CI for each metric individually returning it as a list of tuples.
-  """
-  arr = []
-  for col_2d in iterate_columns(np_data_2d):
-    mean = col_2d.mean()
-    sigma = col_2d.std()
-
-    ci = sc.norm.interval(percent, loc=mean, scale=sigma / np.sqrt(len(col_2d)))
-    arr.append(ci)
-
-  # TODO: This seems to be returning NaN when all the samples have the same exact value
-  # (e.g. stddev=0, which can trivially happen when sample count = 1).
-
-  return arr
-
-def print_analysis(it, label_header: List[str], data_header: List[str], output_samples: str):
-  print(label_header)
-
-  with open(output_samples, "w") as output_file:
-
-    csv_writer = csv.writer(output_file)
-    csv_writer.writerow(label_header + ['mean', 'std', 'confidence_interval_a', 'confidence_interval_b'])
-
-    for label_list, np_data_2d in it:
-      print("**********************")
-      print(label_list)
-      print()
-      print("      ", data_header)
-      # aggregate computation column-wise
-      print("Mean: ", np_data_2d.mean(axis=0))
-      print("Std:  ", np_data_2d.std(axis=0))
-      print("CI95%:", confidence_interval(np_data_2d))
-      print("SEM:  ", stats_standard_error_one(np_data_2d, axis=0))
-
-      #ci = confidence_interval(np_data_2d)[_PLOT_DATA_INDEX]
-      sem = stats_standard_error_one(np_data_2d, axis=0)[_PLOT_DATA_INDEX]
-      mean = np_data_2d.mean(axis=0)[_PLOT_DATA_INDEX]
-
-      ci = (mean - sem, mean + sem)
-
-      csv_writer.writerow(label_list + [mean, np_data_2d.std(axis=0)[_PLOT_DATA_INDEX], ci[0], ci[1]])
-
-def from_file_group_by_labels(input_file):
-  (label_header, data_header) = read_headers(input_file)
-  label_data_iter = read_labels_and_data(input_file)
-  grouped_iter = group_metrics_by_label(label_data_iter)
-  grouped_numpy_iter = data_to_numpy(grouped_iter)
-
-  return grouped_numpy_iter, label_header, data_header
-
-def list_without_index(list, index):
-  return list[:index] + list[index+1:]
-
-def group_by_without_baseline_key(grouped_numpy_iter, label_header):
-  """
-  Data is considered comparable if the only difference is the baseline key
-  (i.e. the readahead is different but the package, compilation filter, etc, are the same).
-
-  Returns iterator that's grouped by the non-baseline labels to an iterator of
-  (label_list, data_2d).
-  """
-  baseline_index = label_header.index(_BASELINE[0])
-
-  def get_label_without_baseline(tpl):
-    label_list, _ = tpl
-    return list_without_index(label_list, baseline_index)
-  # [['pkgname', 'compfilter', 'warm'], [data]]
-  # [['pkgname', 'compfilter', 'cold'], [data2]]
-  # [['pkgname2', 'compfilter', 'warm'], [data3]]
-  #
-  #   ->
-  # ( [['pkgname', 'compfilter', 'warm'], [data]]      # ignore baseline label change.
-  #   [['pkgname', 'compfilter', 'cold'], [data2]] ),  # split here because the pkgname changed.
-  # ( [['pkgname2', 'compfilter', 'warm'], [data3]] )
-  for group_info, it in itertools.groupby(grouped_numpy_iter, key = get_label_without_baseline):
-    yield it
-
-  # TODO: replace this messy manual iteration/grouping with pandas
-
-def iterate_comparable_metrics(without_baseline_iter, label_header):
-  baseline_index = label_header.index(_BASELINE[0])
-  baseline_value = _BASELINE[1]
-
-  _debug_print("iterate comparables")
-
-  def is_baseline_fun(tp):
-    ll, dat = tp
-    return ll[baseline_index] == baseline_value
-
-  # iterating here when everything but the baseline key is the same.
-  for it in without_baseline_iter:
-    it1, it2 = itertools.tee(it)
-
-    # find all the baseline data.
-    baseline_filter_it = filter(is_baseline_fun, it1)
-
-    # find non-baseline data.
-    nonbaseline_filter_it = itertools.filterfalse(is_baseline_fun, it2)
-
-    yield itertools.product(baseline_filter_it, nonbaseline_filter_it)
-
-def stats_standard_error_one(a, axis):
-  a_std = a.std(axis=axis, ddof=0)
-  a_len = a.shape[axis]
-
-  return a_std / np.sqrt(a_len)
-
-def stats_standard_error(a, b, axis):
-  a_std = a.std(axis=axis, ddof=0)
-  b_std = b.std(axis=axis, ddof=0)
-
-  a_len = a.shape[axis]
-  b_len = b.shape[axis]
-
-  temp1 = a_std*a_std/a_len
-  temp2 = b_std*b_std/b_len
-
-  return np.sqrt(temp1 + temp2)
-
-def stats_tvalue(a, b, axis, delta = 0):
-  a_mean = a.mean(axis=axis)
-  b_mean = b.mean(axis=axis)
-
-  return (a_mean - b_mean - delta) / stats_standard_error(a, b, axis)
-
-def stats_pvalue(a, b, axis, delta, left:bool = False):
-  """
-  Single-tailed 2-sample t-test.
-
-  Returns p-value for the null hypothesis: mean(a) - mean(b) >= delta.
-  :param a: numpy 2d array
-  :param b: numpy 2d array
-  :param axis: which axis to do the calculations across
-  :param delta: test value of mean differences
-  :param left: if true then use <= delta instead of >= delta
-  :return: p-value
-  """
-  # implement our own pvalue calculation because the built-in t-test (t,p values)
-  # only offer delta=0 , e.g. m1-m1 ? 0
-  # we are however interested in m1-m2 ? delta
-  t_value = stats_tvalue(a, b, axis, delta)
-
-  # 2-sample degrees of freedom is using the array sizes - 2.
-  dof = a.shape[axis] + b.shape[axis] - 2
-
-  if left:
-    # left tailed test. e.g. m1-m2 <= delta
-    return sc.t.cdf(t_value, dof)
-  else:
-    # right tailed test. e.g. m1-m2 >= delta
-    return sc.t.sf(t_value, dof)
-  # a left+right tailed test is a 2-tail t-test and can be done using ttest_ind for delta=0
-
-def print_comparable_analysis(comparable_metrics_iter, label_header, data_header, output_comparable: str, output_comparable_significant: str):
-  baseline_value = _BASELINE[1]
-  baseline_index = label_header.index(_BASELINE[0])
-
-  old_baseline_label_list = None
-  delta = _DELTA
-  filter_value = _IGNORE_PAIR[1]
-  filter_index = label_header.index(_IGNORE_PAIR[0])
-
-  pvalue_threshold = _PVALUE_THRESHOLD
-  ci_threshold = (1 - _PVALUE_THRESHOLD) * 100.0
-
-  with open(output_comparable, "w") as output_file:
-
-    csv_writer = csv.writer(output_file)
-    csv_writer.writerow(label_header + ['mean', 'mean_diff', 'sem', 'pvalue_2tailed', 'pvalue_gt%d' %(_DELTA), 'pvalue_gt%d' %(_DELTA2)])
-
-    print("------------------------------------------------------------------")
-    print("Comparison against the baseline %s = %s" %(_BASELINE, baseline_value))
-    print("--- Right-tailed t-test checks if the baseline >= current %s by at least %d" %(_BASELINE[0], delta))
-    print()
-
-    global_stats = {'better_than_delta': [], 'better_than_delta_p95': []}
-
-    for nested_it in comparable_metrics_iter:
-      print("************************")
-
-      better_than_delta = []
-      better_than_delta_p95 = []
-
-      saw_baseline_once = False
-
-      for ((baseline_label_list, baseline_np_data_2d), (rest_label_list, rest_np_data_2d)) in nested_it:
-        _debug_print("baseline_label_list:", baseline_label_list)
-        _debug_print("baseline_np_data_2d:", baseline_np_data_2d)
-        _debug_print("rest_label_list:", rest_label_list)
-        _debug_print("rest_np_data_2d:", rest_np_data_2d)
-
-        mean_diff = baseline_np_data_2d.mean(axis=0) - rest_np_data_2d.mean(axis=0)
-        # 2-sample 2-tailed t-test with delta=0
-        # e.g. "Is it true that usually the two sample means are different?"
-        t_statistic, t_pvalue = sc.ttest_ind(baseline_np_data_2d, rest_np_data_2d, axis=0)
-
-        # 2-sample 1-tailed t-test with delta=50
-        # e.g. "Is it true that usually the sample means better than 50ms?"
-        t2 = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta)
-        p2 = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta)
-
-        t2_b = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2)
-        p2_b = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2)
-
-        print("%s vs %s" %(rest_label_list, baseline_value))
-        print("                           ", data_header)
-        print("Mean Difference:           ", mean_diff)
-        print("T-test (2-tailed) != 0:      t=%s, p=%s" %(t_statistic, t_pvalue))
-        print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA, t2, p2))
-        print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA2, t2_b, p2_b))
-
-        def write_out_values(label_list, *args):
-          csv_writer.writerow(label_list + [i[_PLOT_DATA_INDEX] for i in args])
-
-        sem = stats_standard_error(baseline_np_data_2d, rest_np_data_2d, axis=0)
-        if saw_baseline_once == False:
-          saw_baseline_once = True
-          base_sem = stats_standard_error_one(baseline_np_data_2d, axis=0)
-          write_out_values(baseline_label_list, baseline_np_data_2d.mean(axis=0), [0], base_sem, [None], [None], [None])
-        write_out_values(rest_label_list, rest_np_data_2d.mean(axis=0), mean_diff, sem, t_pvalue, p2, p2_b)
-
-        # now do the global statistics aggregation
-
-        if rest_label_list[filter_index] == filter_value:
-          continue
-
-        if mean_diff > delta:
-          better_than_delta.append((mean_diff, p2, rest_label_list))
-
-          if p2 <= pvalue_threshold:
-            better_than_delta_p95.append((mean_diff, rest_label_list))
-
-      if better_than_delta:
-        global_stats['better_than_delta'].append(better_than_delta)
-      if better_than_delta_p95:
-        global_stats['better_than_delta_p95'].append(better_than_delta_p95)
-
-    print("------------------------")
-    print("Global statistics:")
-    print("//// Rows with %s=%s are ignored here." %_IGNORE_PAIR)
-    print("- # of results with mean diff better than delta(%d)       = %d" %(delta, len(global_stats['better_than_delta'])))
-    print("    > (meandiff, pvalue, labels)")
-    for i in global_stats['better_than_delta']:
-      print("    > %s" %i)
-    print("- # of results with mean diff better than delta(%d) CI%d%% = %d" %(delta, ci_threshold, len(global_stats['better_than_delta_p95'])))
-    print("    > (meandiff, labels)")
-    for i in global_stats['better_than_delta_p95']:
-      print("    > %s" %i)
-
-def main():
-  global _debug
-  global _DELTA
-  global _PVALUE_THRESHOLD
-
-  opts = parse_options()
-  _debug = opts.debug
-  _debug_print("parsed options: ", opts)
-
-  _PVALUE_THRESHOLD = opts.pvalue_threshold or _PVALUE_THRESHOLD
-
-  for file_name in opts.input_files:
-    with open(file_name, 'r') as input_file:
-      (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file)
-      print_analysis(grouped_numpy_iter, label_header, data_header, opts.output_samples)
-
-    with open(file_name, 'r') as input_file:
-      (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file)
-      without_baseline_iter = group_by_without_baseline_key(grouped_numpy_iter, label_header)
-      #_debug_print_gen(without_baseline_iter)
-
-      comparable_metrics_iter = iterate_comparable_metrics(without_baseline_iter, label_header)
-      print_comparable_analysis(comparable_metrics_iter, label_header, data_header, opts.output_comparable, opts.output_comparable_significant)
-
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/startop/scripts/app_startup/app_startup_runner.py b/startop/scripts/app_startup/app_startup_runner.py
deleted file mode 100755
index 25ee6f7..0000000
--- a/startop/scripts/app_startup/app_startup_runner.py
+++ /dev/null
@@ -1,393 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-#
-# Measure application start-up time by launching applications under various combinations.
-# See --help for more details.
-#
-#
-# Sample usage:
-# $> ./app_startup_runner.py -p com.google.android.calculator -r warm -r cold -lc 10  -o out.csv
-# $> ./analyze_metrics.py out.csv
-#
-#
-
-import argparse
-import csv
-import itertools
-import os
-import sys
-import tempfile
-from datetime import timedelta
-from typing import Any, Callable, Iterable, List, NamedTuple, TextIO, Tuple, \
-    TypeVar, Union, Optional
-
-# local import
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-import lib.cmd_utils as cmd_utils
-import lib.print_utils as print_utils
-from app_startup.run_app_with_prefetch import PrefetchAppRunner
-import app_startup.lib.args_utils as args_utils
-from app_startup.lib.data_frame import DataFrame
-from app_startup.lib.perfetto_trace_collector import PerfettoTraceCollector
-from iorap.compiler import CompilerType
-import iorap.compiler as compiler
-
-# The following command line options participate in the combinatorial generation.
-# All other arguments have a global effect.
-_COMBINATORIAL_OPTIONS = ['package', 'readahead', 'compiler_filter',
-                          'activity', 'trace_duration']
-_TRACING_READAHEADS = ['mlock', 'fadvise']
-_FORWARD_OPTIONS = {'loop_count': '--count'}
-_RUN_SCRIPT = os.path.join(os.path.dirname(os.path.realpath(__file__)),
-                           'run_app_with_prefetch.py')
-
-CollectorPackageInfo = NamedTuple('CollectorPackageInfo',
-                                  [('package', str), ('compiler_filter', str)])
-# by 2; systrace starts up slowly.
-
-_UNLOCK_SCREEN_SCRIPT = os.path.join(
-    os.path.dirname(os.path.realpath(__file__)), 'unlock_screen')
-
-RunCommandArgs = NamedTuple('RunCommandArgs',
-                            [('package', str),
-                             ('readahead', str),
-                             ('activity', Optional[str]),
-                             ('compiler_filter', Optional[str]),
-                             ('timeout', Optional[int]),
-                             ('debug', bool),
-                             ('simulate', bool),
-                             ('input', Optional[str]),
-                             ('trace_duration', Optional[timedelta])])
-
-# This must be the only mutable global variable. All other global variables are constants to avoid magic literals.
-_debug = False  # See -d/--debug flag.
-_DEBUG_FORCE = None  # Ignore -d/--debug if this is not none.
-_PERFETTO_TRACE_DURATION_MS = 5000 # milliseconds
-_PERFETTO_TRACE_DURATION = timedelta(milliseconds=_PERFETTO_TRACE_DURATION_MS)
-
-# Type hinting names.
-T = TypeVar('T')
-NamedTupleMeta = Callable[
-    ..., T]  # approximation of a (S : NamedTuple<T> where S() == T) metatype.
-
-def parse_options(argv: List[str] = None):
-  """Parse command line arguments and return an argparse Namespace object."""
-  parser = argparse.ArgumentParser(description="Run one or more Android "
-                                               "applications under various "
-                                               "settings in order to measure "
-                                               "startup time.")
-  # argparse considers args starting with - and -- optional in --help, even though required=True.
-  # by using a named argument group --help will clearly say that it's required instead of optional.
-  required_named = parser.add_argument_group('required named arguments')
-  required_named.add_argument('-p', '--package', action='append',
-                              dest='packages',
-                              help='package of the application', required=True)
-  required_named.add_argument('-r', '--readahead', action='append',
-                              dest='readaheads',
-                              help='which readahead mode to use',
-                              choices=('warm', 'cold', 'mlock', 'fadvise'),
-                              required=True)
-
-  # optional arguments
-  # use a group here to get the required arguments to appear 'above' the optional arguments in help.
-  optional_named = parser.add_argument_group('optional named arguments')
-  optional_named.add_argument('-c', '--compiler-filter', action='append',
-                              dest='compiler_filters',
-                              help='which compiler filter to use. if omitted it does not enforce the app\'s compiler filter',
-                              choices=('speed', 'speed-profile', 'quicken'))
-  optional_named.add_argument('-s', '--simulate', dest='simulate',
-                              action='store_true',
-                              help='Print which commands will run, but don\'t run the apps')
-  optional_named.add_argument('-d', '--debug', dest='debug',
-                              action='store_true',
-                              help='Add extra debugging output')
-  optional_named.add_argument('-o', '--output', dest='output', action='store',
-                              help='Write CSV output to file.')
-  optional_named.add_argument('-t', '--timeout', dest='timeout', action='store',
-                              type=int, default=10,
-                              help='Timeout after this many seconds when executing a single run.')
-  optional_named.add_argument('-lc', '--loop-count', dest='loop_count',
-                              default=1, type=int, action='store',
-                              help='How many times to loop a single run.')
-  optional_named.add_argument('-in', '--inodes', dest='inodes', type=str,
-                              action='store',
-                              help='Path to inodes file (system/extras/pagecache/pagecache.py -d inodes)')
-  optional_named.add_argument('--compiler-trace-duration-ms',
-                              dest='trace_duration',
-                              type=lambda ms_str: timedelta(milliseconds=int(ms_str)),
-                              action='append',
-                              help='The trace duration (milliseconds) in '
-                                   'compilation')
-  optional_named.add_argument('--compiler-type', dest='compiler_type',
-                              type=CompilerType, choices=list(CompilerType),
-                              default=CompilerType.DEVICE,
-                              help='The type of compiler.')
-
-  return parser.parse_args(argv)
-
-def key_to_cmdline_flag(key: str) -> str:
-  """Convert key into a command line flag, e.g. 'foo-bars' -> '--foo-bar' """
-  if key.endswith("s"):
-    key = key[:-1]
-  return "--" + key.replace("_", "-")
-
-def as_run_command(tpl: NamedTuple) -> List[Union[str, Any]]:
-  """
-  Convert a named tuple into a command-line compatible arguments list.
-
-  Example: ABC(1, 2, 3) -> ['--a', 1, '--b', 2, '--c', 3]
-  """
-  args = []
-  for key, value in tpl._asdict().items():
-    if value is None:
-      continue
-    args.append(key_to_cmdline_flag(key))
-    args.append(value)
-  return args
-
-def run_perfetto_collector(collector_info: CollectorPackageInfo,
-                           timeout: int,
-                           simulate: bool) -> Tuple[bool, TextIO]:
-  """Run collector to collect prefetching trace.
-
-  Returns:
-    A tuple of whether the collection succeeds and the generated trace file.
-  """
-  tmp_output_file = tempfile.NamedTemporaryFile()
-
-  collector = PerfettoTraceCollector(package=collector_info.package,
-                                     activity=None,
-                                     compiler_filter=collector_info.compiler_filter,
-                                     timeout=timeout,
-                                     simulate=simulate,
-                                     trace_duration=_PERFETTO_TRACE_DURATION,
-                                     save_destination_file_path=tmp_output_file.name)
-  result = collector.run()
-
-  return result is not None, tmp_output_file
-
-def parse_run_script_csv_file(csv_file: TextIO) -> DataFrame:
-  """Parse a CSV file full of integers into a DataFrame."""
-  csv_reader = csv.reader(csv_file)
-
-  try:
-    header_list = next(csv_reader)
-  except StopIteration:
-    header_list = []
-
-  if not header_list:
-    return None
-
-  headers = [i for i in header_list]
-
-  d = {}
-  for row in csv_reader:
-    header_idx = 0
-
-    for i in row:
-      v = i
-      if i:
-        v = int(i)
-
-      header_key = headers[header_idx]
-      l = d.get(header_key, [])
-      l.append(v)
-      d[header_key] = l
-
-      header_idx = header_idx + 1
-
-  return DataFrame(d)
-
-def build_ri_compiler_argv(inodes_path: str,
-                           perfetto_trace_file: str,
-                           trace_duration: Optional[timedelta]
-                           ) -> str:
-  argv = ['-i', inodes_path, '--perfetto-trace',
-          perfetto_trace_file]
-
-  if trace_duration is not None:
-    argv += ['--duration', str(int(trace_duration.total_seconds()
-                                   * PerfettoTraceCollector.MS_PER_SEC))]
-
-  print_utils.debug_print(argv)
-  return argv
-
-def execute_run_using_perfetto_trace(collector_info,
-                                     run_combos: Iterable[RunCommandArgs],
-                                     simulate: bool,
-                                     inodes_path: str,
-                                     timeout: int,
-                                     compiler_type: CompilerType,
-                                     requires_trace_collection: bool) -> DataFrame:
-  """ Executes run based on perfetto trace. """
-  if requires_trace_collection:
-    passed, perfetto_trace_file = run_perfetto_collector(collector_info,
-                                                         timeout,
-                                                         simulate)
-    if not passed:
-      raise RuntimeError('Cannot run perfetto collector!')
-  else:
-    perfetto_trace_file = tempfile.NamedTemporaryFile()
-
-  with perfetto_trace_file:
-    for combos in run_combos:
-      if combos.readahead in _TRACING_READAHEADS:
-        if simulate:
-          compiler_trace_file = tempfile.NamedTemporaryFile()
-        else:
-          ri_compiler_argv = build_ri_compiler_argv(inodes_path,
-                                                    perfetto_trace_file.name,
-                                                    combos.trace_duration)
-          compiler_trace_file = compiler.compile(compiler_type,
-                                                 inodes_path,
-                                                 ri_compiler_argv,
-                                                 combos.package,
-                                                 combos.activity)
-
-        with compiler_trace_file:
-          combos = combos._replace(input=compiler_trace_file.name)
-          print_utils.debug_print(combos)
-          output = PrefetchAppRunner(**combos._asdict()).run()
-      else:
-        print_utils.debug_print(combos)
-        output = PrefetchAppRunner(**combos._asdict()).run()
-
-      yield DataFrame(dict((x, [y]) for x, y in output)) if output else None
-
-def execute_run_combos(
-    grouped_run_combos: Iterable[Tuple[CollectorPackageInfo, Iterable[RunCommandArgs]]],
-    simulate: bool,
-    inodes_path: str,
-    timeout: int,
-    compiler_type: CompilerType,
-    requires_trace_collection: bool):
-  # nothing will work if the screen isn't unlocked first.
-  cmd_utils.execute_arbitrary_command([_UNLOCK_SCREEN_SCRIPT],
-                                      timeout,
-                                      simulate=simulate,
-                                      shell=False)
-
-  for collector_info, run_combos in grouped_run_combos:
-    yield from execute_run_using_perfetto_trace(collector_info,
-                                                run_combos,
-                                                simulate,
-                                                inodes_path,
-                                                timeout,
-                                                compiler_type,
-                                                requires_trace_collection)
-
-def gather_results(commands: Iterable[Tuple[DataFrame]],
-                   key_list: List[str], value_list: List[Tuple[str, ...]]):
-  print_utils.debug_print("gather_results: key_list = ", key_list)
-  stringify_none = lambda s: s is None and "<none>" or s
-  #  yield key_list + ["time(ms)"]
-  for (run_result_list, values) in itertools.zip_longest(commands, value_list):
-    print_utils.debug_print("run_result_list = ", run_result_list)
-    print_utils.debug_print("values = ", values)
-
-    if not run_result_list:
-      continue
-
-    # RunCommandArgs(package='com.whatever', readahead='warm', compiler_filter=None)
-    # -> {'package':['com.whatever'], 'readahead':['warm'], 'compiler_filter':[None]}
-    values_dict = {}
-    for k, v in values._asdict().items():
-      if not k in key_list:
-        continue
-      values_dict[k] = [stringify_none(v)]
-
-    values_df = DataFrame(values_dict)
-    # project 'values_df' to be same number of rows as run_result_list.
-    values_df = values_df.repeat(run_result_list.data_row_len)
-
-    # the results are added as right-hand-side columns onto the existing labels for the table.
-    values_df.merge_data_columns(run_result_list)
-
-    yield values_df
-
-def eval_and_save_to_csv(output, annotated_result_values):
-  printed_header = False
-
-  csv_writer = csv.writer(output)
-  for row in annotated_result_values:
-    if not printed_header:
-      headers = row.headers
-      csv_writer.writerow(headers)
-      printed_header = True
-      # TODO: what about when headers change?
-
-    for data_row in row.data_table:
-      data_row = [d for d in data_row]
-      csv_writer.writerow(data_row)
-
-    output.flush()  # see the output live.
-
-def coerce_to_list(opts: dict):
-  """Tranform values of the dictionary to list.
-  For example:
-  1 -> [1], None -> [None], [1,2,3] -> [1,2,3]
-  [[1],[2]] -> [[1],[2]], {1:1, 2:2} -> [{1:1, 2:2}]
-  """
-  result = {}
-  for key in opts:
-    val = opts[key]
-    result[key] = val if issubclass(type(val), list) else [val]
-  return result
-
-def main():
-  global _debug
-
-  opts = parse_options()
-  _debug = opts.debug
-  if _DEBUG_FORCE is not None:
-    _debug = _DEBUG_FORCE
-
-  print_utils.DEBUG = _debug
-  cmd_utils.SIMULATE = opts.simulate
-
-  print_utils.debug_print("parsed options: ", opts)
-
-  output_file = opts.output and open(opts.output, 'w') or sys.stdout
-
-  combos = lambda: args_utils.generate_run_combinations(
-      RunCommandArgs,
-      coerce_to_list(vars(opts)),
-      opts.loop_count)
-  print_utils.debug_print_gen("run combinations: ", combos())
-
-  grouped_combos = lambda: args_utils.generate_group_run_combinations(combos(),
-                                                                      CollectorPackageInfo)
-
-  print_utils.debug_print_gen("grouped run combinations: ", grouped_combos())
-  requires_trace_collection = any(i in _TRACING_READAHEADS for i in opts.readaheads)
-  exec = execute_run_combos(grouped_combos(),
-                            opts.simulate,
-                            opts.inodes,
-                            opts.timeout,
-                            opts.compiler_type,
-                            requires_trace_collection)
-
-  results = gather_results(exec, _COMBINATORIAL_OPTIONS, combos())
-
-  eval_and_save_to_csv(output_file, results)
-
-  return 1
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/startop/scripts/app_startup/app_startup_runner_test.py b/startop/scripts/app_startup/app_startup_runner_test.py
deleted file mode 100755
index 0c2bbea..0000000
--- a/startop/scripts/app_startup/app_startup_runner_test.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for the app_startup_runner.py script.
-
-Install:
-  $> sudo apt-get install python3-pytest   ##  OR
-  $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
-  $> ./app_startup_runner_test.py
-  $> pytest app_startup_runner_test.py
-  $> python -m pytest app_startup_runner_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-import io
-import shlex
-import sys
-import typing
-# global imports
-from contextlib import contextmanager
-
-# local imports
-import app_startup_runner as asr
-# pip imports
-import pytest
-
-#
-# Argument Parsing Helpers
-#
-
-@contextmanager
-def ignore_stdout_stderr():
-  """Ignore stdout/stderr output for duration of this context."""
-  old_stdout = sys.stdout
-  old_stderr = sys.stderr
-  sys.stdout = io.StringIO()
-  sys.stderr = io.StringIO()
-  try:
-    yield
-  finally:
-    sys.stdout = old_stdout
-    sys.stderr = old_stderr
-
-@contextmanager
-def argparse_bad_argument(msg):
-  """
-  Assert that a SystemExit is raised when executing this context.
-  If the assertion fails, print the message 'msg'.
-  """
-  with pytest.raises(SystemExit, message=msg):
-    with ignore_stdout_stderr():
-      yield
-
-def assert_bad_argument(args, msg):
-  """
-  Assert that the command line arguments in 'args' are malformed.
-  Prints 'msg' if the assertion fails.
-  """
-  with argparse_bad_argument(msg):
-    parse_args(args)
-
-def parse_args(args):
-  """
-  :param args: command-line like arguments as a single string
-  :return:  dictionary of parsed key/values
-  """
-  # "-a b -c d"    => ['-a', 'b', '-c', 'd']
-  return vars(asr.parse_options(shlex.split(args)))
-
-def default_dict_for_parsed_args(**kwargs):
-  """
-  # Combine it with all of the "optional" parameters' default values.
-  """
-  d = {'compiler_filters': None, 'simulate': False, 'debug': False,
-       'output': None, 'timeout': 10, 'loop_count': 1, 'inodes': None,
-       'trace_duration': None, 'compiler_type': asr.CompilerType.DEVICE}
-  d.update(kwargs)
-  return d
-
-def default_mock_dict_for_parsed_args(include_optional=True, **kwargs):
-  """
-  Combine default dict with all optional parameters with some mock required parameters.
-  """
-  d = {'packages': ['com.fake.package'], 'readaheads': ['warm']}
-  if include_optional:
-    d.update(default_dict_for_parsed_args())
-  d.update(kwargs)
-  return d
-
-def parse_optional_args(str):
-  """
-  Parse an argument string which already includes all the required arguments
-  in default_mock_dict_for_parsed_args.
-  """
-  req = "--package com.fake.package --readahead warm"
-  return parse_args("%s %s" % (req, str))
-
-def test_argparse():
-  # missing arguments
-  assert_bad_argument("", "-p and -r are required")
-  assert_bad_argument("-r warm", "-p is required")
-  assert_bad_argument("--readahead warm", "-p is required")
-  assert_bad_argument("-p com.fake.package", "-r is required")
-  assert_bad_argument("--package com.fake.package", "-r is required")
-
-  # required arguments are parsed correctly
-  ad = default_dict_for_parsed_args  # assert dict
-
-  assert parse_args("--package xyz --readahead warm") == ad(packages=['xyz'],
-                                                            readaheads=['warm'])
-  assert parse_args("-p xyz -r warm") == ad(packages=['xyz'],
-                                            readaheads=['warm'])
-
-  assert parse_args("-p xyz -r warm -s") == ad(packages=['xyz'],
-                                               readaheads=['warm'],
-                                               simulate=True)
-  assert parse_args("-p xyz -r warm --simulate") == ad(packages=['xyz'],
-                                                       readaheads=['warm'],
-                                                       simulate=True)
-
-  # optional arguments are parsed correctly.
-  mad = default_mock_dict_for_parsed_args  # mock assert dict
-  assert parse_optional_args("--output filename.csv") == mad(
-    output='filename.csv')
-  assert parse_optional_args("-o filename.csv") == mad(output='filename.csv')
-
-  assert parse_optional_args("--timeout 123") == mad(timeout=123)
-  assert parse_optional_args("-t 456") == mad(timeout=456)
-
-  assert parse_optional_args("--loop-count 123") == mad(loop_count=123)
-  assert parse_optional_args("-lc 456") == mad(loop_count=456)
-
-  assert parse_optional_args("--inodes bar") == mad(inodes="bar")
-  assert parse_optional_args("-in baz") == mad(inodes="baz")
-
-
-
-def test_key_to_cmdline_flag():
-  assert asr.key_to_cmdline_flag("abc") == "--abc"
-  assert asr.key_to_cmdline_flag("foos") == "--foo"
-  assert asr.key_to_cmdline_flag("ba_r") == "--ba-r"
-  assert asr.key_to_cmdline_flag("ba_zs") == "--ba-z"
-
-def test_parse_run_script_csv_file():
-  # empty file -> empty list
-  f = io.StringIO("")
-  assert asr.parse_run_script_csv_file(f) == None
-
-  # common case
-  f = io.StringIO("TotalTime_ms,Displayed_ms\n1,2")
-  df = asr.DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [2]})
-
-  pf = asr.parse_run_script_csv_file(f)
-  assert pf == df
-
-if __name__ == '__main__':
-  pytest.main()
diff --git a/startop/scripts/app_startup/force_compiler_filter b/startop/scripts/app_startup/force_compiler_filter
deleted file mode 100755
index 08f983d..0000000
--- a/startop/scripts/app_startup/force_compiler_filter
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# Forces an application APK to be compiled (by ART's dex2oat)
-# with a specific compiler filter.
-#
-# Example usage:
-#    $> ./force_compiler_filter -p com.google.android.apps.maps -c speed-profile
-#
-# (The application may be started/stopped as a side effect)
-#
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/lib/common"
-
-usage() {
-    cat <<EOF
-Usage: $(basename $0) [OPTION]...
-
-  Required:
-    -p, --package               package of the app to recompile
-    -c, --compiler-filter       override the compiler filter if set (default none)
-                                valid options are listed by: adb shell cmd package, under compile -m
-
-  Optional:
-    -a, --activity              activity of the app to recompile
-    -h, --help                  usage information (this)
-    -v, --verbose               enable extra verbose printing
-    -w, --wait_time             how long to wait for app startup (default 10) in seconds
-EOF
-}
-
-wait_time="10" # seconds
-
-parse_arguments() {
-  while [[ $# -gt 0 ]]; do
-    case "$1" in
-      -a|--activity)
-        activity="$2"
-        shift
-        ;;
-      -h|--help)
-        usage
-        exit 0
-        ;;
-      -p|--package)
-        package="$2"
-        shift
-        ;;
-      -w|--wait_time)
-        wait_time="$2"
-        shift
-        ;;
-      -c|--compiler-filter)
-        compiler_filter="$2"
-        shift
-        ;;
-      -v|--verbose)
-        verbose="y"
-        ;;
-    esac
-    shift
-  done
-
-  if [[ -z "$compiler_filter" ]]; then
-    echo "Missing required --compiler-filter" >&2
-    echo ""
-    usage
-    exit 1
-  fi
-  if [[ -z "$package" ]]; then
-    echo "Missing required --package" >&2
-    echo ""
-    usage
-    exit 1
-  fi
-
-  if [[ "$activity" == "" ]]; then
-    activity="$(get_activity_name "$package")"
-    if [[ "$activity" == "" ]]; then
-      echo "Activity name could not be found, invalid package name?" 1>&2
-      exit 1
-    else
-      verbose_print "Activity name inferred: " "$activity"
-    fi
-  fi
-}
-
-force_package_compilation() {
-  local arg_compiler_filter="$1"
-  local arg_package="$2"
-
-  if [[ $arg_compiler_filter == speed-profile ]]; then
-    # Force the running app to dump its profiles to disk.
-    remote_pkill "$arg_package" -SIGUSR1
-    sleep 1 # give some time for above to complete.
-  fi
-
-  adb shell cmd package compile -m "$arg_compiler_filter" -f "$arg_package"
-}
-
-main() {
-  parse_arguments "$@"
-
-  if [[ $compiler_filter == speed-profile ]]; then
-    # screen needs to be unlocked in order to run an app
-    "$DIR"/unlock_screen
-
-    local output=$("$DIR"/launch_application "$package" "$activity")
-    if [[ $? -ne 0 ]]; then
-      echo "launching application failed" >&2
-      exit 1
-    fi
-
-    verbose_print "$output"
-    # give some time for app startup to complete.
-    # this is supposed to be an upper bound for measuring startup time.
-    sleep "$wait_time"
-  fi
-
-  force_package_compilation "$compiler_filter" "$package"
-
-  # kill the application to ensure next time it's started,
-  # it picks up the correct compilation filter.
-  adb shell am force-stop "$package"
-  remote_pkill "$package"
-}
-
-main "$@"
diff --git a/startop/scripts/app_startup/launch_application b/startop/scripts/app_startup/launch_application
deleted file mode 100755
index 6704a5a..0000000
--- a/startop/scripts/app_startup/launch_application
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/lib/common"
-
-launch_application_usage() {
-    cat <<EOF
-Usage: $(basename $0) <package> <activity>
-
-  Positional Arguments:
-    <package>                   package of the app to test
-    <activity>                  activity to use
-
-  Named Arguments:
-    -h, --help                  usage information (this)
-EOF
-}
-
-launch_application() {
-  local package="$1"
-  local activity="$2"
-
-  # if there's any $s inside of the activity name, it needs to be escaped to \$.
-  # example '.app.honeycomb.Shell$HomeActivity'
-  # if the $ is not escaped, adb shell will try to evaluate $HomeActivity to a variable.
-  activity=${activity//\$/\\$}
-
-  adb shell am start -S -W "$package"/"$activity"
-
-  # pipe this into 'parse_metrics' to parse the output.
-}
-
-if [[ $# -lt 2 ]]; then
-  launch_application_usage
-  exit 1
-fi
-
-launch_application "$@"
diff --git a/startop/scripts/app_startup/lib/adb_utils.py b/startop/scripts/app_startup/lib/adb_utils.py
deleted file mode 100644
index 3cebc9a..0000000
--- a/startop/scripts/app_startup/lib/adb_utils.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Helper util libraries for calling adb command line."""
-
-import datetime
-import os
-import re
-import sys
-import time
-from typing import Optional
-
-sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
-  os.path.abspath(__file__)))))
-import lib.cmd_utils as cmd_utils
-import lib.logcat_utils as logcat_utils
-
-
-def logcat_save_timestamp() -> str:
-  """Gets the current logcat timestamp.
-
-  Returns:
-    A string of timestamp.
-  """
-  _, output = cmd_utils.run_adb_shell_command(
-    "date -u +\'%Y-%m-%d %H:%M:%S.%N\'")
-  return output
-
-def vm_drop_cache():
-  """Free pagecache and slab object."""
-  cmd_utils.run_adb_shell_command('echo 3 > /proc/sys/vm/drop_caches')
-  # Sleep a little bit to provide enough time for cache cleanup.
-  time.sleep(1)
-
-def root():
-  """Roots adb and successive adb commands will run under root."""
-  cmd_utils.run_shell_command('adb root')
-
-def disable_selinux():
-  """Disables selinux setting."""
-  _, output = cmd_utils.run_adb_shell_command('getenforce')
-  if output == 'Permissive':
-    return
-
-  print('Disable selinux permissions and restart framework.')
-  cmd_utils.run_adb_shell_command('setenforce 0')
-  cmd_utils.run_adb_shell_command('stop')
-  cmd_utils.run_adb_shell_command('start')
-  cmd_utils.run_shell_command('adb wait-for-device')
-
-def pkill(procname: str):
-  """Kills a process on device specified by the substring pattern in procname"""
-  _, pids = cmd_utils.run_shell_command('adb shell ps | grep "{}" | '
-                                        'awk \'{{print $2;}}\''.
-                                          format(procname))
-
-  for pid in pids.split('\n'):
-    pid = pid.strip()
-    if pid:
-      passed,_ = cmd_utils.run_adb_shell_command('kill {}'.format(pid))
-      time.sleep(1)
-
-def parse_time_to_milliseconds(time: str) -> int:
-  """Parses the time string to milliseconds."""
-  # Example: +1s56ms, +56ms
-  regex = r'\+((?P<second>\d+?)s)?(?P<millisecond>\d+?)ms'
-  result = re.search(regex, time)
-  second = 0
-  if result.group('second'):
-    second = int(result.group('second'))
-  ms = int(result.group('millisecond'))
-  return second * 1000 + ms
-
-def blocking_wait_for_logcat_displayed_time(timestamp: datetime.datetime,
-                                            package: str,
-                                            timeout: int) -> Optional[int]:
-  """Parses the displayed time in the logcat.
-
-  Returns:
-    the displayed time.
-  """
-  pattern = re.compile('.*ActivityTaskManager: Displayed {}.*'.format(package))
-  # 2019-07-02 22:28:34.469453349 -> 2019-07-02 22:28:34.469453
-  timestamp = datetime.datetime.strptime(timestamp[:-3],
-                                         '%Y-%m-%d %H:%M:%S.%f')
-  timeout_dt = timestamp + datetime.timedelta(0, timeout)
-  # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager:
-  # Displayed com.android.settings/.Settings: +927ms
-  result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
-                                                         pattern,
-                                                         timeout_dt)
-  if not result or not '+' in result:
-    return None
-  displayed_time = result[result.rfind('+'):]
-
-  return parse_time_to_milliseconds(displayed_time)
-
-def delete_file_on_device(file_path: str) -> None:
-  """ Deletes a file on the device. """
-  cmd_utils.run_adb_shell_command(
-    "[[ -f '{file_path}' ]] && rm -f '{file_path}' || "
-    "exit 0".format(file_path=file_path))
-
-def set_prop(property: str, value: str) -> None:
-  """ Sets property using adb shell. """
-  cmd_utils.run_adb_shell_command('setprop "{property}" "{value}"'.format(
-      property=property, value=value))
-
-def pull_file(device_file_path: str, output_file_path: str) -> None:
-  """ Pulls file from device to output """
-  cmd_utils.run_shell_command('adb pull "{device_file_path}" "{output_file_path}"'.
-      format(device_file_path=device_file_path,
-             output_file_path=output_file_path))
diff --git a/startop/scripts/app_startup/lib/adb_utils_test.py b/startop/scripts/app_startup/lib/adb_utils_test.py
deleted file mode 100644
index e590fed..0000000
--- a/startop/scripts/app_startup/lib/adb_utils_test.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import adb_utils
-
-# pip imports
-import pytest
-
-def test_parse_time_to_milliseconds():
-  # Act
-  result1 = adb_utils.parse_time_to_milliseconds('+1s7ms')
-  result2 = adb_utils.parse_time_to_milliseconds('+523ms')
-
-  # Assert
-  assert result1 == 1007
-  assert result2 == 523
-
-if __name__ == '__main__':
-  pytest.main()
diff --git a/startop/scripts/app_startup/lib/app_runner.py b/startop/scripts/app_startup/lib/app_runner.py
deleted file mode 100644
index 78873fa..0000000
--- a/startop/scripts/app_startup/lib/app_runner.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Class to run an app."""
-import os
-import sys
-from typing import Optional, List, Tuple
-
-# local import
-sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
-    os.path.abspath(__file__)))))
-
-import app_startup.lib.adb_utils as adb_utils
-import lib.cmd_utils as cmd_utils
-import lib.print_utils as print_utils
-
-class AppRunnerListener(object):
-  """Interface for lisenter of AppRunner. """
-
-  def preprocess(self) -> None:
-    """Preprocess callback to initialized before the app is running. """
-    pass
-
-  def postprocess(self, pre_launch_timestamp: str) -> None:
-    """Postprocess callback to cleanup after the app is running.
-
-      param:
-        'pre_launch_timestamp': indicates the timestamp when the app is
-        launching.. """
-    pass
-
-  def metrics_selector(self, am_start_output: str,
-                       pre_launch_timestamp: str) -> None:
-    """A metrics selection callback that waits for the desired metrics to
-      show up in logcat.
-      params:
-        'am_start_output': indicates the output of app startup.
-        'pre_launch_timestamp': indicates the timestamp when the app is
-                        launching.
-      returns:
-        a string in the format of "<metric>=<value>\n<metric>=<value>\n..."
-        for further parsing. For example "TotalTime=123\nDisplayedTime=121".
-        Return an empty string if no metrics need to be parsed further.
-        """
-    pass
-
-class AppRunner(object):
-  """ Class to run an app. """
-  # static variables
-  DIR = os.path.abspath(os.path.dirname(__file__))
-  APP_STARTUP_DIR = os.path.dirname(DIR)
-  IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(DIR,
-                                                           '../../iorap/common'))
-  DEFAULT_TIMEOUT = 30 # seconds
-
-  def __init__(self,
-               package: str,
-               activity: Optional[str],
-               compiler_filter: Optional[str],
-               timeout: Optional[int],
-               simulate: bool):
-    self.package = package
-    self.simulate = simulate
-
-    # If the argument activity is None, try to set it.
-    self.activity = activity
-    if self.simulate:
-      self.activity = 'act'
-    if self.activity is None:
-      self.activity = AppRunner.get_activity(self.package)
-
-    self.compiler_filter = compiler_filter
-    self.timeout = timeout if timeout else AppRunner.DEFAULT_TIMEOUT
-
-    self.listeners = []
-
-  def add_callbacks(self, listener: AppRunnerListener):
-    self.listeners.append(listener)
-
-  def remove_callbacks(self, listener: AppRunnerListener):
-    self.listeners.remove(listener)
-
-  @staticmethod
-  def get_activity(package: str) -> str:
-    """ Tries to set the activity based on the package. """
-    passed, activity = cmd_utils.run_shell_func(
-        AppRunner.IORAP_COMMON_BASH_SCRIPT,
-        'get_activity_name',
-        [package])
-
-    if not passed or not activity:
-      raise ValueError(
-          'Activity name could not be found, invalid package name?!')
-
-    return activity
-
-  def configure_compiler_filter(self) -> bool:
-    """Configures compiler filter (e.g. speed).
-
-    Returns:
-      A bool indicates whether configure of compiler filer succeeds or not.
-    """
-    if not self.compiler_filter:
-      print_utils.debug_print('No --compiler-filter specified, don\'t'
-                              ' need to force it.')
-      return True
-
-    passed, current_compiler_filter_info = \
-      cmd_utils.run_shell_command(
-          '{} --package {}'.format(os.path.join(AppRunner.APP_STARTUP_DIR,
-                                                'query_compiler_filter.py'),
-                                   self.package))
-
-    if passed != 0:
-      return passed
-
-    # TODO: call query_compiler_filter directly as a python function instead of
-    #  these shell calls.
-    current_compiler_filter, current_reason, current_isa = \
-      current_compiler_filter_info.split(' ')
-    print_utils.debug_print('Compiler Filter={} Reason={} Isa={}'.format(
-        current_compiler_filter, current_reason, current_isa))
-
-    # Don't trust reasons that aren't 'unknown' because that means
-    #  we didn't manually force the compilation filter.
-    # (e.g. if any automatic system-triggered compilations are not unknown).
-    if current_reason != 'unknown' or \
-        current_compiler_filter != self.compiler_filter:
-      passed, _ = adb_utils.run_shell_command('{}/force_compiler_filter '
-                                              '--compiler-filter "{}" '
-                                              '--package "{}"'
-                                              ' --activity "{}'.
-                                                format(AppRunner.APP_STARTUP_DIR,
-                                                       self.compiler_filter,
-                                                       self.package,
-                                                       self.activity))
-    else:
-      adb_utils.debug_print('Queried compiler-filter matched requested '
-                            'compiler-filter, skip forcing.')
-      passed = False
-    return passed
-
-  def run(self) -> Optional[List[Tuple[str]]]:
-    """Runs an app.
-
-    Returns:
-      A list of (metric, value) tuples.
-    """
-    print_utils.debug_print('==========================================')
-    print_utils.debug_print('=====             START              =====')
-    print_utils.debug_print('==========================================')
-    # Run the preprocess.
-    for listener in self.listeners:
-      listener.preprocess()
-
-    # Ensure the APK is currently compiled with whatever we passed in
-    # via --compiler-filter.
-    # No-op if this option was not passed in.
-    if not self.configure_compiler_filter():
-      print_utils.error_print('Compiler filter configuration failed!')
-      return None
-
-    pre_launch_timestamp = adb_utils.logcat_save_timestamp()
-    # Launch the app.
-    results = self.launch_app(pre_launch_timestamp)
-
-    # Run the postprocess.
-    for listener in self.listeners:
-      listener.postprocess(pre_launch_timestamp)
-
-    return results
-
-  def launch_app(self, pre_launch_timestamp: str) -> Optional[List[Tuple[str]]]:
-    """ Launches the app.
-
-        Returns:
-          A list of (metric, value) tuples.
-    """
-    print_utils.debug_print('Running with timeout {}'.format(self.timeout))
-
-    passed, am_start_output = cmd_utils.run_shell_command('timeout {timeout} '
-                                                 '"{DIR}/launch_application" '
-                                                 '"{package}" '
-                                                 '"{activity}"'.
-                                                   format(timeout=self.timeout,
-                                                          DIR=AppRunner.APP_STARTUP_DIR,
-                                                          package=self.package,
-                                                          activity=self.activity))
-    if not passed and not self.simulate:
-      return None
-
-    return self.wait_for_app_finish(pre_launch_timestamp, am_start_output)
-
-  def wait_for_app_finish(self,
-                          pre_launch_timestamp: str,
-                          am_start_output:  str) -> Optional[List[Tuple[str]]]:
-    """ Wait for app finish and all metrics are shown in logcat.
-
-    Returns:
-      A list of (metric, value) tuples.
-    """
-    if self.simulate:
-      return [('TotalTime', '123')]
-
-    ret = []
-    for listener in self.listeners:
-      output = listener.metrics_selector(am_start_output,
-                                         pre_launch_timestamp)
-      ret = ret + AppRunner.parse_metrics_output(output)
-
-    return ret
-
-  @staticmethod
-  def parse_metrics_output(input: str) -> List[
-    Tuple[str, str, str]]:
-    """Parses output of app startup to metrics and corresponding values.
-
-    It converts 'a=b\nc=d\ne=f\n...' into '[(a,b,''),(c,d,''),(e,f,'')]'
-
-    Returns:
-      A list of tuples that including metric name, metric value and rest info.
-    """
-    all_metrics = []
-    for line in input.split('\n'):
-      if not line:
-        continue
-      splits = line.split('=')
-      if len(splits) < 2:
-        print_utils.error_print('Bad line "{}"'.format(line))
-        continue
-      metric_name = splits[0]
-      metric_value = splits[1]
-      rest = splits[2] if len(splits) > 2 else ''
-      if rest:
-        print_utils.error_print('Corrupt line "{}"'.format(line))
-      print_utils.debug_print('metric: "{metric_name}", '
-                              'value: "{metric_value}" '.
-                                format(metric_name=metric_name,
-                                     metric_value=metric_value))
-
-      all_metrics.append((metric_name, metric_value))
-    return all_metrics
-
-  @staticmethod
-  def parse_total_time( am_start_output: str) -> Optional[str]:
-    """Parses the total time from 'adb shell am start pkg' output.
-
-    Returns:
-      the total time of app startup.
-    """
-    for line in am_start_output.split('\n'):
-      if 'TotalTime:' in line:
-        return line[len('TotalTime:'):].strip()
-    return None
-
diff --git a/startop/scripts/app_startup/lib/app_runner_test.py b/startop/scripts/app_startup/lib/app_runner_test.py
deleted file mode 100644
index 33d233b..0000000
--- a/startop/scripts/app_startup/lib/app_runner_test.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""Unit tests for the AppRunner."""
-import os
-import sys
-from pathlib import Path
-
-from app_runner import AppRunner, AppRunnerListener
-from mock import Mock, call, patch
-
-# The path is "frameworks/base/startop/scripts/"
-sys.path.append(Path(os.path.realpath(__file__)).parents[2])
-import lib.cmd_utils as cmd_utils
-
-class AppRunnerTestListener(AppRunnerListener):
-  def preprocess(self) -> None:
-    cmd_utils.run_shell_command('pre'),
-
-  def postprocess(self, pre_launch_timestamp: str) -> None:
-    cmd_utils.run_shell_command('post'),
-
-  def metrics_selector(self, am_start_output: str,
-                       pre_launch_timestamp: str) -> None:
-    return 'TotalTime=123\n'
-
-RUNNER = AppRunner(package='music',
-                   activity='MainActivity',
-                   compiler_filter='speed',
-                   timeout=None,
-                   simulate=False)
-
-
-
-def test_configure_compiler_filter():
-  with patch('lib.cmd_utils.run_shell_command',
-             new_callable=Mock) as mock_run_shell_command:
-    mock_run_shell_command.return_value = (True, 'speed arm64 kUpToDate')
-
-    RUNNER.configure_compiler_filter()
-
-    calls = [call(os.path.realpath(
-        os.path.join(RUNNER.DIR,
-                     '../query_compiler_filter.py')) + ' --package music')]
-    mock_run_shell_command.assert_has_calls(calls)
-
-def test_parse_metrics_output():
-  input = 'a1=b1\nc1=d1\ne1=f1'
-  ret = RUNNER.parse_metrics_output(input)
-
-  assert ret == [('a1', 'b1'), ('c1', 'd1'), ('e1', 'f1')]
-
-def _mocked_run_shell_command(*args, **kwargs):
-  if args[0] == 'adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"':
-    return (True, "2019-07-02 23:20:06.972674825")
-  elif args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
-    return (True, '9999')
-  else:
-    return (True, 'a1=b1\nc1=d1=d2\ne1=f1')
-
-@patch('app_startup.lib.adb_utils.blocking_wait_for_logcat_displayed_time')
-@patch('lib.cmd_utils.run_shell_command')
-def test_run(mock_run_shell_command,
-             mock_blocking_wait_for_logcat_displayed_time):
-  mock_run_shell_command.side_effect = _mocked_run_shell_command
-  mock_blocking_wait_for_logcat_displayed_time.return_value = 123
-
-  test_listener = AppRunnerTestListener()
-  RUNNER.add_callbacks(test_listener)
-
-  result = RUNNER.run()
-
-  RUNNER.remove_callbacks(test_listener)
-
-  calls = [call('pre'),
-           call(os.path.realpath(
-               os.path.join(RUNNER.DIR,
-                            '../query_compiler_filter.py')) +
-                ' --package music'),
-           call('adb shell "date -u +\'%Y-%m-%d %H:%M:%S.%N\'"'),
-           call(
-               'timeout {timeout} "{DIR}/launch_application" "{package}" "{activity}"'
-                 .format(timeout=30,
-                         DIR=os.path.realpath(os.path.dirname(RUNNER.DIR)),
-                         package='music',
-                         activity='MainActivity',
-                         timestamp='2019-07-02 23:20:06.972674825')),
-           call('post')
-           ]
-  mock_run_shell_command.assert_has_calls(calls)
-  assert result == [('TotalTime', '123')]
-  assert len(RUNNER.listeners) == 0
\ No newline at end of file
diff --git a/startop/scripts/app_startup/lib/args_utils.py b/startop/scripts/app_startup/lib/args_utils.py
deleted file mode 100644
index 080f3b5..0000000
--- a/startop/scripts/app_startup/lib/args_utils.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import itertools
-import os
-import sys
-from typing import Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, \
-    TypeVar, Optional
-
-# local import
-sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(
-    os.path.abspath(__file__)))))
-import lib.print_utils as print_utils
-
-T = TypeVar('T')
-NamedTupleMeta = Callable[
-    ..., T]  # approximation of a (S : NamedTuple<T> where S() == T) metatype.
-FilterFuncType = Callable[[NamedTuple], bool]
-
-def dict_lookup_any_key(dictionary: dict, *keys: List[Any]):
-  for k in keys:
-    if k in dictionary:
-      return dictionary[k]
-
-
-  print_utils.debug_print("None of the keys {} were in the dictionary".format(
-      keys))
-  return [None]
-
-def generate_run_combinations(named_tuple: NamedTupleMeta[T],
-                              opts_dict: Dict[str, List[Optional[object]]],
-                              loop_count: int = 1) -> Iterable[T]:
-  """
-  Create all possible combinations given the values in opts_dict[named_tuple._fields].
-
-  :type T: type annotation for the named_tuple type.
-  :param named_tuple: named tuple type, whose fields are used to make combinations for
-  :param opts_dict: dictionary of keys to value list. keys correspond to the named_tuple fields.
-  :param loop_count: number of repetitions.
-  :return: an iterable over named_tuple instances.
-  """
-  combinations_list = []
-  for k in named_tuple._fields:
-    # the key can be either singular or plural , e.g. 'package' or 'packages'
-    val = dict_lookup_any_key(opts_dict, k, k + "s")
-
-    # treat {'x': None} key value pairs as if it was [None]
-    # otherwise itertools.product throws an exception about not being able to iterate None.
-    combinations_list.append(val or [None])
-
-  print_utils.debug_print("opts_dict: ", opts_dict)
-  print_utils.debug_print_nd("named_tuple: ", named_tuple)
-  print_utils.debug_print("combinations_list: ", combinations_list)
-
-  for i in range(loop_count):
-    for combo in itertools.product(*combinations_list):
-      yield named_tuple(*combo)
-
-def filter_run_combinations(named_tuple: NamedTuple,
-                            filters: List[FilterFuncType]) -> bool:
-  for filter in filters:
-    if filter(named_tuple):
-      return False
-  return True
-
-def generate_group_run_combinations(run_combinations: Iterable[NamedTuple],
-                                    dst_nt: NamedTupleMeta[T]) \
-    -> Iterable[Tuple[T, Iterable[NamedTuple]]]:
-  def group_by_keys(src_nt):
-    src_d = src_nt._asdict()
-    # now remove the keys that aren't legal in dst.
-    for illegal_key in set(src_d.keys()) - set(dst_nt._fields):
-      if illegal_key in src_d:
-        del src_d[illegal_key]
-
-    return dst_nt(**src_d)
-
-  for args_list_it in itertools.groupby(run_combinations, group_by_keys):
-    (group_key_value, args_it) = args_list_it
-    yield (group_key_value, args_it)
diff --git a/startop/scripts/app_startup/lib/args_utils_test.py b/startop/scripts/app_startup/lib/args_utils_test.py
deleted file mode 100644
index 4b7e0fa..0000000
--- a/startop/scripts/app_startup/lib/args_utils_test.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""Unit tests for the args_utils.py script."""
-
-import typing
-
-import args_utils
-
-def generate_run_combinations(*args):
-  # expand out the generator values so that assert x == y works properly.
-  return [i for i in args_utils.generate_run_combinations(*args)]
-
-def test_generate_run_combinations():
-  blank_nd = typing.NamedTuple('Blank')
-  assert generate_run_combinations(blank_nd, {}, 1) == [()], "empty"
-  assert generate_run_combinations(blank_nd, {'a': ['a1', 'a2']}) == [
-    ()], "empty filter"
-  a_nd = typing.NamedTuple('A', [('a', str)])
-  assert generate_run_combinations(a_nd, {'a': None}) == [(None,)], "None"
-  assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}) == [('a1',), (
-    'a2',)], "one item"
-  assert generate_run_combinations(a_nd,
-                                   {'a': ['a1', 'a2'], 'b': ['b1', 'b2']}) == [
-           ('a1',), ('a2',)], \
-    "one item filter"
-  assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}, 2) == [('a1',), (
-    'a2',), ('a1',), ('a2',)], "one item"
-  ab_nd = typing.NamedTuple('AB', [('a', str), ('b', str)])
-  assert generate_run_combinations(ab_nd,
-                                   {'a': ['a1', 'a2'],
-                                    'b': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
-                                                            ab_nd('a1', 'b2'),
-                                                            ab_nd('a2', 'b1'),
-                                                            ab_nd('a2', 'b2')], \
-    "two items"
-
-  assert generate_run_combinations(ab_nd,
-                                   {'as': ['a1', 'a2'],
-                                    'bs': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
-                                                             ab_nd('a1', 'b2'),
-                                                             ab_nd('a2', 'b1'),
-                                                             ab_nd('a2', 'b2')], \
-    "two items plural"
diff --git a/startop/scripts/app_startup/lib/common b/startop/scripts/app_startup/lib/common
deleted file mode 100755
index bedaa1e..0000000
--- a/startop/scripts/app_startup/lib/common
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/bin/bash
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-if [[ -z $ANDROID_BUILD_TOP ]]; then
-  echo "Please run source build/envsetup.sh first" >&2
-  exit 1
-fi
-
-source $ANDROID_BUILD_TOP/build/envsetup.sh
-
-verbose_print() {
-  if [[ "$verbose" == "y" ]]; then
-    echo "$@" >&2
-  fi
-}
-
-remote_pidof() {
-  local procname="$1"
-  adb shell ps | grep "$procname" | awk '{print $2;}'
-}
-
-remote_pkill() {
-  local procname="$1"
-  shift
-
-  local the_pids=$(remote_pidof "$procname")
-  local pid
-
-  for pid in $the_pids; do
-    verbose_print adb shell kill "$@" "$pid"
-    adb shell kill "$@" "$pid"
-  done
-}
-
-get_activity_name() {
-  local package="$1"
-  local action_key="android.intent.action.MAIN:"
-
-  # Example query-activities output being parsed:
-  #
-  #  Activity #14:
-  #    priority=0 preferredOrder=0 match=0x108000 specificIndex=-1 isDefault=true
-  #    com.google.android.videos/com.google.android.youtube.videos.EntryPoint
-  #  Activity #15:
-  #    priority=0 preferredOrder=0 match=0x108000 specificIndex=-1 isDefault=true
-  #    com.google.android.youtube/.app.honeycomb.Shell$HomeActivity
-
-  # Given package 'com.google.android.youtube' return '.app.honeycomb.Shell$HomeActivity'
-
-  local activity_line="$(adb shell cmd package query-activities --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER | grep "$package/")"
-  IFS="/" read -a array <<< "$activity_line"
-  local activity_name="${array[1]}"
-
-  # Activities starting with '.' are shorthand for having their package name prefixed.
-  if [[ $activity_name == .* ]]; then
-    activity_name="${package}${activity_name}"
-  fi
-  echo "$activity_name"
-}
-
-# Use with logcat_from_timestamp to skip all past log-lines.
-logcat_save_timestamp() {
-  adb shell 'date -u +"%Y-%m-%d %H:%M:%S.%N"'
-}
-
-# Roll forward logcat to only show events
-# since the specified timestamp.
-#
-# i.e. don't look at historical logcat,
-# only look at FUTURE logcat.
-#
-# First use 'logcat_save_timestamp'
-# Then do whatever action you want.
-# Then use 'logcat_from_timestamp_bg $timestamp'
-logcat_from_timestamp_bg() {
-  local timestamp="$1"
-  shift # drop timestamp from args.
-  verbose_print adb logcat -T \"$timestamp\" \"$@\"
-  adb logcat -v UTC -T "$timestamp" "$@" &
-  logcat_from_timestamp_pid=$!
-}
-
-# Starting at timestamp $2, wait until we seen pattern $3
-# or until a timeout happens in $1 seconds.
-# If successful, also echo the line that matched the pattern.
-#
-# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
-logcat_select_pattern() {
-  local timeout="$1"
-  local timestamp="$2"
-  local pattern="$3"
-
-  local logcat_fd
-
-  coproc logcat_fd {
-    kill_children_quietly() {
-      kill "$logcat_pidd"
-      wait "$logcat_pidd" 2>/dev/null
-    }
-
-    trap 'kill_children_quietly' EXIT # kill logcat when this coproc is killed.
-
-    # run logcat in the background so it can be killed.
-    logcat_from_timestamp_bg "$timestamp"
-    logcat_pidd=$logcat_from_timestamp_pid
-    wait "$logcat_pidd"
-  }
-  local logcat_pid="$!"
-  verbose_print "[LOGCAT] Spawn pid $logcat_pid"
-
-  local timeout_ts="$(date -d "now + ${timeout} seconds" '+%s')"
-  local now_ts="0"
-
-  local return_code=1
-
-  verbose_print "logcat_wait_for_pattern begin"
-
-  while read -t "$timeout" -r -u "${logcat_fd[0]}" logcat_output; do
-    if (( $VERBOSE_LOGCAT )); then
-      verbose_print "LOGCAT: $logcat_output"
-    fi
-    if [[ "$logcat_output:" == *"$pattern"* ]]; then
-      verbose_print "LOGCAT: " "$logcat_output"
-      verbose_print "WE DID SEE PATTERN" '<<' "$pattern" '>>.'
-      echo "$logcat_output"
-      return_code=0
-      break
-    fi
-    now_ts="$(date -d "now" '+%s')"
-    if (( now_ts >= timeout_ts )); then
-      verbose_print "DID TIMEOUT BEFORE SEEING ANYTHING (timeout=$timeout seconds) " '<<' "$pattern" '>>.'
-      break
-    fi
-  done
-
-  # Don't leave logcat lying around since it will keep going.
-  kill "$logcat_pid"
-  # Suppress annoying 'Terminated...' message.
-  wait "$logcat_pid" 2>/dev/null
-
-  verbose_print "[LOGCAT] $logcat_pid should be killed"
-
-  return $return_code
-}
-
-# Starting at timestamp $2, wait until we seen pattern $3
-# or until a timeout happens in $1 seconds.
-#
-# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
-logcat_wait_for_pattern() {
-  logcat_select_pattern "$@" > /dev/null
-}
-
-# Starting at timestamp $2, wait until we seen pattern $3
-# or until a timeout happens in $1 seconds.
-# If successful, extract with the regular expression pattern in #4
-# and return the first capture group.
-#
-# Set VERBOSE_LOGCAT=1 to debug every line of logcat it tries to parse.
-logcat_extract_pattern() {
-  local timeout="$1"
-  local timestamp="$2"
-  local pattern="$3"
-  local re_pattern="$4"
-
-  local result
-  local exit_code
-
-  result="$(logcat_select_pattern "$@")"
-  exit_code=$?
-
-  if [[ $exit_code -ne 0 ]]; then
-    return $exit_code
-  fi
-
-  echo "$result" | sed 's/'"$re_pattern"'/\1/g'
-}
-
-# Join array
-#   FOO=(a b c)
-#   join_by , "${FOO[@]}" #a,b,c
-join_by() {
-  local IFS="$1"
-  shift
-  echo "$*"
-}
diff --git a/startop/scripts/app_startup/lib/data_frame.py b/startop/scripts/app_startup/lib/data_frame.py
deleted file mode 100644
index 20a2308..0000000
--- a/startop/scripts/app_startup/lib/data_frame.py
+++ /dev/null
@@ -1,201 +0,0 @@
-import itertools
-from typing import Dict, List
-
-class DataFrame:
-  """Table-like class for storing a 2D cells table with named columns."""
-  def __init__(self, data: Dict[str, List[object]] = {}):
-    """
-    Create a new DataFrame from a dictionary (keys = headers,
-    values = columns).
-    """
-    self._headers = [i for i in data.keys()]
-    self._rows = []
-
-    row_num = 0
-
-    def get_data_row(idx):
-      r = {}
-      for header, header_data in data.items():
-
-        if not len(header_data) > idx:
-          continue
-
-        r[header] = header_data[idx]
-
-      return r
-
-    while True:
-      row_dict = get_data_row(row_num)
-      if len(row_dict) == 0:
-        break
-
-      self._append_row(row_dict.keys(), row_dict.values())
-      row_num = row_num + 1
-
-  def concat_rows(self, other: 'DataFrame') -> None:
-    """
-    In-place concatenate rows of other into the rows of the
-    current DataFrame.
-
-    None is added in pre-existing cells if new headers
-    are introduced.
-    """
-    other_datas = other._data_only()
-
-    other_headers = other.headers
-
-    for d in other_datas:
-      self._append_row(other_headers, d)
-
-  def _append_row(self, headers: List[str], data: List[object]):
-    new_row = {k:v for k,v in zip(headers, data)}
-    self._rows.append(new_row)
-
-    for header in headers:
-      if not header in self._headers:
-        self._headers.append(header)
-
-  def __repr__(self):
-#     return repr(self._rows)
-    repr = ""
-
-    header_list = self._headers_only()
-
-    row_format = u""
-    for header in header_list:
-      row_format = row_format + u"{:>%d}" %(len(header) + 1)
-
-    repr = row_format.format(*header_list) + "\n"
-
-    for v in self._data_only():
-      repr = repr + row_format.format(*v) + "\n"
-
-    return repr
-
-  def __eq__(self, other):
-    if isinstance(other, self.__class__):
-      return self.headers == other.headers and self.data_table == other.data_table
-    else:
-      print("wrong instance", other.__class__)
-      return False
-
-  @property
-  def headers(self) -> List[str]:
-    return [i for i in self._headers_only()]
-
-  @property
-  def data_table(self) -> List[List[object]]:
-    return list(self._data_only())
-
-  @property
-  def data_table_transposed(self) -> List[List[object]]:
-    return list(self._transposed_data())
-
-  @property
-  def data_row_len(self) -> int:
-    return len(self._rows)
-
-  def data_row_at(self, idx) -> List[object]:
-    """
-    Return a single data row at the specified index (0th based).
-
-    Accepts negative indices, e.g. -1 is last row.
-    """
-    row_dict = self._rows[idx]
-    l = []
-
-    for h in self._headers_only():
-      l.append(row_dict.get(h)) # Adds None in blank spots.
-
-    return l
-
-  def copy(self) -> 'DataFrame':
-    """
-    Shallow copy of this DataFrame.
-    """
-    return self.repeat(count=0)
-
-  def repeat(self, count: int) -> 'DataFrame':
-    """
-    Returns a new DataFrame where each row of this dataframe is repeated count times.
-    A repeat of a row is adjacent to other repeats of that same row.
-    """
-    df = DataFrame()
-    df._headers = self._headers.copy()
-
-    rows = []
-    for row in self._rows:
-      for i in range(count):
-        rows.append(row.copy())
-
-    df._rows = rows
-
-    return df
-
-  def merge_data_columns(self, other: 'DataFrame'):
-    """
-    Merge self and another DataFrame by adding the data from other column-wise.
-    For any headers that are the same, data from 'other' is preferred.
-    """
-    for h in other._headers:
-      if not h in self._headers:
-        self._headers.append(h)
-
-    append_rows = []
-
-    for self_dict, other_dict in itertools.zip_longest(self._rows, other._rows):
-      if not self_dict:
-        d = {}
-        append_rows.append(d)
-      else:
-        d = self_dict
-
-      d_other = other_dict
-      if d_other:
-        for k,v in d_other.items():
-          d[k] = v
-
-    for r in append_rows:
-      self._rows.append(r)
-
-  def data_row_reduce(self, fnc) -> 'DataFrame':
-    """
-    Reduces the data row-wise by applying the fnc to each row (column-wise).
-    Empty cells are skipped.
-
-    fnc(Iterable[object]) -> object
-    fnc is applied over every non-empty cell in that column (descending row-wise).
-
-    Example:
-      DataFrame({'a':[1,2,3]}).data_row_reduce(sum) == DataFrame({'a':[6]})
-
-    Returns a new single-row DataFrame.
-    """
-    df = DataFrame()
-    df._headers = self._headers.copy()
-
-    def yield_by_column(header_key):
-      for row_dict in self._rows:
-        val = row_dict.get(header_key)
-        if val:
-          yield val
-
-    new_row_dict = {}
-    for h in df._headers:
-      cell_value = fnc(yield_by_column(h))
-      new_row_dict[h] = cell_value
-
-    df._rows = [new_row_dict]
-    return df
-
-  def _headers_only(self):
-    return self._headers
-
-  def _data_only(self):
-    row_len = len(self._rows)
-
-    for i in range(row_len):
-      yield self.data_row_at(i)
-
-  def _transposed_data(self):
-    return zip(*self._data_only())
\ No newline at end of file
diff --git a/startop/scripts/app_startup/lib/data_frame_test.py b/startop/scripts/app_startup/lib/data_frame_test.py
deleted file mode 100644
index 1cbc1cb..0000000
--- a/startop/scripts/app_startup/lib/data_frame_test.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""Unit tests for the data_frame.py script."""
-
-from data_frame import DataFrame
-
-def test_data_frame():
-  # trivial empty data frame
-  df = DataFrame()
-  assert df.headers == []
-  assert df.data_table == []
-  assert df.data_table_transposed == []
-
-  # common case, same number of values in each place.
-  df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
-  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
-  assert df.data_table == [[1, 4], [2, 5], [3, 6]]
-  assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)]
-
-  # varying num values.
-  df = DataFrame({'many': [1, 2], 'none': []})
-  assert df.headers == ['many', 'none']
-  assert df.data_table == [[1, None], [2, None]]
-  assert df.data_table_transposed == [(1, 2), (None, None)]
-
-  df = DataFrame({'many': [], 'none': [1, 2]})
-  assert df.headers == ['many', 'none']
-  assert df.data_table == [[None, 1], [None, 2]]
-  assert df.data_table_transposed == [(None, None), (1, 2)]
-
-  # merge multiple data frames
-  df = DataFrame()
-  df.concat_rows(DataFrame())
-  assert df.headers == []
-  assert df.data_table == []
-  assert df.data_table_transposed == []
-
-  df = DataFrame()
-  df2 = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
-
-  df.concat_rows(df2)
-  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
-  assert df.data_table == [[1, 4], [2, 5], [3, 6]]
-  assert df.data_table_transposed == [(1, 2, 3), (4, 5, 6)]
-
-  df = DataFrame({'TotalTime_ms': [1, 2]})
-  df2 = DataFrame({'Displayed_ms': [4, 5]})
-
-  df.concat_rows(df2)
-  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
-  assert df.data_table == [[1, None], [2, None], [None, 4], [None, 5]]
-
-  df = DataFrame({'TotalTime_ms': [1, 2]})
-  df2 = DataFrame({'TotalTime_ms': [3, 4], 'Displayed_ms': [5, 6]})
-
-  df.concat_rows(df2)
-  assert df.headers == ['TotalTime_ms', 'Displayed_ms']
-  assert df.data_table == [[1, None], [2, None], [3, 5], [4, 6]]
-
-  # data_row_at
-  df = DataFrame({'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [4, 5, 6]})
-  assert df.data_row_at(-1) == [3, 6]
-  assert df.data_row_at(2) == [3, 6]
-  assert df.data_row_at(1) == [2, 5]
-
-  # repeat
-  df = DataFrame({'TotalTime_ms': [1], 'Displayed_ms': [4]})
-  df2 = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
-  assert df.repeat(3) == df2
-
-  # repeat
-  df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
-  assert df.data_row_len == 3
-  df = DataFrame({'TotalTime_ms': [1, 1]})
-  assert df.data_row_len == 2
-
-  # repeat
-  df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
-  assert df.data_row_len == 3
-  df = DataFrame({'TotalTime_ms': [1, 1]})
-  assert df.data_row_len == 2
-
-  # data_row_reduce
-  df = DataFrame({'TotalTime_ms': [1, 1, 1], 'Displayed_ms': [4, 4, 4]})
-  df_sum = DataFrame({'TotalTime_ms': [3], 'Displayed_ms': [12]})
-  assert df.data_row_reduce(sum) == df_sum
-
-  # merge_data_columns
-  df = DataFrame({'TotalTime_ms': [1, 2, 3]})
-  df2 = DataFrame({'Displayed_ms': [3, 4, 5, 6]})
-
-  df.merge_data_columns(df2)
-  assert df == DataFrame(
-    {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4, 5, 6]})
-
-  df = DataFrame({'TotalTime_ms': [1, 2, 3]})
-  df2 = DataFrame({'Displayed_ms': [3, 4]})
-
-  df.merge_data_columns(df2)
-  assert df == DataFrame(
-    {'TotalTime_ms': [1, 2, 3], 'Displayed_ms': [3, 4]})
-
-  df = DataFrame({'TotalTime_ms': [1, 2, 3]})
-  df2 = DataFrame({'TotalTime_ms': [10, 11]})
-
-  df.merge_data_columns(df2)
-  assert df == DataFrame({'TotalTime_ms': [10, 11, 3]})
-
-  df = DataFrame({'TotalTime_ms': []})
-  df2 = DataFrame({'TotalTime_ms': [10, 11]})
-
-  df.merge_data_columns(df2)
-  assert df == DataFrame({'TotalTime_ms': [10, 11]})
diff --git a/startop/scripts/app_startup/lib/perfetto_trace_collector.py b/startop/scripts/app_startup/lib/perfetto_trace_collector.py
deleted file mode 100644
index 9ffb349..0000000
--- a/startop/scripts/app_startup/lib/perfetto_trace_collector.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Class to collector perfetto trace."""
-import datetime
-import os
-import re
-import sys
-import time
-from datetime import timedelta
-from typing import Optional, List, Tuple
-
-# global variables
-DIR = os.path.abspath(os.path.dirname(__file__))
-
-sys.path.append(os.path.dirname(os.path.dirname(DIR)))
-
-import app_startup.lib.adb_utils as adb_utils
-from app_startup.lib.app_runner import AppRunner, AppRunnerListener
-import lib.print_utils as print_utils
-import lib.logcat_utils as logcat_utils
-import iorap.lib.iorapd_utils as iorapd_utils
-
-class PerfettoTraceCollector(AppRunnerListener):
-  """ Class to collect perfetto trace.
-
-      To set trace duration of perfetto, change the 'trace_duration_ms'.
-      To pull the generated perfetto trace on device, set the 'output'.
-  """
-  TRACE_FILE_SUFFIX = 'perfetto_trace.pb'
-  TRACE_DURATION_PROP = 'iorapd.perfetto.trace_duration_ms'
-  MS_PER_SEC  = 1000
-  DEFAULT_TRACE_DURATION = timedelta(milliseconds=5000) # 5 seconds
-  _COLLECTOR_TIMEOUT_MULTIPLIER = 10  # take the regular timeout and multiply
-
-  def __init__(self,
-               package: str,
-               activity: Optional[str],
-               compiler_filter: Optional[str],
-               timeout: Optional[int],
-               simulate: bool,
-               trace_duration: timedelta = DEFAULT_TRACE_DURATION,
-               save_destination_file_path: Optional[str] = None):
-    """ Initialize the perfetto trace collector. """
-    self.app_runner = AppRunner(package,
-                                activity,
-                                compiler_filter,
-                                timeout,
-                                simulate)
-    self.app_runner.add_callbacks(self)
-
-    self.trace_duration = trace_duration
-    self.save_destination_file_path = save_destination_file_path
-
-  def purge_file(self, suffix: str) -> None:
-    print_utils.debug_print('iorapd-perfetto: purge file in ' +
-                            self._get_remote_path())
-    adb_utils.delete_file_on_device(self._get_remote_path())
-
-  def run(self) -> Optional[List[Tuple[str]]]:
-    """Runs an app.
-
-    Returns:
-      A list of (metric, value) tuples.
-    """
-    return self.app_runner.run()
-
-  def preprocess(self):
-    # Sets up adb environment.
-    adb_utils.root()
-    adb_utils.disable_selinux()
-    time.sleep(1)
-
-    # Kill any existing process of this app
-    adb_utils.pkill(self.app_runner.package)
-
-    # Remove existing trace and compiler files
-    self.purge_file(PerfettoTraceCollector.TRACE_FILE_SUFFIX)
-
-    # Set perfetto trace duration prop to milliseconds.
-    adb_utils.set_prop(PerfettoTraceCollector.TRACE_DURATION_PROP,
-                       int(self.trace_duration.total_seconds()*
-                           PerfettoTraceCollector.MS_PER_SEC))
-
-    if not iorapd_utils.stop_iorapd():
-      raise RuntimeError('Cannot stop iorapd!')
-
-    if not iorapd_utils.enable_iorapd_perfetto():
-      raise RuntimeError('Cannot enable perfetto!')
-
-    if not iorapd_utils.disable_iorapd_readahead():
-      raise RuntimeError('Cannot disable readahead!')
-
-    if not iorapd_utils.start_iorapd():
-      raise RuntimeError('Cannot start iorapd!')
-
-    # Drop all caches to get cold starts.
-    adb_utils.vm_drop_cache()
-
-  def postprocess(self, pre_launch_timestamp: str):
-    # Kill any existing process of this app
-    adb_utils.pkill(self.app_runner.package)
-
-    iorapd_utils.disable_iorapd_perfetto()
-
-    if self.save_destination_file_path is not None:
-      adb_utils.pull_file(self._get_remote_path(),
-                          self.save_destination_file_path)
-
-  def metrics_selector(self, am_start_output: str,
-                       pre_launch_timestamp: str) -> str:
-    """Parses the metric after app startup by reading from logcat in a blocking
-    manner until all metrics have been found".
-
-    Returns:
-      An empty string because the metric needs no further parsing.
-    """
-    if not self._wait_for_perfetto_trace(pre_launch_timestamp):
-      raise RuntimeError('Could not save perfetto app trace file!')
-
-    return ''
-
-  def _wait_for_perfetto_trace(self, pre_launch_timestamp) -> Optional[str]:
-    """ Waits for the perfetto trace being saved to file.
-
-    The string is in the format of r".*Perfetto TraceBuffer saved to file:
-    <file path>.*"
-
-    Returns:
-      the string what the program waits for. If the string doesn't show up,
-      return None.
-    """
-    pattern = re.compile(r'.*Perfetto TraceBuffer saved to file: {}.*'.
-                         format(self._get_remote_path()))
-
-    # The pre_launch_timestamp is longer than what the datetime can parse. Trim
-    # last three digits to make them align. For example:
-    # 2019-07-02 23:20:06.972674825999 -> 2019-07-02 23:20:06.972674825
-    assert len(pre_launch_timestamp) == len('2019-07-02 23:20:06.972674825')
-    timestamp = datetime.datetime.strptime(pre_launch_timestamp[:-3],
-                                           '%Y-%m-%d %H:%M:%S.%f')
-
-    # The timeout of perfetto trace is longer than the normal app run timeout.
-    timeout_dt = self.app_runner.timeout * PerfettoTraceCollector._COLLECTOR_TIMEOUT_MULTIPLIER
-    timeout_end = timestamp + datetime.timedelta(seconds=timeout_dt)
-
-    return logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
-                                                         pattern,
-                                                         timeout_end)
-
-  def _get_remote_path(self):
-    # For example: android.music%2Fmusic.TopLevelActivity.perfetto_trace.pb
-    return iorapd_utils._iorapd_path_to_data_file(self.app_runner.package,
-                                                  self.app_runner.activity,
-                                                  PerfettoTraceCollector.TRACE_FILE_SUFFIX)
diff --git a/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py b/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py
deleted file mode 100644
index 8d94fc5..0000000
--- a/startop/scripts/app_startup/lib/perfetto_trace_collector_test.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""Unit tests for the data_frame.py script."""
-import os
-import sys
-from pathlib import Path
-from datetime import timedelta
-
-from mock import call, patch
-from perfetto_trace_collector import PerfettoTraceCollector
-
-sys.path.append(Path(os.path.realpath(__file__)).parents[2])
-from app_startup.lib.app_runner import AppRunner
-
-RUNNER = PerfettoTraceCollector(package='music',
-                                activity='MainActivity',
-                                compiler_filter=None,
-                                timeout=10,
-                                simulate=False,
-                                trace_duration = timedelta(milliseconds=1000),
-                                # No actual file will be created. Just to
-                                # check the command.
-                                save_destination_file_path='/tmp/trace.pb')
-
-def _mocked_run_shell_command(*args, **kwargs):
-  if args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
-    return (True, '9999')
-  else:
-    return (True, '')
-
-@patch('lib.logcat_utils.blocking_wait_for_logcat_pattern')
-@patch('lib.cmd_utils.run_shell_command')
-def test_perfetto_trace_collector_preprocess(mock_run_shell_command,
-                                             mock_blocking_wait_for_logcat_pattern):
-  mock_run_shell_command.side_effect = _mocked_run_shell_command
-  mock_blocking_wait_for_logcat_pattern.return_value = "Succeed!"
-
-  RUNNER.preprocess()
-
-  calls = [call('adb root'),
-           call('adb shell "getenforce"'),
-           call('adb shell "setenforce 0"'),
-           call('adb shell "stop"'),
-           call('adb shell "start"'),
-           call('adb wait-for-device'),
-           call('adb shell ps | grep "music" | awk \'{print $2;}\''),
-           call('adb shell "kill 9999"'),
-           call(
-               'adb shell "[[ -f \'/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb\' ]] '
-               '&& rm -f \'/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb\' || exit 0"'),
-           call('adb shell "setprop "iorapd.perfetto.trace_duration_ms" "1000""'),
-           call(
-               'bash -c "source {}; iorapd_stop"'.format(
-                   AppRunner.IORAP_COMMON_BASH_SCRIPT)),
-           call(
-               'bash -c "source {}; iorapd_perfetto_enable"'.format(
-                   AppRunner.IORAP_COMMON_BASH_SCRIPT)),
-           call(
-               'bash -c "source {}; iorapd_readahead_disable"'.format(
-                   AppRunner.IORAP_COMMON_BASH_SCRIPT)),
-           call(
-               'bash -c "source {}; iorapd_start"'.format(
-                   AppRunner.IORAP_COMMON_BASH_SCRIPT)),
-           call('adb shell "echo 3 > /proc/sys/vm/drop_caches"')]
-
-  mock_run_shell_command.assert_has_calls(calls)
-
-@patch('lib.logcat_utils.blocking_wait_for_logcat_pattern')
-@patch('lib.cmd_utils.run_shell_command')
-def test_perfetto_trace_collector_postprocess(mock_run_shell_command,
-                                              mock_blocking_wait_for_logcat_pattern):
-  mock_run_shell_command.side_effect = _mocked_run_shell_command
-  mock_blocking_wait_for_logcat_pattern.return_value = "Succeed!"
-
-  RUNNER.postprocess('2019-07-02 23:20:06.972674825')
-
-  calls = [call('adb shell ps | grep "music" | awk \'{print $2;}\''),
-           call('adb shell "kill 9999"'),
-           call(
-               'bash -c "source {}; iorapd_perfetto_disable"'.format(
-                   AppRunner.IORAP_COMMON_BASH_SCRIPT)),
-           call('adb pull '
-                '"/data/misc/iorapd/music%2FMainActivity.perfetto_trace.pb" '
-                '"/tmp/trace.pb"')]
-
-  mock_run_shell_command.assert_has_calls(calls)
diff --git a/startop/scripts/app_startup/parse_metrics b/startop/scripts/app_startup/parse_metrics
deleted file mode 100755
index 3fa1462..0000000
--- a/startop/scripts/app_startup/parse_metrics
+++ /dev/null
@@ -1,215 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-usage() {
-    cat <<EOF
-Usage: launch_application package activity | parse_metrics --package <name> --timestamp <timestamp> [OPTIONS]...
-
-  Reads from stdin the result of 'am start' metrics. May also parse logcat
-  for additional metrics.
-
-  Output form:
-
-    MetricName_unit=numeric_value
-    MetricName2_unit=numeric_value2
-
-  This may block until all desired metrics are parsed from logcat.
-  To get a list of metrics without doing real parsing, use --simulate.
-
-  To add package-specific metrics, add a script called 'metrics/\$full_package_name'
-  that exposes additional metrics in same way as above.
-
-  (required)
-    -p, --package <name>        package of the app that is being used
-    -ts, --timestamp <name>     logcat timestamp [only looks at logcat entries after this timestamp].
-
-  (optional)
-    -s, --simulate              prints dummy values instead of real metrics
-    -a, --activity <name>       activity to use (default: inferred)
-    -h, --help                  usage information (this)
-    -v, --verbose               enable extra verbose printing
-    -t, --timeout <sec>         how many seconds to timeout when trying to wait for logcat to change
-    -rfd, --reportfullydrawn    wait for report fully drawn (default: off)
-EOF
-}
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/lib/common"
-
-report_fully_drawn="n"
-package=""
-activity=""
-timeout=5
-simulate="n"
-parse_arguments() {
-  while [[ $# -gt 0 ]]; do
-    case "$1" in
-      -h|--help)
-        usage
-        exit 0
-        ;;
-      -p|--package)
-        package="$2"
-        shift
-        ;;
-      -a|--activity)
-        activity="$2"
-        shift
-        ;;
-      -v|--verbose)
-        export verbose="y"
-        ;;
-      -t|--timeout)
-        timeout="$2"
-        shift
-        ;;
-      -ts|--timestamp)
-        timestamp="$2"
-        shift
-        ;;
-      -s|--simulate)
-        simulate="y"
-        ;;
-      -rfd|--reportfullydrawn)
-        report_fully_drawn="y"
-        ;;
-
-
-      *)
-        echo "Invalid argument: $1" >&2
-        exit 1
-    esac
-    shift
-  done
-}
-
-# Main entry point
-if [[ $# -eq 0 ]]; then
-  usage
-  exit 1
-else
-  parse_arguments "$@"
-
-  # if we do not have have package exit early with an error
-  [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 64
-
-  # ignore timestamp for --simulate. it's optional.
-  if [[ $simulate == y ]]; then
-    timestamp=0
-  fi
-
-  # if we do not have timestamp, exit early with an error
-  [[ "$timestamp" == "" ]] && echo "--timestamp not specified" 1>&2 && exit 64
-
-  if [[ "$activity" == "" ]] && [[ "$simulate" != "y" ]]; then
-    activity="$(get_activity_name "$package")"
-    if [[ "$activity" == "" ]]; then
-      echo "Activity name could not be found, invalid package name?" 1>&2
-      exit 64
-    else
-      verbose_print "Activity name inferred: " "$activity"
-    fi
-  fi
-fi
-
-parse_metric_from_logcat() {
-  local metric_name="$1"
-  local pattern="$2"
-  local re_pattern="$3"
-  local retcode
-  local result
-  local sec
-  local ms
-
-  # parse logcat for 'Displayed...' and that other one...
-
-  # 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms
-  verbose_print "parse_metric_from_logcat: $re_pattern"
-
-
-  echo -ne "$metric_name="
-
-  if [[ $simulate == y ]]; then
-    echo "-1"
-    return 0
-  fi
-
-  result="$(logcat_extract_pattern "$timeout" "$timestamp" "$pattern" "$re_pattern")"
-  retcode=$?
-
-  if [[ $retcode -ne 0 ]]; then
-    # Timed out before finding the pattern. Could also mean the pattern is wrong.
-    echo "Parse $re_pattern from logcat TIMED OUT after $timeout seconds." >&2
-    echo "-$?"
-    return $retcode
-  fi
-
-  # "10s123ms" -> "10s123"
-  result=${result/ms/}
-  if [[ $result =~ s ]]; then
-    ms=${result/*s/}
-    sec=${result/s*/}
-  else
-    sec=0
-    ms=$result
-  fi
-  ((result=sec*1000+ms))
-
-  echo "$result"
-  return $retcode
-}
-
-
-total_time="-1"
-if [[ $simulate != y ]]; then
-  verbose_print 'logcat timestamp NOW: ' $(logcat_save_timestamp)
-
-  # parse stdin for 'am start' result
-  while read -t "$timeout" -r input_line; do
-    verbose_print 'stdin:' "$input_line"
-    if [[ $input_line == *TotalTime:* ]]; then
-      total_time="$(echo "$input_line" | sed 's/TotalTime: \([[:digit:]]\+\)/\1/g')"
-      # but keep reading the rest from stdin until <EOF>
-    fi
-  done
-fi
-
-echo "TotalTime_ms=$total_time"
-
-# parse logcat for 'Displayed...' and that other one...
-
-# 05-06 14:34:08.854 29460 29481 I ActivityTaskManager: Displayed com.google.android.dialer/.extensions.GoogleDialtactsActivity: +361ms
-pattern="ActivityTaskManager: Displayed ${package}"
-re_pattern='.*Displayed[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*'
-
-parse_metric_from_logcat "Displayed_ms" "$pattern" "$re_pattern"
-
-# Only track ReportFullyDrawn with --reportfullydrawn/-rfd flags
-if [[ $report_fully_drawn == y ]]; then
-  # 01-16 17:31:44.550 11172 11204 I ActivityTaskManager: Fully drawn com.google.android.GoogleCamera/com.android.camera.CameraLauncher: +10s897ms
-  pattern="ActivityTaskManager: Fully drawn ${package}"
-  #re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+\).*'
-  re_pattern='.*Fully drawn[[:blank:]]\+'"${package}"'[/][^[:blank:]]\+[[:blank:]]+\([[:digit:]]\+ms\|[[:digit:]]\+s[[:digit:]]\+ms\).*'
-
-  parse_metric_from_logcat "Fully_drawn_ms" "$pattern" "$re_pattern"
-fi
-
-# also call into package-specific scripts if there are additional metrics
-if [[ -x "$DIR/metrics/$package" ]]; then
-  source "$DIR/metrics/$package" "$timestamp"
-else
-  verbose_print parse_metrics: no per-package metrics script found at "$DIR/metrics/$package"
-fi
diff --git a/startop/scripts/app_startup/query_compiler_filter.py b/startop/scripts/app_startup/query_compiler_filter.py
deleted file mode 100755
index ea14264..0000000
--- a/startop/scripts/app_startup/query_compiler_filter.py
+++ /dev/null
@@ -1,232 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-#
-# Query the current compiler filter for an application by its package name.
-# (By parsing the results of the 'adb shell dumpsys package $package' command).
-# The output is a string "$compilation_filter $compilation_reason $isa".
-#
-# See --help for more details.
-#
-# -----------------------------------
-#
-# Sample usage:
-#
-# $> ./query_compiler_filter.py --package com.google.android.calculator
-# speed-profile unknown arm64
-#
-
-import argparse
-import os
-import re
-import sys
-
-# TODO: refactor this with a common library file with analyze_metrics.py
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-import lib.cmd_utils as cmd_utils
-import lib.print_utils as print_utils
-
-from typing import List, NamedTuple, Iterable
-
-_DEBUG_FORCE = None  # Ignore -d/--debug if this is not none.
-
-def parse_options(argv: List[str] = None):
-  """Parse command line arguments and return an argparse Namespace object."""
-  parser = argparse.ArgumentParser(description="Query the compiler filter for a package.")
-  # argparse considers args starting with - and -- optional in --help, even though required=True.
-  # by using a named argument group --help will clearly say that it's required instead of optional.
-  required_named = parser.add_argument_group('required named arguments')
-  required_named.add_argument('-p', '--package', action='store', dest='package', help='package of the application', required=True)
-
-  # optional arguments
-  # use a group here to get the required arguments to appear 'above' the optional arguments in help.
-  optional_named = parser.add_argument_group('optional named arguments')
-  optional_named.add_argument('-i', '--isa', '--instruction-set', action='store', dest='instruction_set', help='which instruction set to select. defaults to the first one available if not specified.', choices=('arm64', 'arm', 'x86_64', 'x86'))
-  optional_named.add_argument('-s', '--simulate', dest='simulate', action='store_true', help='Print which commands will run, but don\'t run the apps')
-  optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
-
-  return parser.parse_args(argv)
-
-def remote_dumpsys_package(package: str, simulate: bool) -> str:
-  # --simulate is used for interactive debugging/development, but also for the unit test.
-  if simulate:
-    return """
-Dexopt state:
-  [%s]
-    path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk
-      arm64: [status=speed-profile] [reason=unknown]
-    path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk
-      arm: [status=speed] [reason=first-boot]
-    path: /data/app/%s-D7s8PLidqqEq7Jc7UH_a5A==/base.apk
-      x86: [status=quicken] [reason=install]
-""" %(package, package, package, package)
-
-  code, res = cmd_utils.execute_arbitrary_command(['adb', 'shell', 'dumpsys',
-                                                   'package', package],
-                                                  simulate=False,
-                                                  timeout=5,
-                                                  shell=False)
-  if code:
-    return res
-  else:
-    raise AssertionError("Failed to dumpsys package, errors = %s", res)
-
-ParseTree = NamedTuple('ParseTree', [('label', str), ('children', List['ParseTree'])])
-DexoptState = ParseTree # With the Dexopt state: label
-ParseResult = NamedTuple('ParseResult', [('remainder', List[str]), ('tree', ParseTree)])
-
-def find_parse_subtree(parse_tree: ParseTree, match_regex: str) -> ParseTree:
-  if re.match(match_regex, parse_tree.label):
-    return parse_tree
-
-  for node in parse_tree.children:
-    res = find_parse_subtree(node, match_regex)
-    if res:
-      return res
-
-  return None
-
-def find_parse_children(parse_tree: ParseTree, match_regex: str) -> Iterable[ParseTree]:
-  for node in parse_tree.children:
-    if re.match(match_regex, node.label):
-      yield node
-
-def parse_tab_subtree(label: str, str_lines: List[str], separator=' ', indent=-1) -> ParseResult:
-  children = []
-
-  get_indent_level = lambda line: len(line) - len(line.lstrip())
-
-  line_num = 0
-
-  keep_going = True
-  while keep_going:
-    keep_going = False
-
-    for line_num in range(len(str_lines)):
-      line = str_lines[line_num]
-      current_indent = get_indent_level(line)
-
-      print_utils.debug_print("INDENT=%d, LINE=%s" %(current_indent, line))
-
-      current_label = line.lstrip()
-
-      # skip empty lines
-      if line.lstrip() == "":
-        continue
-
-      if current_indent > indent:
-        parse_result = parse_tab_subtree(current_label, str_lines[line_num+1::], separator, current_indent)
-        str_lines = parse_result.remainder
-        children.append(parse_result.tree)
-        keep_going = True
-      else:
-        # current_indent <= indent
-        keep_going = False
-
-      break
-
-  new_remainder = str_lines[line_num::]
-  print_utils.debug_print("NEW REMAINDER: ", new_remainder)
-
-  parse_tree = ParseTree(label, children)
-  return ParseResult(new_remainder, parse_tree)
-
-def parse_tab_tree(str_tree: str, separator=' ', indentation_level=-1) -> ParseTree:
-
-  label = None
-  lst = []
-
-  line_num = 0
-  line_lst = str_tree.split("\n")
-
-  return parse_tab_subtree("", line_lst, separator, indentation_level).tree
-
-def parse_dexopt_state(dumpsys_tree: ParseTree) -> DexoptState:
-  res = find_parse_subtree(dumpsys_tree, "Dexopt(\s+)state[:]?")
-  if not res:
-    raise AssertionError("Could not find the Dexopt state")
-  return res
-
-def find_first_compiler_filter(dexopt_state: DexoptState, package: str, instruction_set: str) -> str:
-  lst = find_all_compiler_filters(dexopt_state, package)
-
-  print_utils.debug_print("all compiler filters: ", lst)
-
-  for compiler_filter_info in lst:
-    if not instruction_set:
-      return compiler_filter_info
-
-    if compiler_filter_info.isa == instruction_set:
-      return compiler_filter_info
-
-  return None
-
-CompilerFilterInfo = NamedTuple('CompilerFilterInfo', [('isa', str), ('status', str), ('reason', str)])
-
-def find_all_compiler_filters(dexopt_state: DexoptState, package: str) -> List[CompilerFilterInfo]:
-
-  lst = []
-  package_tree = find_parse_subtree(dexopt_state, re.escape("[%s]" %package))
-
-  if not package_tree:
-    raise AssertionError("Could not find any package subtree for package %s" %(package))
-
-  print_utils.debug_print("package tree: ", package_tree)
-
-  for path_tree in find_parse_children(package_tree, "path: "):
-    print_utils.debug_print("path tree: ", path_tree)
-
-    matchre = re.compile("([^:]+):\s+\[status=([^\]]+)\]\s+\[reason=([^\]]+)\]")
-
-    for isa_node in find_parse_children(path_tree, matchre):
-
-      matches = re.match(matchre, isa_node.label).groups()
-
-      info = CompilerFilterInfo(*matches)
-      lst.append(info)
-
-  return lst
-
-def main() -> int:
-  opts = parse_options()
-  cmd_utils._debug = opts.debug
-  if _DEBUG_FORCE is not None:
-    cmd_utils._debug = _DEBUG_FORCE
-  print_utils.debug_print("parsed options: ", opts)
-
-  # Note: This can often 'fail' if the package isn't actually installed.
-  package_dumpsys = remote_dumpsys_package(opts.package, opts.simulate)
-  print_utils.debug_print("package dumpsys: ", package_dumpsys)
-  dumpsys_parse_tree = parse_tab_tree(package_dumpsys, package_dumpsys)
-  print_utils.debug_print("parse tree: ", dumpsys_parse_tree)
-  dexopt_state = parse_dexopt_state(dumpsys_parse_tree)
-
-  filter = find_first_compiler_filter(dexopt_state, opts.package, opts.instruction_set)
-
-  if filter:
-    print(filter.status, end=' ')
-    print(filter.reason, end=' ')
-    print(filter.isa)
-  else:
-    print("ERROR: Could not find any compiler-filter for package %s, isa %s" %(opts.package, opts.instruction_set), file=sys.stderr)
-    return 1
-
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/startop/scripts/app_startup/query_compiler_filter_test.py b/startop/scripts/app_startup/query_compiler_filter_test.py
deleted file mode 100755
index a751a43..0000000
--- a/startop/scripts/app_startup/query_compiler_filter_test.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for the query_compiler_filter.py script.
-
-Install:
-  $> sudo apt-get install python3-pytest   ##  OR
-  $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
-  $> ./query_compiler_filter.py
-  $> pytest query_compiler_filter.py
-  $> python -m pytest query_compiler_filter.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-from contextlib import contextmanager
-import io
-import shlex
-import sys
-import typing
-
-# pip imports
-import pytest
-
-# local imports
-import query_compiler_filter as qcf
-
-@contextmanager
-def redirect_stdout_stderr():
-  """Redirect stdout/stderr to a new StringIO for duration of context."""
-  old_stdout = sys.stdout
-  old_stderr = sys.stderr
-  new_stdout = io.StringIO()
-  sys.stdout = new_stdout
-  new_stderr = io.StringIO()
-  sys.stderr = new_stderr
-  try:
-    yield (new_stdout, new_stderr)
-  finally:
-    sys.stdout = old_stdout
-    sys.stderr = old_stderr
-    # Seek back to the beginning so we can read whatever was written into it.
-    new_stdout.seek(0)
-    new_stderr.seek(0)
-
-@contextmanager
-def replace_argv(argv):
-  """ Temporarily replace argv for duration of this context."""
-  old_argv = sys.argv
-  sys.argv = [sys.argv[0]] + argv
-  try:
-    yield
-  finally:
-    sys.argv = old_argv
-
-def exec_main(argv):
-  """Run the query_compiler_filter main function with the provided arguments.
-
-  Returns the stdout result when successful, assertion failure otherwise.
-  """
-  try:
-    with redirect_stdout_stderr() as (the_stdout, the_stderr):
-      with replace_argv(argv):
-        code = qcf.main()
-    assert 0 == code, the_stderr.readlines()
-
-    all_lines = the_stdout.readlines()
-    return "".join(all_lines)
-  finally:
-    the_stdout.close()
-    the_stderr.close()
-
-def test_query_compiler_filter():
-  # no --instruction-set specified: provide whatever was the 'first' filter.
-  assert exec_main(['--simulate',
-                    '--package', 'com.google.android.apps.maps']) == \
-      "speed-profile unknown arm64\n"
-
-  # specifying an instruction set finds the exact compiler filter match.
-  assert exec_main(['--simulate',
-                    '--package', 'com.google.android.apps.maps',
-                    '--instruction-set', 'arm64']) == \
-      "speed-profile unknown arm64\n"
-
-  assert exec_main(['--simulate',
-                    '--package', 'com.google.android.apps.maps',
-                    '--instruction-set', 'arm']) == \
-      "speed first-boot arm\n"
-
-  assert exec_main(['--simulate',
-                    '--debug',
-                    '--package', 'com.google.android.apps.maps',
-                    '--instruction-set', 'x86']) == \
-      "quicken install x86\n"
-
-if __name__ == '__main__':
-  pytest.main()
diff --git a/startop/scripts/app_startup/run_app_with_prefetch b/startop/scripts/app_startup/run_app_with_prefetch
deleted file mode 100755
index 31f6253..0000000
--- a/startop/scripts/app_startup/run_app_with_prefetch
+++ /dev/null
@@ -1,487 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-usage() {
-    cat <<EOF
-Usage: run_app_with_prefetch --package <name> [OPTIONS]...
-
-    -p, --package <name>        package of the app to test
-    -a, --activity <name>       activity to use
-    -h, --help                  usage information (this)
-    -v, --verbose               enable extra verbose printing
-    -i, --input <file>          trace file protobuf (default 'TraceFile.pb')
-    -r, --readahead <mode>      cold, warm, fadvise, mlock (default 'warm')
-    -w, --when <when>           aot or jit (default 'jit')
-    -c, --count <count>         how many times to run (default 1)
-    -s, --sleep <sec>           how long to sleep after readahead
-    -t, --timeout <sec>         how many seconds to timeout in between each app run (default 10)
-    -o, --output <file.csv>     what file to write the performance results into as csv (default stdout)
-EOF
-}
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-source "$DIR/../iorap/common"
-
-report_fully_drawn="n"
-needs_trace_file="n"
-input_file=""
-package=""
-mode='warm'
-count=2
-sleep_time=2
-timeout=10
-output="" # stdout by default
-when="jit"
-parse_arguments() {
-  while [[ $# -gt 0 ]]; do
-    case "$1" in
-      -h|--help)
-        usage
-        exit 0
-        ;;
-      -p|--package)
-        package="$2"
-        shift
-        ;;
-      -a|--activity)
-        activity="$2"
-        shift
-        ;;
-      -i|--input)
-        input_file="$2"
-        shift
-        ;;
-      -v|--verbose)
-        export verbose="y"
-        ;;
-      -r|--readahead)
-        mode="$2"
-        shift
-        ;;
-      -rfd|--reportfullydrawn)
-        report_fully_drawn="y"
-        shift
-        ;;
-      -c|--count)
-        count="$2"
-        ((count+=1))
-        shift
-        ;;
-      -s|--sleep)
-        sleep_time="$2"
-        shift
-        ;;
-      -t|--timeout)
-        timeout="$2"
-        shift
-        ;;
-      -o|--output)
-        output="$2"
-        shift
-        ;;
-      -w|--when)
-        when="$2"
-        shift
-        ;;
-      --compiler-filter)
-        compiler_filter="$2"
-        shift
-        ;;
-      *)
-        echo "Invalid argument: $1" >&2
-        exit 1
-    esac
-    shift
-  done
-
-  if [[ $when == "aot" ]]; then
-    # TODO: re-implement aot later for experimenting.
-    echo "Error: --when $when is unsupported" >&2
-    exit 1
-  elif [[ $when != "jit" ]]; then
-    echo "Error: --when must be one of (aot jit)." >&2
-    exit 1
-  fi
-}
-
-echo_to_output_file() {
-  if [[ "x$output" != x ]]; then
-    echo "$@" >> $output
-  fi
-  # Always echo to stdout as well.
-  echo "$@"
-}
-
-find_package_path() {
-  local pkg="$1"
-
-  res="$(adb shell find "/data/app/$pkg"-'*' -maxdepth 0 2> /dev/null)"
-  if [[ -z $res ]]; then
-    res="$(adb shell find "/system/app/$pkg"-'*' -maxdepth 0 2> /dev/null)"
-  fi
-  echo "$res"
-}
-
-# Main entry point
-if [[ $# -eq 0 ]]; then
-  usage
-  exit 1
-else
-  parse_arguments "$@"
-
-  # if we do not have have package exit early with an error
-  [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 1
-
-  if [[ $mode != "cold" && $mode != "warm" ]]; then
-    needs_trace_file="y"
-    if [[ -z "$input_file" ]] || ! [[ -f $input_file ]]; then
-      echo "--input not specified" 1>&2
-      exit 1
-    fi
-  fi
-
-  if [[ "$activity" == "" ]]; then
-    activity="$(get_activity_name "$package")"
-    if [[ "$activity" == "" ]]; then
-      echo "Activity name could not be found, invalid package name?" 1>&2
-      exit 1
-    else
-      verbose_print "Activity name inferred: " "$activity"
-    fi
-  fi
-fi
-
-adb root > /dev/null
-
-if [[ ($when == jit) || ($when == aot) ]] && [[ "$(adb shell getenforce)" != "Permissive" ]]; then
-  echo "Disable selinux permissions and restart framework."
-  adb shell setenforce 0
-  adb shell stop
-  adb shell start
-  adb wait-for-device
-fi
-
-# TODO: set performance governor etc, preferrably only once
-# before every single app run.
-
-# Kill everything before running.
-remote_pkill "$package"
-sleep 1
-
-timings_array=()
-
-package_path="$(find_package_path "$package")"
-if [[ $? -ne 0 ]]; then
-  echo "Failed to detect package path for '$package'" >&2
-  exit 1
-fi
-verbose_print "Package was in path '$package_path'"
-
-application_trace_file_path="$package_path/TraceFile.pb"
-trace_file_directory="$package_path"
-if [[ $needs_trace_file == y ]]; then
-  # system server always passes down the package path in a hardcoded spot.
-  if [[ $when == "jit" ]]; then
-    if ! iorapd_compiler_install_trace_file "$package" "$activity" "$input_file"; then
-      echo "Error: Failed to install compiled TraceFile.pb for '$package/$activity'" >&2
-      exit 1
-    fi
-    keep_application_trace_file="y"
-  else
-    echo "TODO: --readahead=aot is non-functional and needs to be fixed." >&2
-    exit 1
-    # otherwise use a temporary directory to get normal non-jit behavior.
-    trace_file_directory="/data/local/tmp/prefetch/$package"
-    adb shell mkdir -p "$trace_file_directory"
-    verbose_print  adb push "$input_file" "$trace_file_directory/TraceFile.pb"
-    adb push "$input_file" "$trace_file_directory/TraceFile.pb"
-  fi
-fi
-
-# Everything other than JIT: remove the trace file,
-# otherwise system server activity hints will kick in
-# and the new just-in-time app pre-warmup will happen.
-if [[ $keep_application_trace_file == "n" ]]; then
-  iorapd_compiler_purge_trace_file "$package" "$activity"
-fi
-
-# Perform AOT readahead/pinning/etc when an application is about to be launched.
-# For JIT readahead, we allow the system to handle it itself (this is a no-op).
-#
-# For warm, cold, etc modes which don't need readahead this is always a no-op.
-perform_aot() {
-  local the_when="$1" # user: aot, jit
-  local the_mode="$2" # warm, cold, fadvise, mlock, etc.
-
-  # iorapd readahead for jit+(mlock/fadvise)
-  if [[ $the_when == "jit" && $the_mode != 'warm' && $the_mode != 'cold' ]]; then
-    iorapd_readahead_enable
-    return 0
-  fi
-
-  if [[ $the_when != "aot" ]]; then
-    # TODO: just in time implementation.. should probably use system server.
-    return 0
-  fi
-
-  # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script.
-  if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
-
-    # TODO: add activity_hint_sender.exp
-    verbose_print "starting with package=$package package_path=$trace_file_directory"
-    coproc hint_sender_fd { $ANDROID_BUILD_TOP/system/iorap/src/sh/activity_hint_sender.exp "$package" "$trace_file_directory" "$the_mode"; }
-    hint_sender_pid=$!
-    verbose_print "Activity hint sender began"
-
-    notification_success="n"
-    while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do
-      verbose_print "$hint_sender_output"
-      if [[ "$hint_sender_output" == "Press any key to send completed event..."* ]]; then
-        verbose_print "WE DID SEE NOTIFICATION SUCCESS."
-        notification_success='y'
-        # Give it some time to actually perform the readaheads.
-        sleep $sleep_time
-        break
-      fi
-    done
-
-    if [[ $notification_success == 'n' ]]; then
-      echo "[FATAL] Activity hint notification failed." 1>&2
-      exit 1
-    fi
-  fi
-}
-
-# Perform cleanup at the end of each loop iteration.
-perform_post_launch_cleanup() {
-  local the_when="$1" # user: aot, jit
-  local the_mode="$2" # warm, cold, fadvise, mlock, etc.
-  local logcat_timestamp="$3"  # timestamp from before am start.
-  local res
-
-  if [[ $the_when != "aot" ]]; then
-    if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
-      # Validate that readahead completes.
-      # If this fails for some reason, then this will also discard the timing of the run.
-      iorapd_readahead_wait_until_finished "$package" "$activity" "$logcat_timestamp" "$timeout"
-      res=$?
-
-      iorapd_readahead_disable
-
-      return $res
-    fi
-    # Don't need to do anything for warm or cold.
-    return 0
-  fi
-
-  # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script.
-  if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
-    # Clean up the hint sender by telling it that the launch was completed,
-    # and to shutdown the watcher.
-    echo "Done\n" >&"${hint_sender_fd[1]}"
-
-    while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do
-      verbose_print "$hint_sender_output"
-    done
-
-    wait $hint_sender_pid
-  fi
-}
-
-configure_compiler_filter() {
-  local the_compiler_filter="$1"
-  local the_package="$2"
-  local the_activity="$3"
-
-  if [[ -z $the_compiler_filter ]]; then
-    verbose_print "No --compiler-filter specified, don't need to force it."
-    return 0
-  fi
-
-  local current_compiler_filter_info="$("$DIR"/query_compiler_filter.py --package "$the_package")"
-  local res=$?
-  if [[ $res -ne 0 ]]; then
-    return $res
-  fi
-
-  local current_compiler_filter
-  local current_reason
-  local current_isa
-  read current_compiler_filter current_reason current_isa <<< "$current_compiler_filter_info"
-
-  verbose_print "Compiler Filter="$current_compiler_filter "Reason="$current_reason "Isa="$current_isa
-
-  # Don't trust reasons that aren't 'unknown' because that means we didn't manually force the compilation filter.
-  # (e.g. if any automatic system-triggered compilations are not unknown).
-  if [[ $current_reason != "unknown" ]] || [[ $current_compiler_filter != $the_compiler_filter ]]; then
-    verbose_print "$DIR"/force_compiler_filter --compiler-filter "$the_compiler_filter" --package "$the_package" --activity "$the_activity"
-    "$DIR"/force_compiler_filter --compiler-filter "$the_compiler_filter" --package "$the_package" --activity "$the_activity"
-    res=$?
-  else
-    verbose_print "Queried compiler-filter matched requested compiler-filter, skip forcing."
-    res=0
-  fi
-
-  return $res
-}
-
-# Ensure the APK is currently compiled with whatever we passed in via --compiler-filter.
-# No-op if this option was not passed in.
-configure_compiler_filter "$compiler_filter" "$package" "$activity" || exit 1
-
-# convert 'a=b\nc=d\ne=f\n...' into 'b,d,f,...'
-parse_metrics_output_string() {
-  # single string with newlines in it.
-  local input="$1"
-
-  local metric_name
-  local metric_value
-  local rest
-
-  local all_metrics=()
-
-  # (n1=v1 n2=v2 n3=v3 ...)
-  readarray -t all_metrics <<< "$input"
-
-  local kv_pair=()
-  local i
-
-  for i in "${all_metrics[@]}"
-  do
-    verbose_print "parse_metrics_output: element '$i'"
-    # name=value
-
-    IFS='=' read -r metric_name metric_value rest <<< "$i"
-
-    verbose_print "parse_metrics_output: metric_value '$metric_value'"
-
-    # (value1 value2 value3 ...)
-    all_metrics+=(${metric_value})
-  done
-
-  # "value1,value2,value3,..."
-  join_by ',' "${all_metrics[@]}"
-}
-
-# convert 'a=b\nc=d\ne=f\n... into b,d,f,...'
-parse_metrics_output() {
-  local metric_name
-  local metric_value
-  local rest
-
-  local all_metrics=()
-
-  while IFS='=' read -r metric_name metric_value rest; do
-    verbose_print "metric: $metric_name, value: $metric_value; rest: $rest"
-    all_metrics+=($metric_value)
-  done
-
-  join_by ',' "${all_metrics[@]}"
-}
-
-# convert 'a=b\nc=d\ne=f\n... into b,d,f,...'
-parse_metrics_header() {
-  local metric_name
-  local metric_value
-  local rest
-
-  local all_metrics=()
-
-  while IFS='=' read -r metric_name metric_value rest; do
-    verbose_print "metric: $metric_name, value: $metric_value; rest: $rest"
-    all_metrics+=($metric_name)
-  done
-
-  join_by ',' "${all_metrics[@]}"
-}
-
-if [[ $report_fully_drawn == y ]]; then
-  metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate --reportfullydrawn | parse_metrics_header)"
-else
-  metrics_header="$("$DIR/parse_metrics" --package "$package" --activity "$activity" --simulate | parse_metrics_header)"
-fi
-
-# TODO: This loop logic could probably be moved into app_startup_runner.py
-for ((i=0;i<count;++i)) do
-  verbose_print "=========================================="
-  verbose_print "====         ITERATION $i             ===="
-  verbose_print "=========================================="
-  if [[ $mode != "warm" ]]; then
-    # The package must be killed **before** we drop caches, otherwise pages will stay resident.
-    verbose_print "Kill package for non-warm start."
-    remote_pkill "$package"
-    verbose_print "Drop caches for non-warm start."
-    # Drop all caches to get cold starts.
-    adb shell "echo 3 > /proc/sys/vm/drop_caches"
-  fi
-
-  perform_aot "$when" "$mode"
-
-  verbose_print "Running with timeout $timeout"
-
-  pre_launch_timestamp="$(logcat_save_timestamp)"
-
-  # TODO: multiple metrics output.
-
-if [[ $report_fully_drawn == y ]]; then
-  total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" --reportfullydrawn | parse_metrics_output)"
-else
-  total_time="$(timeout $timeout "$DIR/launch_application" "$package" "$activity" | "$DIR/parse_metrics" --package "$package" --activity "$activity" --timestamp "$pre_launch_timestamp" | parse_metrics_output)"
-fi
-
-  if [[ $? -ne 0 ]]; then
-    echo "WARNING: Skip bad result, try iteration again." >&2
-    ((i=i-1))
-    continue
-  fi
-
-  perform_post_launch_cleanup "$when" "$mode" "$pre_launch_timestamp"
-
-  if [[ $? -ne 0 ]]; then
-    echo "WARNING: Skip bad cleanup, try iteration again." >&2
-    ((i=i-1))
-    continue
-  fi
-
-  echo "Iteration $i. Total time was: $total_time"
-
-  timings_array+=("$total_time")
-done
-
-# drop the first result which is usually garbage.
-timings_array=("${timings_array[@]:1}")
-
-# Print the CSV header first.
-echo_to_output_file "$metrics_header"
-
-# Print out interactive/debugging timings and averages.
-# Other scripts should use the --output flag and parse the CSV.
-for tim in "${timings_array[@]}"; do
-  echo_to_output_file "$tim"
-done
-
-if [[ x$output != x ]]; then
-  echo " Saved results to '$output'"
-fi
-
-if [[ $needs_trace_file == y ]] ; then
-  iorapd_compiler_purge_trace_file "$package" "$activity"
-fi
-
-# Kill the process to ensure AM isn't keeping it around.
-remote_pkill "$package"
-
-exit 0
diff --git a/startop/scripts/app_startup/run_app_with_prefetch.py b/startop/scripts/app_startup/run_app_with_prefetch.py
deleted file mode 100755
index 2f1eff2..0000000
--- a/startop/scripts/app_startup/run_app_with_prefetch.py
+++ /dev/null
@@ -1,230 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Runner of one test given a setting.
-
-Run app and gather the measurement in a certain configuration.
-Print the result to stdout.
-See --help for more details.
-
-Sample usage:
-  $> ./python run_app_with_prefetch.py  -p com.android.settings -a
-     com.android.settings.Settings -r fadvise -i input
-
-"""
-
-import argparse
-import os
-import sys
-import time
-from typing import List, Tuple, Optional
-
-# local imports
-import lib.adb_utils as adb_utils
-from lib.app_runner import AppRunner, AppRunnerListener
-
-# global variables
-DIR = os.path.abspath(os.path.dirname(__file__))
-
-sys.path.append(os.path.dirname(DIR))
-import lib.print_utils as print_utils
-import lib.cmd_utils as cmd_utils
-import iorap.lib.iorapd_utils as iorapd_utils
-
-class PrefetchAppRunner(AppRunnerListener):
-  def __init__(self,
-               package: str,
-               activity: Optional[str],
-               readahead: str,
-               compiler_filter: Optional[str],
-               timeout: Optional[int],
-               simulate: bool,
-               debug: bool,
-               input:Optional[str],
-               **kwargs):
-    self.app_runner = AppRunner(package,
-                                activity,
-                                compiler_filter,
-                                timeout,
-                                simulate)
-    self.app_runner.add_callbacks(self)
-
-    self.simulate = simulate
-    self.readahead = readahead
-    self.debug = debug
-    self.input = input
-    print_utils.DEBUG = self.debug
-    cmd_utils.SIMULATE = self.simulate
-
-
-  def run(self) -> Optional[List[Tuple[str]]]:
-    """Runs an app.
-
-    Returns:
-      A list of (metric, value) tuples.
-    """
-    return self.app_runner.run()
-
-  def preprocess(self):
-    passed = self.validate_options()
-    if not passed:
-      return
-
-    # Sets up adb environment.
-    adb_utils.root()
-    adb_utils.disable_selinux()
-    time.sleep(1)
-
-    # Kill any existing process of this app
-    adb_utils.pkill(self.app_runner.package)
-
-    if self.readahead != 'warm':
-      print_utils.debug_print('Drop caches for non-warm start.')
-      # Drop all caches to get cold starts.
-      adb_utils.vm_drop_cache()
-
-    if self.readahead != 'warm' and self.readahead != 'cold':
-      iorapd_utils.enable_iorapd_readahead()
-
-  def postprocess(self, pre_launch_timestamp: str):
-    passed = self._perform_post_launch_cleanup(pre_launch_timestamp)
-    if not passed and not self.app_runner.simulate:
-      print_utils.error_print('Cannot perform post launch cleanup!')
-      return None
-
-    # Kill any existing process of this app
-    adb_utils.pkill(self.app_runner.package)
-
-  def _perform_post_launch_cleanup(self, logcat_timestamp: str) -> bool:
-    """Performs cleanup at the end of each loop iteration.
-
-    Returns:
-      A bool indicates whether the cleanup succeeds or not.
-    """
-    if self.readahead != 'warm' and self.readahead != 'cold':
-      passed = iorapd_utils.wait_for_iorapd_finish(self.app_runner.package,
-                                                   self.app_runner.activity,
-                                                   self.app_runner.timeout,
-                                                   self.debug,
-                                                   logcat_timestamp)
-
-      if not passed:
-        return passed
-
-      return iorapd_utils.disable_iorapd_readahead()
-
-    # Don't need to do anything for warm or cold.
-    return True
-
-  def metrics_selector(self, am_start_output: str,
-                       pre_launch_timestamp: str) -> str:
-    """Parses the metric after app startup by reading from logcat in a blocking
-    manner until all metrics have been found".
-
-    Returns:
-      the total time and displayed time of app startup.
-      For example: "TotalTime=123\nDisplayedTime=121
-    """
-    total_time = AppRunner.parse_total_time(am_start_output)
-    displayed_time = adb_utils.blocking_wait_for_logcat_displayed_time(
-        pre_launch_timestamp, self.app_runner.package, self.app_runner.timeout)
-
-    return 'TotalTime={}\nDisplayedTime={}'.format(total_time, displayed_time)
-
-  def validate_options(self) -> bool:
-    """Validates the activity and trace file if needed.
-
-    Returns:
-      A bool indicates whether the activity is valid.
-    """
-    needs_trace_file = self.readahead != 'cold' and self.readahead != 'warm'
-    if needs_trace_file and (self.input is None or
-                             not os.path.exists(self.input)):
-      print_utils.error_print('--input not specified!')
-      return False
-
-    # Install necessary trace file. This must be after the activity checking.
-    if needs_trace_file:
-      passed = iorapd_utils.iorapd_compiler_install_trace_file(
-          self.app_runner.package, self.app_runner.activity, self.input)
-      if not cmd_utils.SIMULATE and not passed:
-        print_utils.error_print('Failed to install compiled TraceFile.pb for '
-                                '"{}/{}"'.
-                                    format(self.app_runner.package,
-                                           self.app_runner.activity))
-        return False
-
-    return True
-
-
-
-def parse_options(argv: List[str] = None):
-  """Parses command line arguments and return an argparse Namespace object."""
-  parser = argparse.ArgumentParser(
-      description='Run an Android application once and measure startup time.'
-  )
-
-  required_named = parser.add_argument_group('required named arguments')
-  required_named.add_argument('-p', '--package', action='store', dest='package',
-                              help='package of the application', required=True)
-
-  # optional arguments
-  # use a group here to get the required arguments to appear 'above' the
-  # optional arguments in help.
-  optional_named = parser.add_argument_group('optional named arguments')
-  optional_named.add_argument('-a', '--activity', action='store',
-                              dest='activity',
-                              help='launch activity of the application')
-  optional_named.add_argument('-s', '--simulate', dest='simulate',
-                              action='store_true',
-                              help='simulate the process without executing '
-                                   'any shell commands')
-  optional_named.add_argument('-d', '--debug', dest='debug',
-                              action='store_true',
-                              help='Add extra debugging output')
-  optional_named.add_argument('-i', '--input', action='store', dest='input',
-                              help='perfetto trace file protobuf',
-                              default='TraceFile.pb')
-  optional_named.add_argument('-r', '--readahead', action='store',
-                              dest='readahead',
-                              help='which readahead mode to use',
-                              default='cold',
-                              choices=('warm', 'cold', 'mlock', 'fadvise'))
-  optional_named.add_argument('-t', '--timeout', dest='timeout', action='store',
-                              type=int,
-                              help='Timeout after this many seconds when '
-                                   'executing a single run.',
-                              default=10)
-  optional_named.add_argument('--compiler-filter', dest='compiler_filter',
-                              action='store',
-                              help='Which compiler filter to use.',
-                              default=None)
-
-  return parser.parse_args(argv)
-
-def main():
-  opts = parse_options()
-  runner = PrefetchAppRunner(**vars(opts))
-  result = runner.run()
-
-  if result is None:
-    return 1
-
-  print(result)
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/startop/scripts/app_startup/run_app_with_prefetch_test.py b/startop/scripts/app_startup/run_app_with_prefetch_test.py
deleted file mode 100644
index 8a588e4..0000000
--- a/startop/scripts/app_startup/run_app_with_prefetch_test.py
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Unit tests for the run_app_with_prefetch_test.py script.
-
-Install:
-  $> sudo apt-get install python3-pytest   ##  OR
-  $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
-  $> ./run_app_with_prefetch_test.py
-  $> pytest run_app_with_prefetch_test.py
-  $> python -m pytest run_app_with_prefetch_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-import io
-import os
-import shlex
-import sys
-import tempfile
-# global imports
-from contextlib import contextmanager
-
-# pip imports
-import pytest
-# local imports
-import run_app_with_prefetch as runner
-from mock import call, patch, Mock
-
-sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from app_startup.lib.app_runner import AppRunner
-#
-# Argument Parsing Helpers
-#
-
-@contextmanager
-def ignore_stdout_stderr():
-  """Ignore stdout/stderr output for duration of this context."""
-  old_stdout = sys.stdout
-  old_stderr = sys.stderr
-  sys.stdout = io.StringIO()
-  sys.stderr = io.StringIO()
-  try:
-    yield
-  finally:
-    sys.stdout = old_stdout
-    sys.stderr = old_stderr
-
-@contextmanager
-def argparse_bad_argument(msg):
-  """Asserts that a SystemExit is raised when executing this context.
-
-  If the assertion fails, print the message 'msg'.
-  """
-  with pytest.raises(SystemExit, message=msg):
-    with ignore_stdout_stderr():
-      yield
-
-def assert_bad_argument(args, msg):
-  """Asserts that the command line arguments in 'args' are malformed.
-
-    Prints 'msg' if the assertion fails.
-  """
-  with argparse_bad_argument(msg):
-    parse_args(args)
-
-def parse_args(args):
-  """
-    :param args: command-line like arguments as a single string
-    :return:  dictionary of parsed key/values
-    """
-  # "-a b -c d"    => ['-a', 'b', '-c', 'd']
-  return vars(runner.parse_options(shlex.split(args)))
-
-def default_dict_for_parsed_args(**kwargs):
-  """Combines it with all of the "optional" parameters' default values."""
-  d = {
-    'readahead': 'cold',
-    'simulate': None,
-    'simulate': False,
-    'debug': False,
-    'input': 'TraceFile.pb',
-    'timeout': 10,
-    'compiler_filter': None,
-    'activity': None
-  }
-  d.update(kwargs)
-  return d
-
-def default_mock_dict_for_parsed_args(include_optional=True, **kwargs):
-  """Combines default dict with all optional parameters with some mock required
-    parameters.
-    """
-  d = {'package': 'com.fake.package'}
-  if include_optional:
-    d.update(default_dict_for_parsed_args())
-  d.update(kwargs)
-  return d
-
-def parse_optional_args(str):
-  """
-    Parses an argument string which already includes all the required arguments
-    in default_mock_dict_for_parsed_args.
-  """
-  req = '--package com.fake.package'
-  return parse_args('%s %s' % (req, str))
-
-def test_argparse():
-  # missing arguments
-  assert_bad_argument('', '-p are required')
-
-  # required arguments are parsed correctly
-  ad = default_dict_for_parsed_args  # assert dict
-  assert parse_args('--package xyz') == ad(package='xyz')
-
-  assert parse_args('-p xyz') == ad(package='xyz')
-
-  assert parse_args('-p xyz -s') == ad(package='xyz', simulate=True)
-  assert parse_args('-p xyz --simulate') == ad(package='xyz', simulate=True)
-
-  # optional arguments are parsed correctly.
-  mad = default_mock_dict_for_parsed_args  # mock assert dict
-  assert parse_optional_args('--input trace.pb') == mad(input='trace.pb')
-
-  assert parse_optional_args('--compiler-filter speed') == \
-         mad(compiler_filter='speed')
-
-  assert parse_optional_args('-d') == mad(debug=True)
-  assert parse_optional_args('--debug') == mad(debug=True)
-
-  assert parse_optional_args('--timeout 123') == mad(timeout=123)
-  assert parse_optional_args('-t 456') == mad(timeout=456)
-
-  assert parse_optional_args('-r warm') == mad(readahead='warm')
-  assert parse_optional_args('--readahead warm') == mad(readahead='warm')
-
-  assert parse_optional_args('-a act') == mad(activity='act')
-  assert parse_optional_args('--activity act') == mad(activity='act')
-
-def test_main():
-  args = '--package com.fake.package --activity act -s'
-  opts = runner.parse_options(shlex.split(args))
-  result = runner.PrefetchAppRunner(**vars(opts)).run()
-  assert result == [('TotalTime', '123')]
-
-def _mocked_run_shell_command(*args, **kwargs):
-  if args[0] == 'adb shell ps | grep "music" | awk \'{print $2;}\'':
-    return (True, '9999')
-  else:
-    return (True, '')
-
-def test_preprocess_no_cache_drop():
-  with patch('lib.cmd_utils.run_shell_command',
-             new_callable=Mock) as mock_run_shell_command:
-    mock_run_shell_command.side_effect = _mocked_run_shell_command
-    prefetch_app_runner = runner.PrefetchAppRunner(package='music',
-                                                   activity='MainActivity',
-                                                   readahead='warm',
-                                                   compiler_filter=None,
-                                                   timeout=None,
-                                                   simulate=False,
-                                                   debug=False,
-                                                   input=None)
-
-    prefetch_app_runner.preprocess()
-
-    calls = [call('adb root'),
-             call('adb shell "getenforce"'),
-             call('adb shell "setenforce 0"'),
-             call('adb shell "stop"'),
-             call('adb shell "start"'),
-             call('adb wait-for-device'),
-             call('adb shell ps | grep "music" | awk \'{print $2;}\''),
-             call('adb shell "kill 9999"')]
-    mock_run_shell_command.assert_has_calls(calls)
-
-def test_preprocess_with_cache_drop():
-  with patch('lib.cmd_utils.run_shell_command',
-             new_callable=Mock) as mock_run_shell_command:
-    mock_run_shell_command.side_effect = _mocked_run_shell_command
-    prefetch_app_runner = runner.PrefetchAppRunner(package='music',
-                                                   activity='MainActivity',
-                                                   readahead='cold',
-                                                   compiler_filter=None,
-                                                   timeout=None,
-                                                   simulate=False,
-                                                   debug=False,
-                                                   input=None)
-
-    prefetch_app_runner.preprocess()
-
-    calls = [call('adb root'),
-             call('adb shell "getenforce"'),
-             call('adb shell "setenforce 0"'),
-             call('adb shell "stop"'),
-             call('adb shell "start"'),
-             call('adb wait-for-device'),
-             call('adb shell ps | grep "music" | awk \'{print $2;}\''),
-             call('adb shell "kill 9999"'),
-             call('adb shell "echo 3 > /proc/sys/vm/drop_caches"')]
-    mock_run_shell_command.assert_has_calls(calls)
-
-def test_preprocess_with_cache_drop_and_iorapd_enabled():
-  with patch('lib.cmd_utils.run_shell_command',
-             new_callable=Mock) as mock_run_shell_command:
-    mock_run_shell_command.side_effect = _mocked_run_shell_command
-
-    with tempfile.NamedTemporaryFile() as input:
-      prefetch_app_runner = runner.PrefetchAppRunner(package='music',
-                                                     activity='MainActivity',
-                                                     readahead='fadvise',
-                                                     compiler_filter=None,
-                                                     timeout=None,
-                                                     simulate=False,
-                                                     debug=False,
-                                                     input=input.name)
-
-      prefetch_app_runner.preprocess()
-
-      calls = [call('adb root'),
-               call('adb shell "getenforce"'),
-               call('adb shell "setenforce 0"'),
-               call('adb shell "stop"'),
-               call('adb shell "start"'),
-               call('adb wait-for-device'),
-               call(
-                   'adb shell ps | grep "music" | awk \'{print $2;}\''),
-               call('adb shell "kill 9999"'),
-               call('adb shell "echo 3 > /proc/sys/vm/drop_caches"'),
-               call('bash -c "source {}; iorapd_readahead_enable"'.
-                    format(AppRunner.IORAP_COMMON_BASH_SCRIPT))]
-      mock_run_shell_command.assert_has_calls(calls)
-
-@patch('lib.adb_utils.blocking_wait_for_logcat_displayed_time')
-@patch('lib.cmd_utils.run_shell_command')
-def test_postprocess_with_launch_cleanup(
-    mock_run_shell_command,
-    mock_blocking_wait_for_logcat_displayed_time):
-  mock_run_shell_command.side_effect = _mocked_run_shell_command
-  mock_blocking_wait_for_logcat_displayed_time.return_value = 123
-
-  with tempfile.NamedTemporaryFile() as input:
-    prefetch_app_runner = runner.PrefetchAppRunner(package='music',
-                                                   activity='MainActivity',
-                                                   readahead='fadvise',
-                                                   compiler_filter=None,
-                                                   timeout=10,
-                                                   simulate=False,
-                                                   debug=False,
-                                                   input=input.name)
-
-    prefetch_app_runner.postprocess('2019-07-02 23:20:06.972674825')
-
-    calls = [
-        call('bash -c "source {script_path}; '
-             'iorapd_readahead_wait_until_finished '
-             '\'{package}\' \'{activity}\' \'{timestamp}\' \'{timeout}\'"'.
-                 format(timeout=10,
-                        package='music',
-                        activity='MainActivity',
-                        timestamp='2019-07-02 23:20:06.972674825',
-                        script_path=AppRunner.IORAP_COMMON_BASH_SCRIPT)),
-        call('bash -c "source {}; iorapd_readahead_disable"'.
-             format(AppRunner.IORAP_COMMON_BASH_SCRIPT)),
-        call('adb shell ps | grep "music" | awk \'{print $2;}\''),
-        call('adb shell "kill 9999"')]
-    mock_run_shell_command.assert_has_calls(calls)
-
-if __name__ == '__main__':
-  pytest.main()
diff --git a/startop/scripts/app_startup/unlock_screen b/startop/scripts/app_startup/unlock_screen
deleted file mode 100755
index 478294c..0000000
--- a/startop/scripts/app_startup/unlock_screen
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2018, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This turns the screen on if it's off.
-# If it's on it does nothing unless its on the home screen, in which case it opens up some background
-# menu.
-#
-# However, this menu is ignored because "am start" commands still work as expected.
-adb shell input keyevent MENU
diff --git a/startop/scripts/iorap/analyze_prefetch_file.py b/startop/scripts/iorap/analyze_prefetch_file.py
deleted file mode 100755
index 343cd54..0000000
--- a/startop/scripts/iorap/analyze_prefetch_file.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 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.
-
-import argparse
-import os
-import sys
-from typing import Dict, List, NamedTuple, Tuple
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))  # framework/base/startop/script
-import lib.print_utils as print_utils
-
-# Include generated protos.
-dir_name = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(dir_name + "/generated")
-
-from TraceFile_pb2 import *
-
-def parse_options(argv: List[str] = None):
-  """Parses command line arguments and returns an argparse Namespace object."""
-  parser = argparse.ArgumentParser(description="Analyze compiled_trace iorap protos.")
-  required_named = parser.add_argument_group('required named arguments')
-
-  required_named.add_argument('-i', dest='input', metavar='FILE',
-                              help='Read protobuf file as input')
-
-  optional_named = parser.add_argument_group('optional named arguments')
-
-  optional_named.add_argument('-up', dest='upper_percent', type=float,
-                              default=95.0,
-                              help='Only show the top-most entries up to this value.')
-
-  optional_named.add_argument('-r', dest='raw', action='store_true',
-                              help='Output entire raw file.')
-  optional_named.add_argument('-o', dest='output',
-                              help='The results are stored into the output file')
-  optional_named.add_argument('-d', dest='debug', action='store_true'
-                              , help='Activity of the app to be compiled')
-
-  return parser.parse_args(argv)
-
-def open_iorap_prefetch_file(file_path: str) -> TraceFile:
-  with open(file_path, "rb") as f:
-    tf = TraceFile()
-    tf.ParseFromString(f.read())
-    return tf
-
-def print_stats_summary(trace_file: TraceFile, upper_percent):
-  tf_dict = convert_to_dict(trace_file)
-  print_utils.debug_print(tf_dict)
-
-  total_length = 0
-  summaries = []
-  for name, entries_list in tf_dict.items():
-    summary = entries_sum(entries_list)
-    summaries.append(summary)
-
-    total_length += summary.length
-
-  # Sort by length
-  summaries.sort(reverse=True, key=lambda s: s.length)
-
-  percent_sum = 0.0
-  skipped_entries = 0
-
-  print("===========================================")
-  print("Total length: {:,} bytes".format(total_length))
-  print("Displayed upper percent: {:0.2f}%".format(upper_percent))
-  print("===========================================")
-  print("")
-  print("name,length,percent_of_total,upper_percent")
-  for sum in summaries:
-    percent_of_total = (sum.length * 1.0) / (total_length * 1.0) * 100.0
-
-    percent_sum += percent_of_total
-
-    if percent_sum > upper_percent:
-      skipped_entries = skipped_entries + 1
-      continue
-
-    #print("%s,%d,%.2f%%" %(sum.name, sum.length, percent_of_total))
-    print("{:s},{:d},{:0.2f}%,{:0.2f}%".format(sum.name, sum.length, percent_of_total, percent_sum))
-
-  if skipped_entries > 0:
-    print("[WARNING] Skipped {:d} entries, use -up=100 to show everything".format(skipped_entries))
-
-  pass
-
-class FileEntry(NamedTuple):
-  id: int
-  name: str
-  offset: int
-  length: int
-
-class FileEntrySummary(NamedTuple):
-  name: str
-  length: int
-
-def entries_sum(entries: List[FileEntry]) -> FileEntrySummary:
-  if not entries:
-    return None
-
-  summary = FileEntrySummary(name=entries[0].name, length=0)
-  for entry in entries:
-    summary = FileEntrySummary(summary.name, summary.length + entry.length)
-
-  return summary
-
-def convert_to_dict(trace_file: TraceFile) -> Dict[str, FileEntry]:
-  trace_file_index = trace_file.index
-
-  # entries.id -> entry.file_name
-  entries_map = {}
-
-  index_entries = trace_file_index.entries
-  for entry in index_entries:
-    entries_map[entry.id] = entry.file_name
-
-  final_map = {}
-
-  file_entries_map = {}
-  file_entries = trace_file.list.entries
-  for entry in file_entries:
-    print_utils.debug_print(entry)
-
-    lst = file_entries_map.get(entry.index_id, [])
-    file_entries_map[entry.index_id] = lst
-
-    file_name = entries_map[entry.index_id]
-    file_entry = \
-        FileEntry(id=entry.index_id, name=file_name, offset=entry.file_offset, length=entry.file_length)
-
-    lst.append(file_entry)
-
-    final_map[file_name] = lst
-
-  return final_map
-
-def main(argv: List[str]) -> int:
-  opts = parse_options(argv[1:])
-  if opts.debug:
-    print_utils.DEBUG = opts.debug
-  print_utils.debug_print(opts)
-
-  prefetch_file = open_iorap_prefetch_file(opts.input)
-
-  if opts.raw:
-    print(prefetch_file)
-
-  print_stats_summary(prefetch_file, opts.upper_percent)
-
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv))
diff --git a/startop/scripts/iorap/collector b/startop/scripts/iorap/collector
deleted file mode 100755
index 3dc080a..0000000
--- a/startop/scripts/iorap/collector
+++ /dev/null
@@ -1,403 +0,0 @@
-#!/bin/bash
-#
-# Copyright 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.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-APP_STARTUP_DIR="$DIR/../app_startup/"
-source "$DIR/common"
-
-usage() {
-    cat <<EOF
-Usage: collector [OPTIONS]...
-
-Runs an application, causes an iorap trace to be collected for it, and then invokes the iorap
-compiler to generate a TraceFile.pb.
-
-    -p, --package               package of the app to test
-    -a, --activity              activity of the app to test
-    -h, --help                  usage information (this)
-    -v, --verbose               enable extra verbose printing
-    -i, --inodes                path to inodes file (system/extras/pagecache/pagecache.py -d inodes)
-    -b, --trace_buffer_size     how big to make trace buffer size (default 32768)
-    -w, --wait_time             how long to run systrace for (default 10) in seconds
-    -c, --compiler-filter       override the compilation filter if set (default none)
-    -o, --output                output trace file protobuf (default 'TraceFile.pb')
-EOF
-}
-
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-trace_buffer_size=32768
-wait_time=10
-comp_filter=""
-output_dest="TraceFile.pb"
-
-parse_arguments() {
-  while [[ $# -gt 0 ]]; do
-    case "$1" in
-      -a|--activity)
-        activity="$2"
-        shift
-        ;;
-      -h|--help)
-        usage
-        exit 0
-        ;;
-      -p|--package)
-        package="$2"
-        shift
-        ;;
-      -i|--inodes)
-        inodes="$2"
-        shift
-        ;;
-      -b|--trace_buffer_size)
-        trace_buffer_size="$2"
-        shift
-        ;;
-      -w|--wait_time)
-        wait_time="$2"
-        shift
-        ;;
-      -c|--compiler-filter)
-        comp_filter="$2"
-        shift
-        ;;
-      -o|--output)
-        output_dest="$2"
-        shift
-        ;;
-      -v|--verbose)
-        verbose="y"
-        ;;
-    esac
-    shift
-  done
-}
-
-remote_pidof() {
-  local procname="$1"
-  adb shell ps | grep "$procname" | awk '{print $2;}'
-}
-
-remote_pkill() {
-  local procname="$1"
-  shift
-
-  local the_pids=$(remote_pidof "$procname")
-  local pid
-
-  for pid in $the_pids; do
-    verbose_print adb shell kill "$@" "$pid"
-    adb shell kill "$@" "$pid"
-  done
-}
-
-force_package_compilation() {
-  local arg_comp_filter="$1"
-  local arg_package="$2"
-
-  if [[ $arg_comp_filter == speed-profile ]]; then
-    # Force the running app to dump its profiles to disk.
-    remote_pkill "$arg_package" -SIGUSR1
-    sleep 1 # give some time for above to complete.
-  fi
-
-  adb shell cmd package compile -m "$arg_comp_filter" -f "$arg_package"
-}
-
-parse_package_dumpsys_line() {
-  local what_left="$1"
-  local what_right="$2"
-  local line="$3"
-
-  if [[ $line == *${what_left}*${what_right}* ]]; then
-    found="${line#*$what_left}"
-    found="${found%$what_right*}"
-    echo "$found"
-    return 0
-  fi
-
-  return 1
-}
-
-parse_package_dumpsys_section() {
-  local what_left="$1"
-  local what_right="$2"
-  shift
-  local lines="$@"
-
-  lines="${lines//$'\n'/}"
-
-  local new_lines=()
-
-  local current_line=""
-  local newline=n
-  local line
-  for line in "${lines[@]}"; do
-    if [[ $line == *: ]]; then
-      newline=y
-      current_line=""
-      new_lines+=("$current_line")
-
-      parse_package_dumpsys_line "$what_left" "$what_right" "$current_line" && return 0
-    else
-      # strip all spaces from the start
-      line="${line//$' '/}"
-      current_line+="$line"
-      #prepend to current line
-    fi
-  done
-  [[ "$current_line" != "" ]] && new_lines+=("$current_line")
-
-  parse_package_dumpsys_line "$what_left" "$what_right" "$current_line" && return 0
-
-  return 1
-}
-
-parse_package_compilation() {
-  local pkg="$1"
-#    [com.google.android.apps.maps]
-
-  local compilation_filter
-  local is_prebuilt
-  local isa
-  local etc
-
-  local ret_code
-
-  read compilation_filter is_prebuilt isa etc <<< "$("$APP_STARTUP_DIR"/query_compiler_filter.py --package "$pkg")"
-  ret_code=$?
-
-  if [[ $ret_code -eq 0 && x$compilation_filter != x ]]; then
-    verbose_print "Package compilation info for $pkg was '$compilation_filter'"
-    echo "$compilation_filter"
-    return 0
-  else
-    verbose_print "query failed ret code $ret_code filter=$compilation_filter"
-  fi
-
-  return $ret_code
-}
-
-# Main entry point
-if [[ $# -eq 0 ]]; then
-  usage
-  exit 1
-else
-  parse_arguments "$@"
-
-  # if we do not have have package exit early with an error
-  [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 1
-
-  if [[ -z "$inodes" ]] || ! [[ -f $inodes ]]; then
-    echo "--inodes not specified" 1>&2
-    exit 1
-  fi
-
-  if [[ "$activity" == "" ]]; then
-    activity="$(get_activity_name "$package")"
-    if [[ "$activity" == "" ]]; then
-      echo "Activity name could not be found, invalid package name?" 1>&2
-      exit 1
-    else
-      verbose_print "Activity name inferred: " "$activity"
-    fi
-  fi
-fi
-
-adb root > /dev/null
-
-if [[ "$(adb shell getenforce)" != "Permissive" ]]; then
-  adb shell setenforce 0
-  adb shell stop
-  adb shell start
-  adb wait-for-device
-fi
-
-compilation_was="$(parse_package_compilation "$package")"
-if [[ $? -ne 0 ]]; then
-  echo "Could not determine package compilation filter; was this package installed?" >&2
-  exit 1
-fi
-verbose_print "Package compilation: $compilation_was"
-
-# Cannot downgrade (e.g. from speed-profile to quicken) without forceful recompilation.
-# Forceful recompilation will recompile even if compilation filter was unchanged.
-# Therefore avoid recompiling unless the filter is actually different than what we asked for.
-if [[ "x$comp_filter" != "x" ]] && [[ "$compilation_was" != "$comp_filter" ]]; then
-  echo "Current compilation filter is '$compilation_was'; force recompile to '$comp_filter'" >&2
-  #TODO: this matching seems hopelessly broken, it will always recompile.
-
-  force_package_compilation "$comp_filter" "$package"
-fi
-
-# Drop all caches prior to beginning a systrace, otherwise we won't record anything already in pagecache.
-adb shell "echo 3 > /proc/sys/vm/drop_caches"
-
-trace_tmp_file="$(mktemp -t trace.XXXXXXXXX.html)"
-
-function finish {
-  [[ -f "$trace_tmp_file" ]] &&  rm "$trace_tmp_file"
-}
-trap finish EXIT
-
-launch_application_and_wait_for_trace() {
-  local package="$1"
-  local activity="$2"
-  local timeout=30 # seconds
-
-  # Ensure application isn't running already.
-  remote_pkill "$package"
-
-  # 5 second trace of Home screen causes
-  # a trace of the home screen.
-  # There is no way to abort the trace
-  # so just wait for it to complete instead.
-  sleep 30
-
-  local time_now="$(logcat_save_timestamp)"
-  local retcode=0
-
-  verbose_print "Drop caches for non-warm start."
-  # Drop all caches to get cold starts.
-  adb shell "echo 3 > /proc/sys/vm/drop_caches"
-
-  verbose_print "now launching application"
-  # Launch an application
-  "$APP_STARTUP_DIR"/launch_application "$package" "$activity"
-  retcode=$?
-  if [[ $retcode -ne 0 ]]; then
-    echo "FATAL: Application launch failed." >&2
-    return $retcode
-  fi
-
-  # This blocks until 'am start' returns at which point the application is
-  # already to be considered "started" as the first frame has been drawn.
-
-  # TODO: check for cold start w.r.t to activitymanager?
-
-  # Wait for application to start from the point of view of ActivityTaskManager.
-  local pattern="ActivityTaskManager: Displayed $package"
-  logcat_wait_for_pattern "$timeout" "$time_now" "$pattern"
-  retcode=$?
-  if [[ $retcode -ne 0 ]]; then
-    echo "FATAL: Could not find '$pattern' in logcat." >&2
-    return $retcode
-  fi
-
-  # Wait for iorapd to finish writing out the perfetto traces for this app.
-  iorapd_perfetto_wait_for_app_trace "$package" "$activity" "$timeout" "$time_now"
-  retcode=$?
-  if [[ $retcode -ne 0 ]]; then
-    echo "FATAL: Could not save perfetto app trace file." >&2
-    return $retcode
-  fi
-
-  verbose_print "iorapd has finished collecting app trace file for $package/$activity"
-}
-
-collector_main() {
-  # don't even bother trying to run anything until the screen is unlocked.
-  "$APP_STARTUP_DIR"/unlock_screen
-
-  # Don't mutate state while iorapd is running.
-  iorapd_stop || return $?
-
-  # Remove all existing metadata for a package/activity in iorapd.
-  iorapd_perfetto_purge_app_trace "$package" "$activity" || return $?
-  iorapd_compiler_purge_trace_file "$package" "$activity" || return $?
-
-  iorapd_perfetto_enable || return $?
-  iorapd_readahead_disable || return $?
-  iorapd_start || return $?
-
-  # Wait for perfetto trace to finished writing itself out.
-  launch_application_and_wait_for_trace "$package" "$activity" || return $?
-
-  # Pull the perfetto trace for manual inspection.
-  iorapd_perfetto_pull_trace_file "$package" "$activity" "perfetto_trace.pb"
-
-  # Compile the trace so that the next app run can use prefetching.
-  iorapd_compiler_for_app_trace "$package" "$activity" "$inodes" || return $?
-
-  # Save TraceFile.pb to local file.
-  iorapd_compiler_pull_trace_file "$package" "$activity" "$output_dest" || return $?
-  # Remove the TraceFile.pb from the device.
-  iorapd_compiler_purge_trace_file "$package" "$activity" || return $?
-
-  # TODO: better transactional support for restoring iorapd global properties
-  iorapd_perfetto_disable || return $?
-}
-
-collector_main "$@"
-
-verbose_print "Collector finished. Children: "
-if [[ $verbose == y ]]; then
-  jobs -p
-  ps f -g$$
-fi
-
-exit $?
-
-
-verbose_print "About to begin systrace"
-coproc systrace_fd {
-  # Disable stdout buffering since we need to know the output of systrace RIGHT AWAY.
-  stdbuf -oL "$ANDROID_BUILD_TOP"/external/chromium-trace/systrace.py --target=android -b "$trace_buffer_size" -t "$wait_time" am pagecache dalvik -o "$trace_tmp_file"
-}
-
-verbose_print "Systrace began"
-
-systrace_pid="$!"
-
-while read -r -u "${systrace_fd[0]}" systrace_output; do
-  verbose_print "$systrace_output"
-  if [[ "$systrace_output" == *"Starting tracing"* ]]; then
-    verbose_print "WE DID SEE STARTING TRACING."
-    break
-  fi
-done
-# Systrace has begun recording the tracing.
-# Run the application and collect the results.
-
-am_output="$(adb shell am start -S -W "$package"/"$activity")"
-if [[ $? -ne 0 ]]; then
-  echo "am start failed" >&2
-
-  exit 1
-fi
-
-verbose_print "$am_output"
-total_time="$(echo "$am_output" | grep 'TotalTime:' | sed 's/TotalTime: //g')"
-verbose_print "total time: $total_time"
-
-# Now wait for systrace to finish.
-
-wait "$systrace_pid" || { echo "Systrace finished before am start was finished, try a longer --wait_time"; exit 1; }
-verbose_print "Systrace has now finished"
-verbose_print "$(ls -la "$trace_tmp_file")"
-
-
-iorapd_perfetto_disable
-
-# Now that systrace has finished, convert the trace file html file to a protobuf.
-
-"$ANDROID_BUILD_TOP"/system/iorap/src/py/collector/trace_parser.py -i "$inodes" -t "$trace_tmp_file" -o "$output_dest" || exit 1
-
-echo "Trace file collection complete, trace file saved to \"$output_dest\"!" >&2
-
-finish
diff --git a/startop/scripts/iorap/common b/startop/scripts/iorap/common
deleted file mode 100755
index 387e45d..0000000
--- a/startop/scripts/iorap/common
+++ /dev/null
@@ -1,253 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR_IORAP_COMMON="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-APP_STARTUP_DIR="$DIR_IORAP_COMMON/../app_startup/"
-source "$APP_STARTUP_DIR/lib/common"
-
-IORAPD_DATA_PATH="/data/misc/iorapd"
-
-iorapd_start() {
-  verbose_print 'iorapd_start'
-  adb shell start iorapd
-  sleep 1
-  # TODO: block until logcat prints successfully connecting
-}
-
-iorapd_stop() {
-  verbose_print 'iorapd_stop'
-  adb shell stop iorapd
-}
-
-iorapd_reset() {
-  iorapd_stop
-  iorapd_start
-}
-
-# Enable perfetto tracing.
-# Subsequent launches of an application will record a perfetto trace protobuf.
-iorapd_perfetto_enable() {
-  verbose_print 'enable perfetto'
-  adb shell setprop iorapd.perfetto.enable true
-  iorapd_reset # iorapd only reads this flag when initializing
-}
-
-# Disable perfetto tracing.
-# Subsequent launches of applications will no longer record perfetto trace protobufs.
-iorapd_perfetto_disable() {
-  verbose_print 'disable perfetto'
-  adb shell setprop iorapd.perfetto.enable false
-  iorapd_reset # iorapd only reads this flag when initializing
-}
-
-# Enable readahead
-# Subsequent launches of an application will be sped up by iorapd readahead prefetching
-# (Provided an appropriate compiled trace exists for that application)
-iorapd_readahead_enable() {
-  if [[ "$(adb shell getprop iorapd.readahead.enable)" == true ]]; then
-    verbose_print 'enable readahead [already enabled]'
-    return 0
-  fi
-  verbose_print 'enable readahead [reset iorapd]'
-  adb shell setprop iorapd.readahead.enable true
-  iorapd_reset # iorapd only reads this flag when initializing
-}
-
-# Disable readahead
-# Subsequent launches of an application will be not be sped up by iorapd readahead prefetching.
-iorapd_readahead_disable() {
-  if [[ "$(adb shell getprop iorapd.readahead.enable)" == false ]]; then
-    verbose_print 'disable readahead [already disabled]'
-    return 0
-  fi
-  verbose_print 'disable readahead [reset iorapd]'
-  adb shell setprop iorapd.readahead.enable false
-  iorapd_reset # iorapd only reads this flag when initializing
-}
-
-_iorapd_path_to_data_file() {
-  local package="$1"
-  local activity="$2"
-  local suffix="$3"
-
-  # Match logic of 'AppComponentName' in iorap::compiler C++ code.
-  echo "${IORAPD_DATA_PATH}/${package}%2F${activity}.${suffix}"
-}
-
-iorapd_perfetto_wait_for_app_trace() {
-  local package="$1"
-  local activity="$2"
-  local timeout="$3"
-  local timestamp="$4"
-
-  local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
-
-  verbose_print "iorapd_perfetto_wait_for_app_trace on file '$remote_path'"
-
-  # see event_manager.cc
-  local pattern="Perfetto TraceBuffer saved to file: $remote_path"
-  logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
-}
-
-# Purge all perfetto traces for a given application.
-iorapd_perfetto_purge_app_trace() {
-  local package="$1"
-  local activity="$2"
-
-  local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
-
-  verbose_print 'iorapd-perfetto: purge app trace in ' "$remote_path"
-  adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
-}
-
-# Pull the remote perfetto trace file into a local file.
-iorapd_perfetto_pull_trace_file() {
-  local package="$1"
-  local activity="$2"
-  local output_file="$3" # local path
-
-  local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
-
-  if ! adb shell "[[ -f '$compiled_path' ]]"; then
-    echo "Error: Remote path '$compiled_path' invalid" >&2
-    return 1
-  fi
-  if ! mkdir -p "$(dirname "$output_file")"; then
-    echo "Error: Fail to make output directory for '$output_file'" >&2
-    return 1
-  fi
-  verbose_print adb pull "$compiled_path" "$output_file"
-  adb pull "$compiled_path" "$output_file"
-}
-
-# Compile a perfetto trace for a given application.
-# This requires the app has run at least once with perfetto tracing enabled.
-iorapd_compiler_for_app_trace() {
-  local package="$1"
-  local activity="$2"
-  local inodes="$3" # local path
-
-  # remote path calculations
-  local input_path="$(_iorapd_path_to_data_file "$package" "$activity" "perfetto_trace.pb")"
-  local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.tmp.pb")"
-  local compiled_path_final="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
-  if ! adb shell "[[ -f '$input_path' ]]"; then
-    echo "Error: Missing perfetto traces; nothing to compile. Expected: '$input_path'" >&2
-    return 1
-  fi
-
-  if ! [[ -f $inodes ]]; then
-    # We could compile using 'diskscan' but it's non-deterministic, so refuse instead.
-    echo "Error: Missing inodes textcache at '$inodes'; refusing to compile." >&2
-    return 1
-  fi
-
-  # inodes file needs to be on the device for iorap.cmd.compiler to access it
-  local remote_inodes=/data/local/tmp/prefetch/inodes.txt
-  adb shell "mkdir -p \"$(dirname "$remote_inodes")\"" || return 1
-  verbose_print adb push "$inodes" "$remote_inodes"
-  adb push "$inodes" "$remote_inodes"
-
-  verbose_print 'iorapd-compiler: compile app trace in ' "$input_path"
-  verbose_print adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
-  adb shell "iorap.cmd.compiler '$input_path' --inode-textcache '$remote_inodes' --output-proto '$compiled_path'"
-  retcode=$?
-
-  # Don't overwrite the true 'compiled_trace.pb' unless the compiler completed without error.
-  # TODO: The native compiler code should be handling its own transaction-safety.
-  if [[ $retcode -eq 0 ]]; then
-    adb shell "mv '$compiled_path' '$compiled_path_final'"
-  else
-    adb shell "[[ -f '$compiled_path' ]] && rm -f '$compiled_path'"
-  fi
-
-  # Clean up inodes file we just pushed.
-#  adb shell "[[ -f '$remote_inodes' ]] && rm -f '$remote_inodes'"
-
-  return $retcode
-}
-
-# Pull the remote compiled trace file into a local file.
-iorapd_compiler_pull_trace_file() {
-  local package="$1"
-  local activity="$2"
-  local output_file="$3" # local path
-
-  local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
-  if ! adb shell "[[ -f '$compiled_path' ]]"; then
-    echo "Error: Remote path '$compiled_path' invalid" >&2
-    return 1
-  fi
-  if ! mkdir -p "$(dirname "$output_file")"; then
-    echo "Error: Fail to make output directory for '$output_file'" >&2
-    return 1
-  fi
-  verbose_print adb pull "$compiled_path" "$output_file"
-  adb pull "$compiled_path" "$output_file"
-}
-
-# Install a compiled trace file.
-iorapd_compiler_install_trace_file() {
-  local package="$1"
-  local activity="$2"
-  local input_file="$3" # local path
-
-  # remote path calculations
-  local compiled_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
-  if ! [[ -f $input_file ]]; then
-    echo "Error: File '$input_file' does not exist." >&2
-    return 1
-  fi
-
-  adb shell "mkdir -p \"$(dirname "$compiled_path")\"" || return 1
-
-  verbose_print adb push "$input_file" "$compiled_path"
-  adb push "$input_file" "$compiled_path"
-}
-
-iorapd_compiler_purge_trace_file() {
-  local package="$1"
-  local activity="$2"
-  local input_file="$3" # local path
-
-  local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
-  adb shell "[[ -f '$remote_path' ]] && rm -f '$remote_path' || exit 0"
-}
-
-# Blocks until the readahead for the requested package/activity has finished.
-# This assumes that the trace file was already installed, and also that
-# the application launched but not completed yet.
-iorapd_readahead_wait_until_finished() {
-  local package="$1"
-  local activity="$2"
-  local timestamp="$3"
-  local timeout="$4"
-
-  if [[ $# -lt 4 ]]; then
-    echo "FATAL: Expected 4 arguments (actual $# $@)" >&2
-    exit 1
-  fi
-
-  local remote_path="$(_iorapd_path_to_data_file "$package" "$activity" "compiled_trace.pb")"
-
-  # See 'read_ahead.cc' LOG(INFO).
-  local pattern="Description = $remote_path"
-  logcat_wait_for_pattern "$timeout" "$timestamp" "$pattern"
-}
diff --git a/startop/scripts/iorap/compile_handcrafted_file.py b/startop/scripts/iorap/compile_handcrafted_file.py
deleted file mode 100755
index 6dbbeaf..0000000
--- a/startop/scripts/iorap/compile_handcrafted_file.py
+++ /dev/null
@@ -1,297 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-import asyncio
-import csv
-import itertools
-import os
-import re
-import struct
-import sys
-import tempfile
-import time
-import zipfile
-from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union
-
-# Include generated protos.
-dir_name = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(dir_name + "/generated")
-
-from TraceFile_pb2 import *
-
-
-def parse_options(argv: List[str] = None):
-  """Parse command line arguments and return an argparse Namespace object."""
-  parser = argparse.ArgumentParser(description="Compile a TraceFile.proto from a manual text file.")
-  # argparse considers args starting with - and -- optional in --help, even though required=True.
-  # by using a named argument group --help will clearly say that it's required instead of optional.
-  required_named = parser.add_argument_group('required named arguments')
-
-  # optional arguments
-  # use a group here to get the required arguments to appear 'above' the optional arguments in help.
-  optional_named = parser.add_argument_group('optional named arguments')
-  optional_named.add_argument('-opb', '--output-proto-binary', dest='output_proto_binary', action='store', help='Write binary proto output to file.')
-  optional_named.add_argument('-pm', '--pinlist-meta', dest='pinlist_meta', action='store', help='Path to pinlist.meta (default=none) binary file.')
-  optional_named.add_argument('-pmp', '--pinlist-meta-parent', dest='pinlist_meta_parent', action='store', help='Device path that the pinlist.meta applies to (e.g. /data/.../somefile.apk)')
-  optional_named.add_argument('-i', '--input', dest='input', action='store', help='Input text file (default stdin).')
-  optional_named.add_argument('-zp', '--zip_path', dest='zip_path', action='append', help='Directory containing zip files.')
-  optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
-  optional_named.add_argument('-ot', '--output-text', dest='output_text', action='store', help='Output text file (default stdout).')
-
-  return parser.parse_args(argv)
-
-# TODO: refactor this with a common library file with analyze_metrics.py
-def _debug_print(*args, **kwargs):
-  """Print the args to sys.stderr if the --debug/-d flag was passed in."""
-  if _debug:
-    print(*args, **kwargs, file=sys.stderr)
-
-class BadInputError(Exception):
-  pass
-
-InputRecord = NamedTuple('InputRecord', [('filepath', str), ('offset', int), ('length', int), ('remark', str)])
-
-def find_zip_in_paths(original_name, zip_paths):
-  # /foo/bar/bax.zip -> bax.zip
-  file_basename = os.path.split(original_name)[1]
-
-  # the file must be located in one of the --zip-path arguments
-  matched = None
-  for zip_path in zip_paths:
-    for dir_entry in os.listdir(zip_path):
-      if dir_entry == file_basename:
-        matched = os.path.join(zip_path, dir_entry)
-        break
-    if matched:
-      break
-
-  if not matched:
-    raise ValueError("%s could not be found in any of the --zip_path specified." %(file_basename))
-
-  _debug_print("found zip file ", file_basename, " in ", matched)
-
-  if not zipfile.is_zipfile(matched):
-    raise ValueError("%s is not a zip file" %(matched))
-
-  return matched
-
-def handle_zip_entry(input_record, zip_paths):
-
-  res = re.match("([^!]+)[!](.*)", input_record.filepath)
-
-  if not res:
-    return input_record
-
-                         # 'foo!bar'
-  in_filepath = res[1]   # -> 'foo'
-  in_zip_entry = res[2]  # -> 'bar'
-
-  matched = find_zip_in_paths(in_filepath, zip_paths)
-
-  zip = zipfile.ZipFile(matched)
-
-  try:
-    zip_info = zip.getinfo(in_zip_entry)
-  except KeyError:
-    raise ValueError("%s is not an item in the zip file %s" %(in_zip_entry, matched))
-
-  # TODO: do we also need to add header size to this?
-  in_offset = zip_info.header_offset
-
-  # TODO: if a range is specified, use that instead.
-  in_length = zip_info.compress_size
-
-  return InputRecord(in_filepath, in_offset, in_length, 'zip entry (%s)' %(in_zip_entry))
-
-def parse_input_file(input: Iterable[str], zip_paths: List[str]) -> Iterable[InputRecord]:
-  for line in input:
-    line = line.strip()
-
-    _debug_print("Line = ", line)
-    if not line:
-      _debug_print("  skip empty line", line)
-      continue
-    elif line[0] == "#":
-      _debug_print("  skip commented line", line)
-      continue
-
-    res = re.match("([^\s]+)\s+(\d+)\s+(\d+)", line)
-    if not res:
-      raise BadInputError("Expected input of form: <str:filepath> <int:offset> <int:length>")
-
-    in_filepath = res[1]
-    in_offset = int(res[2])
-    in_length = int(res[3])
-
-    yield handle_zip_entry(InputRecord(in_filepath, in_offset, in_length, 'regular file'), zip_paths)
-
-# format:
-#   (<big_endian(i32):file_offset> <big_endian(i32):range_length>)+
-PIN_META_FORMAT = ">ii"
-PIN_META_READ_SIZE = struct.calcsize(PIN_META_FORMAT)
-
-def parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths):
-  if not pin_meta_file:
-    return ()
-
-  global PIN_META_FORMAT
-  global PIN_META_READ_SIZE
-
-  # '/data/app/com.google.android.GoogleCamera-aNQhzSznf4h_bvJ_MRbweQ==/base.apk'
-  #  -> 'com.google.android.GoogleCamera'
-  package_name_match = re.match('/.*/(.*)-.*=/base.apk', pinlist_meta_parent)
-
-  if not package_name_match:
-    raise ValueError("%s did not contain the <packagename>.apk" %(pinlist_meta_parent))
-
-  package_name = package_name_match[1]
-  # "com.google.android.GoogleCamera" -> "GoogleCamera.apk"
-  apk_name = package_name.split(".")[-1] + ".apk"
-
-  path_to_zip_on_host = find_zip_in_paths(apk_name, zip_paths)
-  apk_file_size = os.path.getsize(path_to_zip_on_host)
-  _debug_print("APK path '%s' file size '%d'" %(path_to_zip_on_host, apk_file_size))
-
-  while True:
-    data = pin_meta_file.read(PIN_META_READ_SIZE)
-
-    if not data:
-      break
-
-    (pin_offset, pin_length) = struct.unpack(PIN_META_FORMAT, data)  # (offset, length)
-
-    remark = 'regular file (pinlist.meta)'
-
-    remaining_size = apk_file_size - pin_offset
-    if remaining_size < 0:
-      print("WARNING: Clamp entry (%d, %d), offset too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size))
-
-      pin_length = pin_length + remaining_size
-      pin_offset = pin_offset + remaining_size
-
-      if pin_offset < 0:
-        pin_offset = 0
-
-      remark += '[clamped.offset]'
-
-    pin_last_offset = pin_offset + pin_length
-    remaining_size = apk_file_size - pin_last_offset
-
-    if remaining_size < 0:
-      print("WARNING: Clamp entry (%d, %d), length too large (max file size = %d)" %(pin_offset, pin_length, apk_file_size))
-      pin_length = pin_length + remaining_size
-
-      remark += '[clamped.length]'
-
-    yield InputRecord(pinlist_meta_parent, pin_offset, pin_length, remark)
-
-def write_text_file_output(input_records: Iterable[InputRecord], output_text_file):
-  for rec in input_records:
-    output_text_file.write("%s %d %d #%s\n" %(rec.filepath, rec.offset, rec.length, rec.remark))
-
-def build_trace_file(input_records: Iterable[InputRecord]) -> TraceFile:
-  trace_file = TraceFile()
-  trace_file_index = trace_file.index
-
-  file_id_counter = 0
-  file_id_map = {} # filename -> id
-
-  stats_length_total = 0
-  filename_stats = {} # filename -> total size
-
-  for rec in input_records:
-    filename = rec.filepath
-
-    file_id = file_id_map.get(filename)
-    if not file_id:
-      file_id = file_id_counter
-      file_id_map[filename] = file_id_counter
-      file_id_counter = file_id_counter + 1
-
-      file_index_entry = trace_file_index.entries.add()
-      file_index_entry.id = file_id
-      file_index_entry.file_name = filename
-
-    # already in the file index, add the file entry.
-    file_entry = trace_file.list.entries.add()
-    file_entry.index_id = file_id
-    file_entry.file_length = rec.length
-    stats_length_total += file_entry.file_length
-    file_entry.file_offset = rec.offset
-
-    filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length
-
-  return trace_file
-
-def main():
-  global _debug
-
-  options= parse_options()
-  _debug = options.debug
-  _debug_print("parsed options: ", options)
-
-  if not options.input:
-    input_file = sys.stdin
-    _debug_print("input = stdin")
-  else:
-    input_file = open(options.input)
-    _debug_print("input = (file)", options.input)
-
-  if not options.output_proto_binary:
-    output_proto_file = None
-  else:
-    output_proto_file = open(options.output_proto_binary, 'wb')
-  _debug_print("output_proto_binary = ", output_proto_file)
-
-  pinlist_meta_parent = options.pinlist_meta_parent
-  if options.pinlist_meta:
-    pin_meta_file = open(options.pinlist_meta, 'rb')
-  else:
-    pin_meta_file = None
-
-  if (pinlist_meta_parent == None) != (pin_meta_file == None):
-    print("Options must be used together: --pinlist-meta and --pinlist-meta-path")
-    return 1
-
-  if not options.output_text:
-    output_text_file = sys.stdout
-    _debug_print("output = stdout")
-  else:
-    output_text_file = open(options.output_text, 'w')
-    _debug_print("output = (file)", options.output_text)
-
-  zip_paths = options.zip_path or []
-
-  input_records = list(parse_pin_meta(pin_meta_file, pinlist_meta_parent, zip_paths))
-  input_records = input_records + list(parse_input_file(input_file, zip_paths))
-
-  for p in input_records:
-    _debug_print(p)
-
-  write_text_file_output(input_records, output_text_file)
-  output_text_file.close()
-
-  out_proto = build_trace_file(input_records)
-
-  if output_proto_file:
-    output_proto_file.write(out_proto.SerializeToString())
-    output_proto_file.close()
-
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/startop/scripts/iorap/compiler.py b/startop/scripts/iorap/compiler.py
deleted file mode 100644
index 1426d34..0000000
--- a/startop/scripts/iorap/compiler.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import importlib
-import os
-import sys
-import tempfile
-from enum import Enum
-from typing import TextIO, List
-
-# local import
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-import lib.print_utils as print_utils
-
-# Type of compiler.
-class CompilerType(Enum):
-  HOST = 1  # iorap.cmd.compiler on host
-  DEVICE = 2  # adb shell iorap.cmd.compiler
-  RI = 3  # compiler.py
-
-def compile_perfetto_trace_ri(
-    argv: List[str],
-    compiler) -> TextIO:
-  print_utils.debug_print('Compile using RI compiler.')
-  compiler_trace_file = tempfile.NamedTemporaryFile()
-  argv.extend(['-o', compiler_trace_file.name])
-  print_utils.debug_print(argv)
-  compiler.main([''] + argv)
-  return compiler_trace_file
-
-def compile_perfetto_trace_device(inodes_path: str,
-                                  package: str,
-                                  activity: str,
-                                  compiler) -> TextIO:
-  print_utils.debug_print('Compile using on-device compiler.')
-  compiler_trace_file = tempfile.NamedTemporaryFile()
-  compiler.main(inodes_path, package, activity, compiler_trace_file.name)
-  return compiler_trace_file
-
-def compile(compiler_type: CompilerType,
-            inodes_path: str,
-            ri_compiler_argv,
-            package: str,
-            activity: str) -> TextIO:
-  if compiler_type == CompilerType.RI:
-    compiler = importlib.import_module('iorap.compiler_ri')
-    compiler_trace_file = compile_perfetto_trace_ri(ri_compiler_argv,
-                                                    compiler)
-    return compiler_trace_file
-  if compiler_type == CompilerType.DEVICE:
-    compiler = importlib.import_module('iorap.compiler_device')
-    compiler_trace_file = compile_perfetto_trace_device(inodes_path,
-                                                        package,
-                                                        activity,
-                                                        compiler)
-    return compiler_trace_file
-
-  # Should not arrive here.
-  raise ValueError('Unknown compiler type')
diff --git a/startop/scripts/iorap/compiler_device.py b/startop/scripts/iorap/compiler_device.py
deleted file mode 100644
index d941cd9..0000000
--- a/startop/scripts/iorap/compiler_device.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-import os
-import sys
-from typing import List
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))  # framework/base/startop/script
-import lib.print_utils as print_utils
-import iorap.lib.iorapd_utils as iorapd_utils
-from app_startup.lib.app_runner import AppRunner
-
-IORAP_COMMON_BASH_SCRIPT = os.path.join(DIR, 'common')
-
-def parse_options(argv: List[str] = None):
-  """Parses command line arguments and returns an argparse Namespace object."""
-  parser = argparse.ArgumentParser(description="Compile perfetto trace file")
-  required_named = parser.add_argument_group('required named arguments')
-
-  required_named.add_argument('-i', dest='inodes', metavar='FILE',
-                              help='Read cached inode data from a file saved '
-                                   'earlier with pagecache.py -d')
-  required_named.add_argument('-p', dest='package',
-                              help='Package of the app to be compiled')
-
-  optional_named = parser.add_argument_group('optional named arguments')
-  optional_named.add_argument('-o', dest='output',
-                              help='The compiled trace is stored into the output file')
-  optional_named.add_argument('-a', dest='activity',
-                              help='Activity of the app to be compiled')
-  optional_named.add_argument('-d', dest='debug', action='store_true'
-                              , help='Activity of the app to be compiled')
-
-  return parser.parse_args(argv)
-
-def main(inodes, package, activity, output, **kwargs) -> int:
-  """Entries of the program."""
-  if not activity:
-    activity = AppRunner.get_activity(package)
-
-  passed = iorapd_utils.compile_perfetto_trace_on_device(package, activity,
-                                                         inodes)
-  if passed and output:
-    iorapd_utils.get_iorapd_compiler_trace(package, activity, output)
-
-  return 0
-
-if __name__ == '__main__':
-  opts = parse_options()
-  if opts.debug:
-    print_utils.DEBUG = opts.debug
-  print_utils.debug_print(opts)
-  sys.exit(main(**(vars(opts))))
diff --git a/startop/scripts/iorap/compiler_ri.py b/startop/scripts/iorap/compiler_ri.py
deleted file mode 100755
index 90fc8a8..0000000
--- a/startop/scripts/iorap/compiler_ri.py
+++ /dev/null
@@ -1,325 +0,0 @@
-#!/usr/bin/env python3
-
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Dependencies:
-#
-# $> sudo apt-get install python3-pip
-# $> pip3 install --user protobuf sqlalchemy sqlite3
-#
-
-import optparse
-import os
-import re
-import sys
-import tempfile
-from pathlib import Path
-from datetime import timedelta
-from typing import Iterable, Optional, List
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-sys.path.append(os.path.dirname(DIR))
-from iorap.generated.TraceFile_pb2 import *
-from iorap.lib.inode2filename import Inode2Filename
-
-parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-sys.path.append(parent_dir_name)
-from trace_analyzer.lib.trace2db import Trace2Db, MmFilemapAddToPageCache, \
-    RawFtraceEntry
-import lib.cmd_utils as cmd_utils
-
-_PAGE_SIZE = 4096 # adb shell getconf PAGESIZE ## size of a memory page in bytes.
-ANDROID_BUILD_TOP = Path(parent_dir_name).parents[3]
-TRACECONV_BIN = ANDROID_BUILD_TOP.joinpath(
-    'external/perfetto/tools/traceconv')
-
-class PageRun:
-  """
-  Intermediate representation for a run of one or more pages.
-  """
-  def __init__(self, device_number: int, inode: int, offset: int, length: int):
-    self.device_number = device_number
-    self.inode = inode
-    self.offset = offset
-    self.length = length
-
-  def __str__(self):
-    return "PageRun(device_number=%d, inode=%d, offset=%d, length=%d)" \
-        %(self.device_number, self.inode, self.offset, self.length)
-
-def debug_print(msg):
-  #print(msg)
-  pass
-
-UNDER_LAUNCH = False
-
-def page_cache_entries_to_runs(page_cache_entries: Iterable[MmFilemapAddToPageCache]):
-  global _PAGE_SIZE
-
-  runs = [
-      PageRun(device_number=pg_entry.dev, inode=pg_entry.ino, offset=pg_entry.ofs,
-              length=_PAGE_SIZE)
-        for pg_entry in page_cache_entries
-  ]
-
-  for r in runs:
-    debug_print(r)
-
-  print("Stats: Page runs totaling byte length: %d" %(len(runs) * _PAGE_SIZE))
-
-  return runs
-
-def optimize_page_runs(page_runs):
-  new_entries = []
-  last_entry = None
-  for pg_entry in page_runs:
-    if last_entry:
-      if pg_entry.device_number == last_entry.device_number and pg_entry.inode == last_entry.inode:
-        # we are dealing with a run for the same exact file as a previous run.
-        if pg_entry.offset == last_entry.offset + last_entry.length:
-          # trivially contiguous entries. merge them together.
-          last_entry.length += pg_entry.length
-          continue
-    # Default: Add the run without merging it to a previous run.
-    last_entry = pg_entry
-    new_entries.append(pg_entry)
-  return new_entries
-
-def is_filename_matching_filter(file_name, filters=[]):
-  """
-  Blacklist-style regular expression filters.
-
-  :return: True iff file_name has an RE match in one of the filters.
-  """
-  for filt in filters:
-    res = re.search(filt, file_name)
-    if res:
-      return True
-
-  return False
-
-def build_protobuf(page_runs, inode2filename, filters=[]):
-  trace_file = TraceFile()
-  trace_file_index = trace_file.index
-
-  file_id_counter = 0
-  file_id_map = {} # filename -> id
-
-  stats_length_total = 0
-  filename_stats = {} # filename -> total size
-
-  skipped_inode_map = {}
-  filtered_entry_map = {} # filename -> count
-
-  for pg_entry in page_runs:
-    fn = inode2filename.resolve(pg_entry.device_number, pg_entry.inode)
-    if not fn:
-      skipped_inode_map[pg_entry.inode] = skipped_inode_map.get(pg_entry.inode, 0) + 1
-      continue
-
-    filename = fn
-
-    if filters and not is_filename_matching_filter(filename, filters):
-      filtered_entry_map[filename] = filtered_entry_map.get(filename, 0) + 1
-      continue
-
-    file_id = file_id_map.get(filename)
-    # file_id could 0, which satisfies "if file_id" and causes duplicate
-    # filename for file id 0.
-    if file_id is None:
-      file_id = file_id_counter
-      file_id_map[filename] = file_id_counter
-      file_id_counter = file_id_counter + 1
-
-      file_index_entry = trace_file_index.entries.add()
-      file_index_entry.id = file_id
-      file_index_entry.file_name = filename
-
-    # already in the file index, add the file entry.
-    file_entry = trace_file.list.entries.add()
-    file_entry.index_id = file_id
-    file_entry.file_length = pg_entry.length
-    stats_length_total += file_entry.file_length
-    file_entry.file_offset = pg_entry.offset
-
-    filename_stats[filename] = filename_stats.get(filename, 0) + file_entry.file_length
-
-  for inode, count in skipped_inode_map.items():
-    print("WARNING: Skip inode %s because it's not in inode map (%d entries)" %(inode, count))
-
-  print("Stats: Sum of lengths %d" %(stats_length_total))
-
-  if filters:
-    print("Filter: %d total files removed." %(len(filtered_entry_map)))
-
-    for fn, count in filtered_entry_map.items():
-      print("Filter: File '%s' removed '%d' entries." %(fn, count))
-
-  for filename, file_size in filename_stats.items():
-    print("%s,%s" %(filename, file_size))
-
-  return trace_file
-
-def calc_trace_end_time(trace2db: Trace2Db,
-                        trace_duration: Optional[timedelta]) -> float:
-  """
-  Calculates the end time based on the trace duration.
-  The start time is the first receiving mm file map event.
-  The end time is the start time plus the trace duration.
-  All of them are in milliseconds.
-  """
-  # If the duration is not set, assume all time is acceptable.
-  if trace_duration is None:
-    # float('inf')
-    return RawFtraceEntry.__table__.c.timestamp.type.python_type('inf')
-
-  first_event = trace2db.session.query(MmFilemapAddToPageCache).join(
-      MmFilemapAddToPageCache.raw_ftrace_entry).order_by(
-      RawFtraceEntry.timestamp).first()
-
-  # total_seconds() will return a float number.
-  return first_event.raw_ftrace_entry.timestamp + trace_duration.total_seconds()
-
-def query_add_to_page_cache(trace2db: Trace2Db, trace_duration: Optional[timedelta]):
-  end_time = calc_trace_end_time(trace2db, trace_duration)
-  # SELECT * FROM tbl ORDER BY id;
-  return trace2db.session.query(MmFilemapAddToPageCache).join(
-      MmFilemapAddToPageCache.raw_ftrace_entry).filter(
-      RawFtraceEntry.timestamp <= end_time).order_by(
-      MmFilemapAddToPageCache.id).all()
-
-def transform_perfetto_trace_to_systrace(path_to_perfetto_trace: str,
-                                         path_to_tmp_systrace: str) -> None:
-  """ Transforms the systrace file from perfetto trace. """
-  cmd_utils.run_command_nofail([str(TRACECONV_BIN),
-                                'systrace',
-                                path_to_perfetto_trace,
-                                path_to_tmp_systrace])
-
-
-def run(sql_db_path:str,
-        trace_file:str,
-        trace_duration:Optional[timedelta],
-        output_file:str,
-        inode_table:str,
-        filter:List[str]) -> int:
-  trace2db = Trace2Db(sql_db_path)
-  # Speed optimization: Skip any entries that aren't mm_filemap_add_to_pagecache.
-  trace2db.set_raw_ftrace_entry_filter(\
-      lambda entry: entry['function'] == 'mm_filemap_add_to_page_cache')
-  # TODO: parse multiple trace files here.
-  parse_count = trace2db.parse_file_into_db(trace_file)
-
-  mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db,
-                                                              trace_duration)
-  print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows)))
-
-  page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows)
-  print("DONE. Converted %d entries" %(len(page_runs)))
-
-  # TODO: flags to select optimizations.
-  optimized_page_runs = optimize_page_runs(page_runs)
-  print("DONE. Optimized down to %d entries" %(len(optimized_page_runs)))
-
-  print("Build protobuf...")
-  trace_file = build_protobuf(optimized_page_runs, inode_table, filter)
-
-  print("Write protobuf to file...")
-  output_file = open(output_file, 'wb')
-  output_file.write(trace_file.SerializeToString())
-  output_file.close()
-
-  print("DONE")
-
-  # TODO: Silent running mode [no output except on error] for build runs.
-
-  return 0
-
-def main(argv):
-  parser = optparse.OptionParser(usage="Usage: %prog [options]", description="Compile systrace file into TraceFile.pb")
-  parser.add_option('-i', dest='inode_data_file', metavar='FILE',
-                    help='Read cached inode data from a file saved earlier with pagecache.py -d')
-  parser.add_option('-t', dest='trace_file', metavar='FILE',
-                    help='Path to systrace file (trace.html) that will be parsed')
-  parser.add_option('--perfetto-trace', dest='perfetto_trace_file',
-                    metavar='FILE',
-                    help='Path to perfetto trace that will be parsed')
-
-  parser.add_option('--db', dest='sql_db', metavar='FILE',
-                    help='Path to intermediate sqlite3 database [default: in-memory].')
-
-  parser.add_option('-f', dest='filter', action="append", default=[],
-                    help="Add file filter. All file entries not matching one of the filters are discarded.")
-
-  parser.add_option('-l', dest='launch_lock', action="store_true", default=False,
-                    help="Exclude all events not inside launch_lock")
-
-  parser.add_option('-o', dest='output_file', metavar='FILE',
-                    help='Output protobuf file')
-
-  parser.add_option('--duration', dest='trace_duration', action="store",
-                    type=int, help='The duration of trace in milliseconds.')
-
-  options, categories = parser.parse_args(argv[1:])
-
-  # TODO: OptionParser should have some flags to make these mandatory.
-  if not options.inode_data_file:
-    parser.error("-i is required")
-  if not options.trace_file and not options.perfetto_trace_file:
-    parser.error("one of -t or --perfetto-trace is required")
-  if options.trace_file and options.perfetto_trace_file:
-    parser.error("please enter either -t or --perfetto-trace, not both")
-  if not options.output_file:
-    parser.error("-o is required")
-
-  if options.launch_lock:
-    print("INFO: Launch lock flag (-l) enabled; filtering all events not inside launch_lock.")
-
-  inode_table = Inode2Filename.new_from_filename(options.inode_data_file)
-
-  sql_db_path = ":memory:"
-  if options.sql_db:
-    sql_db_path = options.sql_db
-
-  trace_duration = timedelta(milliseconds=options.trace_duration) if \
-    options.trace_duration is not None else None
-
-  # if the input is systrace
-  if options.trace_file:
-    return run(sql_db_path,
-               options.trace_file,
-               trace_duration,
-               options.output_file,
-               inode_table,
-               options.filter)
-
-  # if the input is perfetto trace
-  # TODO python 3.7 switch to using nullcontext
-  with tempfile.NamedTemporaryFile() as trace_file:
-    transform_perfetto_trace_to_systrace(options.perfetto_trace_file,
-                                         trace_file.name)
-    return run(sql_db_path,
-               trace_file.name,
-               trace_duration,
-               options.output_file,
-               inode_table,
-               options.filter)
-
-if __name__ == '__main__':
-  print(sys.argv)
-  sys.exit(main(sys.argv))
diff --git a/startop/scripts/iorap/compiler_test.py b/startop/scripts/iorap/compiler_test.py
deleted file mode 100644
index b8de701..0000000
--- a/startop/scripts/iorap/compiler_test.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for the compiler.py script.
-
-Install:
-  $> sudo apt-get install python3-pytest   ##  OR
-  $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
-  $> pytest compiler_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-import os
-
-import compiler_ri as compiler
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-TEXTCACHE = os.path.join(DIR, 'test_fixtures/compiler/common_textcache')
-SYSTRACE = os.path.join(DIR, 'test_fixtures/compiler/common_systrace')
-ARGV = [os.path.join(DIR, 'compiler.py'), '-i', TEXTCACHE, '-t', SYSTRACE]
-PERFETTO_TRACE = os.path.join(DIR,
-                              'test_fixtures/compiler/common_perfetto_trace.pb')
-
-def assert_compile_result(output, expected, *extra_argv):
-  argv = ARGV + ['-o', output] + [args for args in extra_argv]
-
-  compiler.main(argv)
-
-  with open(output, 'rb') as f1, open(expected, 'rb') as f2:
-    assert f1.read() == f2.read()
-
-### Unit tests - testing compiler code directly
-def test_transform_perfetto_trace_to_systrace(tmpdir):
-  expected = os.path.join(DIR,
-                          'test_fixtures/compiler/test_result_systrace')
-  output = tmpdir.mkdir('compiler').join('tmp_systrace')
-
-  compiler.transform_perfetto_trace_to_systrace(PERFETTO_TRACE, str(output))
-
-  with open(output, 'rb') as f1, open(expected, 'rb') as f2:
-    assert f1.read() == f2.read()
-
-### Functional tests - calls 'compiler.py --args...'
-def test_compiler_main(tmpdir):
-  output = tmpdir.mkdir('compiler').join('output')
-
-  # No duration
-  expected = os.path.join(DIR,
-                          'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
-  assert_compile_result(output, expected)
-
-  # 10ms duration
-  expected = os.path.join(DIR,
-                          'test_fixtures/compiler/test_result_with_duration.TraceFile.pb')
-  assert_compile_result(output, expected, '--duration', '10000')
-
-  # 30ms duration
-  expected = os.path.join(DIR,
-                          'test_fixtures/compiler/test_result_without_duration.TraceFile.pb')
-  assert_compile_result(output, expected, '--duration', '30000')
diff --git a/startop/scripts/iorap/dump_compiled_pb b/startop/scripts/iorap/dump_compiled_pb
deleted file mode 100755
index ad26a7d..0000000
--- a/startop/scripts/iorap/dump_compiled_pb
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-#
-# Dumps an iorap compiler protobuf from iorap.cmd.compiler into text
-# with gqui.
-#
-
-if [[ "$#" -lt 1 ]]; then
-  echo "Usage: $0 <compiler_trace_file.pb> [...args]" >&2
-  exit 1
-fi
-
-path_to_proto="$DIR/../../../../../system/iorap/src/serialize/TraceFile.proto"
-
-filename="$1"
-shift
-if ! [[ -f $filename ]]; then
-  echo "Error: $filename does not exist." >&2
-  exit 1
-fi
-
-gqui "rawproto:$filename" proto "$path_to_proto":iorap.serialize.proto.TraceFile "$@"
diff --git a/startop/scripts/iorap/dump_trace_pb b/startop/scripts/iorap/dump_trace_pb
deleted file mode 100755
index bcec4a5..0000000
--- a/startop/scripts/iorap/dump_trace_pb
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-#
-# Dumps a perfetto protobuf collected by iorapd (from perfetto) into text
-# with gqui.
-#
-
-if [[ "$#" -lt 1 ]]; then
-  echo "Usage: $0 <perfetto_trace.pb> [...args]" >&2
-  exit 1
-fi
-
-path_to_perfetto_proto="$DIR/../../../../../external/perfetto/protos/perfetto/trace/perfetto_trace.proto"
-
-filename="$1"
-shift
-if ! [[ -f $filename ]]; then
-  echo "Error: $filename does not exist." >&2
-  exit 1
-fi
-
-gqui "rawproto:$filename" proto "$path_to_perfetto_proto":perfetto.protos.Trace "$@"
diff --git a/startop/scripts/iorap/generated/TraceFile_pb2.py b/startop/scripts/iorap/generated/TraceFile_pb2.py
deleted file mode 100644
index f005bed..0000000
--- a/startop/scripts/iorap/generated/TraceFile_pb2.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: TraceFile.proto
-
-import sys
-_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
-from google.protobuf import descriptor as _descriptor
-from google.protobuf import message as _message
-from google.protobuf import reflection as _reflection
-from google.protobuf import symbol_database as _symbol_database
-from google.protobuf import descriptor_pb2
-# @@protoc_insertion_point(imports)
-
-_sym_db = _symbol_database.Default()
-
-
-
-
-DESCRIPTOR = _descriptor.FileDescriptor(
-  name='TraceFile.proto',
-  package='iorap.serialize.proto',
-  syntax='proto2',
-  serialized_pb=_b('\n\x0fTraceFile.proto\x12\x15iorap.serialize.proto\"u\n\tTraceFile\x12\x34\n\x05index\x18\x01 \x02(\x0b\x32%.iorap.serialize.proto.TraceFileIndex\x12\x32\n\x04list\x18\x02 \x02(\x0b\x32$.iorap.serialize.proto.TraceFileList\"M\n\x0eTraceFileIndex\x12;\n\x07\x65ntries\x18\x01 \x03(\x0b\x32*.iorap.serialize.proto.TraceFileIndexEntry\"4\n\x13TraceFileIndexEntry\x12\n\n\x02id\x18\x01 \x02(\x03\x12\x11\n\tfile_name\x18\x02 \x02(\t\"G\n\rTraceFileList\x12\x36\n\x07\x65ntries\x18\x01 \x03(\x0b\x32%.iorap.serialize.proto.TraceFileEntry\"L\n\x0eTraceFileEntry\x12\x10\n\x08index_id\x18\x01 \x02(\x03\x12\x13\n\x0b\x66ile_offset\x18\x02 \x02(\x03\x12\x13\n\x0b\x66ile_length\x18\x03 \x02(\x03\x42\x1c\n\x18\x63om.google.android.iorapH\x03')
-)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
-
-
-
-
-_TRACEFILE = _descriptor.Descriptor(
-  name='TraceFile',
-  full_name='iorap.serialize.proto.TraceFile',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='index', full_name='iorap.serialize.proto.TraceFile.index', index=0,
-      number=1, type=11, cpp_type=10, label=2,
-      has_default_value=False, default_value=None,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='list', full_name='iorap.serialize.proto.TraceFile.list', index=1,
-      number=2, type=11, cpp_type=10, label=2,
-      has_default_value=False, default_value=None,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  syntax='proto2',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=42,
-  serialized_end=159,
-)
-
-
-_TRACEFILEINDEX = _descriptor.Descriptor(
-  name='TraceFileIndex',
-  full_name='iorap.serialize.proto.TraceFileIndex',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='entries', full_name='iorap.serialize.proto.TraceFileIndex.entries', index=0,
-      number=1, type=11, cpp_type=10, label=3,
-      has_default_value=False, default_value=[],
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  syntax='proto2',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=161,
-  serialized_end=238,
-)
-
-
-_TRACEFILEINDEXENTRY = _descriptor.Descriptor(
-  name='TraceFileIndexEntry',
-  full_name='iorap.serialize.proto.TraceFileIndexEntry',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='id', full_name='iorap.serialize.proto.TraceFileIndexEntry.id', index=0,
-      number=1, type=3, cpp_type=2, label=2,
-      has_default_value=False, default_value=0,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='file_name', full_name='iorap.serialize.proto.TraceFileIndexEntry.file_name', index=1,
-      number=2, type=9, cpp_type=9, label=2,
-      has_default_value=False, default_value=_b("").decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  syntax='proto2',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=240,
-  serialized_end=292,
-)
-
-
-_TRACEFILELIST = _descriptor.Descriptor(
-  name='TraceFileList',
-  full_name='iorap.serialize.proto.TraceFileList',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='entries', full_name='iorap.serialize.proto.TraceFileList.entries', index=0,
-      number=1, type=11, cpp_type=10, label=3,
-      has_default_value=False, default_value=[],
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  syntax='proto2',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=294,
-  serialized_end=365,
-)
-
-
-_TRACEFILEENTRY = _descriptor.Descriptor(
-  name='TraceFileEntry',
-  full_name='iorap.serialize.proto.TraceFileEntry',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='index_id', full_name='iorap.serialize.proto.TraceFileEntry.index_id', index=0,
-      number=1, type=3, cpp_type=2, label=2,
-      has_default_value=False, default_value=0,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='file_offset', full_name='iorap.serialize.proto.TraceFileEntry.file_offset', index=1,
-      number=2, type=3, cpp_type=2, label=2,
-      has_default_value=False, default_value=0,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-    _descriptor.FieldDescriptor(
-      name='file_length', full_name='iorap.serialize.proto.TraceFileEntry.file_length', index=2,
-      number=3, type=3, cpp_type=2, label=2,
-      has_default_value=False, default_value=0,
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      options=None),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  options=None,
-  is_extendable=False,
-  syntax='proto2',
-  extension_ranges=[],
-  oneofs=[
-  ],
-  serialized_start=367,
-  serialized_end=443,
-)
-
-_TRACEFILE.fields_by_name['index'].message_type = _TRACEFILEINDEX
-_TRACEFILE.fields_by_name['list'].message_type = _TRACEFILELIST
-_TRACEFILEINDEX.fields_by_name['entries'].message_type = _TRACEFILEINDEXENTRY
-_TRACEFILELIST.fields_by_name['entries'].message_type = _TRACEFILEENTRY
-DESCRIPTOR.message_types_by_name['TraceFile'] = _TRACEFILE
-DESCRIPTOR.message_types_by_name['TraceFileIndex'] = _TRACEFILEINDEX
-DESCRIPTOR.message_types_by_name['TraceFileIndexEntry'] = _TRACEFILEINDEXENTRY
-DESCRIPTOR.message_types_by_name['TraceFileList'] = _TRACEFILELIST
-DESCRIPTOR.message_types_by_name['TraceFileEntry'] = _TRACEFILEENTRY
-
-TraceFile = _reflection.GeneratedProtocolMessageType('TraceFile', (_message.Message,), dict(
-  DESCRIPTOR = _TRACEFILE,
-  __module__ = 'TraceFile_pb2'
-  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFile)
-  ))
-_sym_db.RegisterMessage(TraceFile)
-
-TraceFileIndex = _reflection.GeneratedProtocolMessageType('TraceFileIndex', (_message.Message,), dict(
-  DESCRIPTOR = _TRACEFILEINDEX,
-  __module__ = 'TraceFile_pb2'
-  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndex)
-  ))
-_sym_db.RegisterMessage(TraceFileIndex)
-
-TraceFileIndexEntry = _reflection.GeneratedProtocolMessageType('TraceFileIndexEntry', (_message.Message,), dict(
-  DESCRIPTOR = _TRACEFILEINDEXENTRY,
-  __module__ = 'TraceFile_pb2'
-  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileIndexEntry)
-  ))
-_sym_db.RegisterMessage(TraceFileIndexEntry)
-
-TraceFileList = _reflection.GeneratedProtocolMessageType('TraceFileList', (_message.Message,), dict(
-  DESCRIPTOR = _TRACEFILELIST,
-  __module__ = 'TraceFile_pb2'
-  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileList)
-  ))
-_sym_db.RegisterMessage(TraceFileList)
-
-TraceFileEntry = _reflection.GeneratedProtocolMessageType('TraceFileEntry', (_message.Message,), dict(
-  DESCRIPTOR = _TRACEFILEENTRY,
-  __module__ = 'TraceFile_pb2'
-  # @@protoc_insertion_point(class_scope:iorap.serialize.proto.TraceFileEntry)
-  ))
-_sym_db.RegisterMessage(TraceFileEntry)
-
-
-DESCRIPTOR.has_options = True
-DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\030com.google.android.iorapH\003'))
-# @@protoc_insertion_point(module_scope)
diff --git a/startop/scripts/iorap/generated/codegen_protos b/startop/scripts/iorap/generated/codegen_protos
deleted file mode 100755
index 5688711..0000000
--- a/startop/scripts/iorap/generated/codegen_protos
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-APROTOC="$(which aprotoc)"
-
-IORAP_SERIALIZE_DIR="${DIR}/../../../../../../system/iorap/src/serialize"
-IORAP_PROTOS=($IORAP_SERIALIZE_DIR/*.proto)
-
-if [[ $? -ne 0 ]]; then
-  echo "Fatal: Missing aprotoc. Set APROTOC=... or lunch build/envsetup.sh?" >&2
-  exit 1
-fi
-
-if ! [[ -d $IORAP_SERIALIZE_DIR ]]; then
-  echo "Fatal: Directory '$IORAP_SERIALIZE_DIR' does not exist." >&2
-  exit 1
-fi
-
-# codegen the .py files into the same directory as this script.
-echo "$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}"
-"$APROTOC" --proto_path="$IORAP_SERIALIZE_DIR" --python_out="$DIR" "${IORAP_PROTOS[@]}"
diff --git a/startop/scripts/iorap/lib/inode2filename.py b/startop/scripts/iorap/lib/inode2filename.py
deleted file mode 100644
index 2e71393..0000000
--- a/startop/scripts/iorap/lib/inode2filename.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python3
-
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union, TextIO
-
-import re
-
-class Inode2Filename:
-  """
-  Parses a text file of the format
-     "uint(dev_t) uint(ino_t) int(file_size) string(filepath)\\n"*
-
-  Lines not matching this format are ignored.
-  """
-
-  def __init__(self, inode_data_file: TextIO):
-    """
-    Create an Inode2Filename that reads cached inode from a file saved earlier
-    (e.g. with pagecache.py -d or with inode2filename --format=textcache)
-
-    :param inode_data_file: a file object (e.g. created with open or StringIO).
-
-    Lifetime: inode_data_file is only used during the construction of the object.
-    """
-    self._inode_table = Inode2Filename.build_inode_lookup_table(inode_data_file)
-
-  @classmethod
-  def new_from_filename(cls, textcache_filename: str) -> 'Inode2Filename':
-    """
-    Create an Inode2Filename that reads cached inode from a file saved earlier
-    (e.g. with pagecache.py -d or with inode2filename --format=textcache)
-
-    :param textcache_filename: path to textcache
-    """
-    with open(textcache_filename) as inode_data_file:
-      return cls(inode_data_file)
-
-  @staticmethod
-  def build_inode_lookup_table(inode_data_file: TextIO) -> Dict[Tuple[int, int], Tuple[str, str]]:
-    """
-    :return: map { (device_int, inode_int) -> (filename_str, size_str) }
-    """
-    inode2filename = {}
-    for line in inode_data_file:
-      # stat -c "%d %i %s %n
-      # device number, inode number, total size in bytes, file name
-      result = re.match('([0-9]+)d? ([0-9]+) -?([0-9]+) (.*)', line)
-      if result:
-        inode2filename[(int(result.group(1)), int(result.group(2)))] = \
-            (result.group(4), result.group(3))
-
-    return inode2filename
-
-  def resolve(self, dev_t: int, ino_t: int) -> Optional[str]:
-    """
-    Return a filename (str) from a (dev_t, ino_t) inode pair.
-
-    Returns None if the lookup fails.
-    """
-    maybe_result = self._inode_table.get((dev_t, ino_t))
-
-    if not maybe_result:
-      return None
-
-    return maybe_result[0] # filename str
-
-  def __len__(self) -> int:
-    """
-    :return: the number of inode entries parsed from the file.
-    """
-    return len(self._inode_table)
-
-  def __repr__(self) -> str:
-    """
-    :return: string representation for debugging/test failures.
-    """
-    return "Inode2Filename%s" %(repr(self._inode_table))
-
-  # end of class.
diff --git a/startop/scripts/iorap/lib/inode2filename_test.py b/startop/scripts/iorap/lib/inode2filename_test.py
deleted file mode 100755
index 1224c61..0000000
--- a/startop/scripts/iorap/lib/inode2filename_test.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for inode2filename module.
-
-Install:
-  $> sudo apt-get install python3-pytest   ##  OR
-  $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
-  $> ./inode2filename_test.py
-  $> pytest inode2filename_test.py
-  $> python -m pytest inode2filename_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-from contextlib import contextmanager
-import io
-import shlex
-import sys
-import typing
-
-# pip imports
-import pytest
-
-# local imports
-from inode2filename import *
-
-def create_inode2filename(*contents):
-  buf = io.StringIO()
-
-  for c in contents:
-    buf.write(c)
-    buf.write("\n")
-
-  buf.seek(0)
-
-  i2f = Inode2Filename(buf)
-
-  buf.close()
-
-  return i2f
-
-def test_inode2filename():
-  a = create_inode2filename("")
-  assert len(a) == 0
-  assert a.resolve(1, 2) == None
-
-  a = create_inode2filename("1 2 3 foo.bar")
-  assert len(a) == 1
-  assert a.resolve(1, 2) == "foo.bar"
-  assert a.resolve(4, 5) == None
-
-  a = create_inode2filename("1 2 3 foo.bar", "4 5 6 bar.baz")
-  assert len(a) == 2
-  assert a.resolve(1, 2) == "foo.bar"
-  assert a.resolve(4, 5) == "bar.baz"
-
-  a = create_inode2filename("1567d 8910 -1 /a/b/c/", "4 5 6 bar.baz")
-  assert len(a) == 2
-  assert a.resolve(1567, 8910) == "/a/b/c/"
-  assert a.resolve(4, 5) == "bar.baz"
-
-if __name__ == '__main__':
-  pytest.main()
diff --git a/startop/scripts/iorap/lib/iorapd_utils.py b/startop/scripts/iorap/lib/iorapd_utils.py
deleted file mode 100644
index f6f21fd..0000000
--- a/startop/scripts/iorap/lib/iorapd_utils.py
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Helper util libraries for iorapd related operations."""
-
-import os
-import sys
-
-# up to two level
-sys.path.append(os.path.join(os.path.abspath(__file__),'../..'))
-import lib.cmd_utils as cmd_utils
-
-IORAPID_LIB_DIR = os.path.abspath(os.path.dirname(__file__))
-IORAPD_DATA_PATH = '/data/misc/iorapd'
-IORAP_COMMON_BASH_SCRIPT = os.path.realpath(os.path.join(IORAPID_LIB_DIR,
-                                                         '../common'))
-
-def _iorapd_path_to_data_file(package: str, activity: str, suffix: str) -> str:
-  """Gets conventional data filename.
-
-   Returns:
-     The path of iorapd data file.
-
-  """
-  # Match logic of 'AppComponentName' in iorap::compiler C++ code.
-  return '{}/{}%2F{}.{}'.format(IORAPD_DATA_PATH, package, activity, suffix)
-
-def compile_perfetto_trace_on_device(package: str, activity: str,
-                                     inodes: str) -> bool:
-  """Compiles the perfetto trace using on-device compiler."""
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_compiler_for_app_trace',
-                                       [package, activity, inodes])
-  return passed
-
-def get_iorapd_compiler_trace(package: str, activity: str, dest: str) -> str:
-  """Gets compiler trace to dest file."""
-  src = _iorapd_path_to_data_file(package, activity, 'compiled_trace.pb')
-  passed, _ = cmd_utils.run_shell_command('adb pull "{}" "{}"'.format(src, dest))
-  if not passed:
-    return False
-  return True
-
-def iorapd_compiler_install_trace_file(package: str, activity: str,
-                                       input_file: str) -> bool:
-  """Installs a compiled trace file.
-
-  Returns:
-    Whether the trace file is installed successful or not.
-  """
-  # remote path calculations
-  compiled_path = _iorapd_path_to_data_file(package, activity,
-                                            'compiled_trace.pb')
-
-  if not os.path.exists(input_file):
-    print('Error: File {} does not exist'.format(input_file))
-    return False
-
-  passed, _ = cmd_utils.run_adb_shell_command(
-    'mkdir -p "$(dirname "{}")"'.format(compiled_path))
-  if not passed:
-    return False
-
-  passed, _ = cmd_utils.run_shell_command('adb push "{}" "{}"'.format(
-    input_file, compiled_path))
-
-  return passed
-
-def wait_for_iorapd_finish(package: str,
-                           activity: str,
-                           timeout: int,
-                           debug: bool,
-                           logcat_timestamp: str)->bool:
-  """Waits for the finish of iorapd.
-
-  Returns:
-    A bool indicates whether the iorapd is done successfully or not.
-  """
-  # Set verbose for bash script based on debug flag.
-  if debug:
-    os.putenv('verbose', 'y')
-
-  # Validate that readahead completes.
-  # If this fails for some reason, then this will also discard the timing of
-  # the run.
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_readahead_wait_until_finished',
-                                       [package, activity, logcat_timestamp,
-                                        str(timeout)])
-  return passed
-
-
-def enable_iorapd_readahead() -> bool:
-  """
-  Disable readahead. Subsequent launches of an application will be sped up
-  by iorapd readahead prefetching.
-
-  Returns:
-    A bool indicates whether the enabling is done successfully or not.
-  """
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_readahead_enable', [])
-  return passed
-
-def disable_iorapd_readahead() -> bool:
-  """
-  Disable readahead. Subsequent launches of an application will be not be sped
-  up by iorapd readahead prefetching.
-
-  Returns:
-    A bool indicates whether the disabling is done successfully or not.
-  """
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_readahead_disable', [])
-  return passed
-
-def enable_iorapd_perfetto() -> bool:
-  """
-  Enable Perfetto. Subsequent launches of an application will record a perfetto
-  trace protobuf.
-
-  Returns:
-    A bool indicates whether the enabling is done successfully or not.
-  """
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_perfetto_enable', [])
-  return passed
-
-def disable_iorapd_perfetto() -> bool:
-  """
-  Disable Perfetto. Subsequent launches of applications will no longer record
-  perfetto trace protobufs.
-
-  Returns:
-    A bool indicates whether the disabling is done successfully or not.
-  """
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_perfetto_disable', [])
-  return passed
-
-def start_iorapd() -> bool:
-  """
-  Starts iorapd.
-
-  Returns:
-    A bool indicates whether the starting is done successfully or not.
-  """
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_start', [])
-  return passed
-
-def stop_iorapd() -> bool:
-  """
-  Stops iorapd.
-
-  Returns:
-    A bool indicates whether the stopping is done successfully or not.
-  """
-  passed, _ = cmd_utils.run_shell_func(IORAP_COMMON_BASH_SCRIPT,
-                                       'iorapd_stop', [])
-  return passed
-
diff --git a/startop/scripts/iorap/pull_textcache b/startop/scripts/iorap/pull_textcache
deleted file mode 100755
index 0554426..0000000
--- a/startop/scripts/iorap/pull_textcache
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-if [[ $# -lt 1 ]]; then
-  echo "Usage: $0 <output-filename>" >&2
-  exit 1
-fi
-
-# see compiler/main.cc for list of roots
-adb shell iorap.inode2filename --output-format=textcache --output=/data/local/tmp/dumpcache --all --root=/system --root=/apex --root=/vendor --root=/data --root=/product --root=/metadata
-adb pull /data/local/tmp/dumpcache "$1"
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb b/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb
deleted file mode 100644
index a47ad3d..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb
+++ /dev/null
Binary files differ
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_systrace b/startop/scripts/iorap/test_fixtures/compiler/common_systrace
deleted file mode 100644
index 4573738..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/common_systrace
+++ /dev/null
@@ -1,5 +0,0 @@
-<...>-2965  (-----) [001] .... 10000.746629: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000679ee1ec pfn=1299913 ofs=192512
-<...>-2965  (-----) [001] .... 10010.746664: mm_filemap_add_to_page_cache: dev 253:6 ino 2 page=0000000006cd2fb7 pfn=1296251 ofs=196608
-<...>-2965  (-----) [001] .... 10020.746677: mm_filemap_add_to_page_cache: dev 253:6 ino 3 page=00000000af82f3d6 pfn=1419330 ofs=200704
-<...>-2965  (-----) [001] .... 10030.746693: mm_filemap_add_to_page_cache: dev 253:6 ino 4 page=000000002840f054 pfn=1304928 ofs=204800
-<...>-2965  (-----) [001] .... 10040.746706: mm_filemap_add_to_page_cache: dev 253:6 ino 5 page=000000004a59da17 pfn=1288069 ofs=208896
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_textcache b/startop/scripts/iorap/test_fixtures/compiler/common_textcache
deleted file mode 100644
index da03004..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/common_textcache
+++ /dev/null
@@ -1,2 +0,0 @@
-64774 1 -1 /system/test1
-64774 3 -1 /data/test2
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace b/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace
deleted file mode 100644
index 59ff753..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace
+++ /dev/null
@@ -1,748 +0,0 @@
-TRACE:
-# tracer: nop
-#
-# entries-in-buffer/entries-written: 30624/30624   #P:4
-#
-#                                      _-----=> irqs-off
-#                                     / _----=> need-resched
-#                                    | / _---=> hardirq/softirq
-#                                    || / _--=> preempt-depth
-#                                    ||| /     delay
-#           TASK-PID    TGID   CPU#  ||||    TIMESTAMP  FUNCTION
-#              | |        |      |   ||||       |         |
-       <unknown>-27388 (-----) [004] .... 1920260.530929: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1461937 ofs=9535488
-       <unknown>-27388 (-----) [005] .... 1920260.532161: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1344589 ofs=9474048
-       <unknown>-27388 (-----) [005] .... 1920260.532183: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1153671 ofs=9478144
-       <unknown>-27388 (-----) [005] .... 1920260.532184: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1219563 ofs=9482240
-       <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1083162 ofs=9486336
-       <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1147318 ofs=9490432
-       <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1333594 ofs=9494528
-       <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1375715 ofs=9498624
-       <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1184831 ofs=9502720
-       <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1241653 ofs=9506816
-       <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1134975 ofs=9510912
-       <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1145772 ofs=9515008
-       <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1090457 ofs=9519104
-       <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1137942 ofs=9523200
-       <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1130123 ofs=9527296
-       <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1208783 ofs=9531392
-       <unknown>-27388 (-----) [005] .... 1920260.532192: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1294989 ofs=9539584
-       <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1163979 ofs=9543680
-       <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1350628 ofs=9547776
-       <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1386717 ofs=9551872
-       <unknown>-27388 (-----) [005] .... 1920260.532207: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1316148 ofs=9555968
-       <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1316419 ofs=9560064
-       <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1149076 ofs=9564160
-       <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1372772 ofs=9568256
-       <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1116389 ofs=9572352
-       <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1325458 ofs=9576448
-       <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1195423 ofs=9580544
-       <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1250964 ofs=9584640
-       <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1196027 ofs=9588736
-       <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1354059 ofs=9592832
-       <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1264649 ofs=9596928
-       <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1245285 ofs=9601024
-       <unknown>-27388 (-----) [005] .... 1920260.535119: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1411552 ofs=44244992
-       <unknown>-27388 (-----) [005] .... 1920260.535129: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1483081 ofs=433524736
-       <unknown>-27388 (-----) [004] .... 1920260.536144: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1276173 ofs=438185984
-       <unknown>-27388 (-----) [004] .... 1920260.536462: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1174575 ofs=44249088
-       <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1126294 ofs=44253184
-       <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1248232 ofs=44257280
-       <unknown>-27388 (-----) [004] .... 1920260.537065: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1332993 ofs=44240896
-       <unknown>-27388 (-----) [006] .... 1920260.537646: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1153343 ofs=44400640
-       <unknown>-27388 (-----) [005] .... 1920260.538777: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1358397 ofs=44474368
-       <unknown>-12683 (-----) [006] .... 1920260.560094: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1426577 ofs=0
-       <unknown>-12683 (-----) [006] .... 1920260.560105: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117587 ofs=1171456
-       <unknown>-12683 (-----) [006] .... 1920260.561199: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099987 ofs=4096
-       <unknown>-12683 (-----) [006] .... 1920260.561411: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099910 ofs=16384
-       <unknown>-12683 (-----) [006] .... 1920260.561598: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099905 ofs=20480
-       <unknown>-12683 (-----) [006] .... 1920260.561758: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099883 ofs=32768
-       <unknown>-12683 (-----) [006] .... 1920260.562088: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099809 ofs=36864
-       <unknown>-12683 (-----) [006] .... 1920260.562325: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099803 ofs=98304
-       <unknown>-12683 (-----) [006] .... 1920260.562516: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099795 ofs=102400
-       <unknown>-12683 (-----) [006] .... 1920260.563094: mm_filemap_add_to_page_cache: dev 0:64768 ino 5f3 page=0000000000000000 pfn=1107649 ofs=12288
-       <unknown>-12683 (-----) [006] .... 1920260.563105: mm_filemap_add_to_page_cache: dev 0:64768 ino 5f3 page=0000000000000000 pfn=1269029 ofs=16384
-       <unknown>-12683 (-----) [006] .... 1920260.563785: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1451096 ofs=8192
-       <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1301480 ofs=12288
-       <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1314353 ofs=16384
-       <unknown>-12683 (-----) [006] .... 1920260.563791: mm_filemap_add_to_page_cache: dev 0:64768 ino 4da page=0000000000000000 pfn=1216744 ofs=24576
-       <unknown>-12683 (-----) [006] .... 1920260.564309: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099787 ofs=49152
-       <unknown>-12683 (-----) [006] .... 1920260.564514: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1099778 ofs=53248
-       <unknown>-12683 (-----) [005] .... 1920260.564756: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1148849 ofs=114688
-       <unknown>-12683 (-----) [005] .... 1920260.564973: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1164731 ofs=118784
-       <unknown>-12683 (-----) [005] .... 1920260.565000: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1170255 ofs=0
-       <unknown>-12683 (-----) [005] .... 1920260.565003: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1181043 ofs=4096
-       <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1296004 ofs=8192
-       <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 1a page=0000000000000000 pfn=1102004 ofs=12288
-       <unknown>-12683 (-----) [005] .... 1920260.565626: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1351232 ofs=470597632
-       <unknown>-12683 (-----) [005] .... 1920260.565982: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1391336 ofs=40210432
-       <unknown>-12683 (-----) [005] .... 1920260.565985: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267536 ofs=12668928
-       <unknown>-27388 (-----) [007] .... 1920260.566082: mm_filemap_add_to_page_cache: dev 0:64768 ino 588 page=0000000000000000 pfn=1256752 ofs=43921408
-       <unknown>-12683 (-----) [005] .... 1920260.566516: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1110966 ofs=176226304
-       <unknown>-12683 (-----) [005] .... 1920260.566519: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1060586 ofs=12967936
-       <unknown>-12683 (-----) [004] .... 1920260.567773: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117234 ofs=421888
-       <unknown>-12683 (-----) [005] .... 1920260.568604: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1210571 ofs=430080
-       <unknown>-12683 (-----) [005] .... 1920260.568887: mm_filemap_add_to_page_cache: dev 0:64771 ino 69 page=0000000000000000 pfn=1055640 ofs=0
-       <unknown>-12683 (-----) [005] .... 1920260.568908: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1142694 ofs=0
-       <unknown>-12683 (-----) [005] .... 1920260.568910: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1060788 ofs=299008
-       <unknown>-12683 (-----) [005] .... 1920260.569418: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1085046 ofs=4096
-       <unknown>-12683 (-----) [005] .... 1920260.569640: mm_filemap_add_to_page_cache: dev 0:64771 ino 49 page=0000000000000000 pfn=1057135 ofs=8192
-       <unknown>-12683 (-----) [005] .... 1920260.569833: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1058976 ofs=19406848
-       <unknown>-12683 (-----) [005] .... 1920260.569835: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1477947 ofs=10526720
-       <unknown>-12683 (-----) [005] .... 1920260.572285: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1237492 ofs=299008
-       <unknown>-12683 (-----) [005] .... 1920260.572297: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1264914 ofs=339968
-       <unknown>-12683 (-----) [005] .... 1920260.572314: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1434748 ofs=348160
-       <unknown>-12683 (-----) [005] .... 1920260.572316: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1372959 ofs=352256
-       <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1258955 ofs=356352
-       <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1113420 ofs=360448
-       <unknown>-12683 (-----) [005] .... 1920260.572318: mm_filemap_add_to_page_cache: dev 0:64768 ino 61d page=0000000000000000 pfn=1137083 ofs=364544
-       <unknown>-12683 (-----) [004] .... 1920260.575490: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1379679 ofs=65536
-       <unknown>-12683 (-----) [006] .... 1920260.576194: mm_filemap_add_to_page_cache: dev 0:64771 ino 11e page=0000000000000000 pfn=1323898 ofs=69632
-       <unknown>-12683 (-----) [006] .... 1920260.576248: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323895 ofs=262623232
-       <unknown>-12683 (-----) [006] .... 1920260.576251: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323861 ofs=13156352
-       <unknown>-12683 (-----) [005] .... 1920260.576810: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1477585 ofs=262590464
-       <unknown>-12683 (-----) [004] .... 1920260.577197: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1267617 ofs=25206784
-       <unknown>-12683 (-----) [004] .... 1920260.577200: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267618 ofs=12636160
-       <unknown>-12683 (-----) [005] .... 1920260.577725: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1056225 ofs=228618240
-       <unknown>-12683 (-----) [005] .... 1920260.577727: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1164942 ofs=13082624
-       <unknown>-12683 (-----) [007] .... 1920260.578411: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1372616 ofs=0
-       <unknown>-12683 (-----) [007] .... 1920260.578422: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1307468 ofs=4096
-       <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1120117 ofs=8192
-       <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1217989 ofs=12288
-       <unknown>-12683 (-----) [007] .... 1920260.578650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1475011 ofs=5419008
-       <unknown>-12683 (-----) [007] .... 1920260.578653: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1066084 ofs=236453888
-       <unknown>-12683 (-----) [007] .... 1920260.578654: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1100271 ofs=13099008
-       <unknown>-12683 (-----) [004] .... 1920260.579004: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1485156 ofs=5423104
-       <unknown>-12683 (-----) [004] .... 1920260.579005: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1124212 ofs=5427200
-       <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1195377 ofs=5431296
-       <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1265888 ofs=5435392
-       <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1170194 ofs=5439488
-       <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1403742 ofs=5443584
-       <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1123826 ofs=5447680
-       <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1255034 ofs=5451776
-       <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1190447 ofs=5455872
-       <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1286864 ofs=5459968
-       <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1428535 ofs=5464064
-       <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1184092 ofs=5468160
-       <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1411906 ofs=5472256
-       <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1342349 ofs=5476352
-       <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1188185 ofs=5480448
-       <unknown>-12683 (-----) [004] .... 1920260.579014: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1158702 ofs=5484544
-       <unknown>-12683 (-----) [005] .... 1920260.579430: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1299421 ofs=5230592
-       <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1317097 ofs=5234688
-       <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1441714 ofs=5238784
-       <unknown>-12683 (-----) [005] .... 1920260.579438: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1081974 ofs=5242880
-       <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1128684 ofs=5246976
-       <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447381 ofs=5251072
-       <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1466410 ofs=5255168
-       <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1259909 ofs=5259264
-       <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1125784 ofs=5263360
-       <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1270592 ofs=5267456
-       <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246070 ofs=5271552
-       <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1472544 ofs=5275648
-       <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1113357 ofs=5279744
-       <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1202021 ofs=5283840
-       <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078639 ofs=5287936
-       <unknown>-12683 (-----) [005] .... 1920260.579449: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1176171 ofs=5292032
-       <unknown>-12683 (-----) [005] .... 1920260.579450: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1089516 ofs=5296128
-       <unknown>-12683 (-----) [005] .... 1920260.579451: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1400065 ofs=5300224
-       <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1300489 ofs=5304320
-       <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1452081 ofs=5308416
-       <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1161862 ofs=5312512
-       <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1161871 ofs=5316608
-       <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1263798 ofs=5320704
-       <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1126887 ofs=5324800
-       <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1375498 ofs=5328896
-       <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1328067 ofs=5332992
-       <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1420691 ofs=5337088
-       <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1298707 ofs=5341184
-       <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078670 ofs=5345280
-       <unknown>-12683 (-----) [005] .... 1920260.579457: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1430498 ofs=5349376
-       <unknown>-12683 (-----) [005] .... 1920260.579458: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1338720 ofs=5353472
-       <unknown>-12683 (-----) [005] .... 1920260.579476: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1452611 ofs=5357568
-       <unknown>-12683 (-----) [006] .... 1920260.580451: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241967 ofs=0
-       <unknown>-12683 (-----) [006] .... 1920260.580454: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1116541 ofs=4096
-       <unknown>-12683 (-----) [006] .... 1920260.580461: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1145049 ofs=8192
-       <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1277255 ofs=12288
-       <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1098037 ofs=16384
-       <unknown>-12683 (-----) [006] .... 1920260.580463: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1135986 ofs=20480
-       <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1154455 ofs=24576
-       <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1221822 ofs=28672
-       <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1078684 ofs=32768
-       <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1158876 ofs=36864
-       <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1289644 ofs=40960
-       <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1289386 ofs=45056
-       <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1131002 ofs=49152
-       <unknown>-12683 (-----) [006] .... 1920260.580467: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1464335 ofs=53248
-       <unknown>-12683 (-----) [006] .... 1920260.580468: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1135789 ofs=57344
-       <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1240897 ofs=61440
-       <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241770 ofs=65536
-       <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1421959 ofs=69632
-       <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1230007 ofs=73728
-       <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1109271 ofs=77824
-       <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1159974 ofs=81920
-       <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1154528 ofs=86016
-       <unknown>-12683 (-----) [006] .... 1920260.580472: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1315790 ofs=90112
-       <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1185583 ofs=94208
-       <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1253153 ofs=98304
-       <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103982 ofs=102400
-       <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1284589 ofs=106496
-       <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1169601 ofs=110592
-       <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1206248 ofs=114688
-       <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1261161 ofs=118784
-       <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1305841 ofs=122880
-       <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1468293 ofs=126976
-       <unknown>-12683 (-----) [004] .... 1920260.580646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1318816 ofs=16384
-       <unknown>-12683 (-----) [004] .... 1920260.580649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1472922 ofs=20480
-       <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1473229 ofs=24576
-       <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1524262 ofs=28672
-       <unknown>-12683 (-----) [004] .... 1920260.580656: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1205714 ofs=32768
-       <unknown>-12683 (-----) [004] .... 1920260.580657: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1310560 ofs=36864
-       <unknown>-12683 (-----) [004] .... 1920260.580658: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1295070 ofs=40960
-       <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1404093 ofs=45056
-       <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1435814 ofs=49152
-       <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1435442 ofs=53248
-       <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1096077 ofs=57344
-       <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1483793 ofs=61440
-       <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1231298 ofs=65536
-       <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1215648 ofs=69632
-       <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1327326 ofs=73728
-       <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1108894 ofs=77824
-       <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1327545 ofs=81920
-       <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1328804 ofs=86016
-       <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1300171 ofs=90112
-       <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353250 ofs=94208
-       <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1333681 ofs=98304
-       <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1144969 ofs=102400
-       <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1450962 ofs=106496
-       <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1255701 ofs=110592
-       <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1294782 ofs=114688
-       <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1226912 ofs=118784
-       <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1294579 ofs=122880
-       <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246960 ofs=126976
-       <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1199086 ofs=131072
-       <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1449590 ofs=135168
-       <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1276363 ofs=139264
-       <unknown>-12683 (-----) [004] .... 1920260.580675: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1389998 ofs=143360
-       <unknown>-12683 (-----) [004] .... 1920260.580739: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1423031 ofs=1249280
-       <unknown>-12683 (-----) [004] .... 1920260.580741: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1171032 ofs=1253376
-       <unknown>-12683 (-----) [004] .... 1920260.580742: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1320946 ofs=1257472
-       <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1314696 ofs=1261568
-       <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1414864 ofs=1265664
-       <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1334933 ofs=1269760
-       <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1242845 ofs=1273856
-       <unknown>-12683 (-----) [004] .... 1920260.580747: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1289488 ofs=1277952
-       <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1335445 ofs=1282048
-       <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1289663 ofs=1286144
-       <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1080462 ofs=1290240
-       <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1286303 ofs=1294336
-       <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353531 ofs=1298432
-       <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1280701 ofs=1302528
-       <unknown>-12683 (-----) [004] .... 1920260.580751: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1107730 ofs=1306624
-       <unknown>-12683 (-----) [004] .... 1920260.580752: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1242729 ofs=1310720
-       <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1078336 ofs=1314816
-       <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1372425 ofs=1318912
-       <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1248813 ofs=1323008
-       <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1201155 ofs=1327104
-       <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1250103 ofs=1331200
-       <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1359710 ofs=1335296
-       <unknown>-12683 (-----) [004] .... 1920260.580756: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1272462 ofs=1339392
-       <unknown>-12683 (-----) [004] .... 1920260.580758: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1097035 ofs=1343488
-       <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1233124 ofs=1347584
-       <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1455812 ofs=1351680
-       <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1355689 ofs=1355776
-       <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1263593 ofs=1359872
-       <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1230789 ofs=1363968
-       <unknown>-12683 (-----) [004] .... 1920260.580761: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1143766 ofs=1368064
-       <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1269666 ofs=1372160
-       <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1353022 ofs=1376256
-       <unknown>-12683 (-----) [004] .... 1920260.581613: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1355509 ofs=258048
-       <unknown>-12683 (-----) [004] .... 1920260.581615: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1178902 ofs=262144
-       <unknown>-12683 (-----) [004] .... 1920260.581616: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1193649 ofs=266240
-       <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1225497 ofs=270336
-       <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1228259 ofs=274432
-       <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1309674 ofs=278528
-       <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1239390 ofs=282624
-       <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1468083 ofs=286720
-       <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1292751 ofs=290816
-       <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1318066 ofs=294912
-       <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1489314 ofs=299008
-       <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1169867 ofs=303104
-       <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1314256 ofs=307200
-       <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1310230 ofs=311296
-       <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1356180 ofs=315392
-       <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1419179 ofs=319488
-       <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1307265 ofs=323584
-       <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1218590 ofs=327680
-       <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447586 ofs=331776
-       <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1209382 ofs=335872
-       <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1072148 ofs=339968
-       <unknown>-12683 (-----) [004] .... 1920260.581645: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1227195 ofs=344064
-       <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1246369 ofs=348160
-       <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1193845 ofs=352256
-       <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1137553 ofs=356352
-       <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1475215 ofs=360448
-       <unknown>-12683 (-----) [004] .... 1920260.581648: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1258935 ofs=364544
-       <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1448788 ofs=368640
-       <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447611 ofs=372736
-       <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1290842 ofs=376832
-       <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1447826 ofs=380928
-       <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino da07 page=0000000000000000 pfn=1181016 ofs=385024
-       <unknown>-12683 (-----) [005] .... 1920260.582230: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1216810 ofs=1662976
-       <unknown>-12683 (-----) [005] .... 1920260.582234: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1175966 ofs=1667072
-       <unknown>-12683 (-----) [005] .... 1920260.582235: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1449798 ofs=1671168
-       <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1273480 ofs=1675264
-       <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1152779 ofs=1679360
-       <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1272810 ofs=1683456
-       <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1248634 ofs=1687552
-       <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1203376 ofs=1691648
-       <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1138880 ofs=1695744
-       <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1344591 ofs=1699840
-       <unknown>-12683 (-----) [005] .... 1920260.582239: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1416060 ofs=1703936
-       <unknown>-12683 (-----) [005] .... 1920260.582246: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1128676 ofs=1708032
-       <unknown>-12683 (-----) [005] .... 1920260.582247: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1301921 ofs=1712128
-       <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1384569 ofs=1716224
-       <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1249106 ofs=1720320
-       <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1206596 ofs=1724416
-       <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1429831 ofs=1728512
-       <unknown>-12683 (-----) [005] .... 1920260.582252: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1107796 ofs=1732608
-       <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1098336 ofs=1736704
-       <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1230286 ofs=1740800
-       <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1100370 ofs=1744896
-       <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1241930 ofs=1748992
-       <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1366807 ofs=1753088
-       <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1136252 ofs=1757184
-       <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1274291 ofs=1761280
-       <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1254775 ofs=1765376
-       <unknown>-12683 (-----) [005] .... 1920260.582259: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1194679 ofs=1769472
-       <unknown>-12683 (-----) [005] .... 1920260.582262: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1177090 ofs=1773568
-       <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1343925 ofs=1777664
-       <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1159217 ofs=1781760
-       <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435471 ofs=1785856
-       <unknown>-12683 (-----) [005] .... 1920260.582264: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435529 ofs=1789952
-       <unknown>-12683 (-----) [004] .... 1920260.582524: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1181910 ofs=0
-       <unknown>-12683 (-----) [004] .... 1920260.582528: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1212021 ofs=4096
-       <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1162778 ofs=8192
-       <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1107700 ofs=12288
-       <unknown>-12683 (-----) [004] .... 1920260.583553: mm_filemap_add_to_page_cache: dev 0:64771 ino df31 page=0000000000000000 pfn=1093394 ofs=3399680
-       <unknown>-12683 (-----) [004] .... 1920260.583984: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1121431 ofs=242503680
-       <unknown>-12683 (-----) [004] .... 1920260.583986: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1168551 ofs=13115392
-       <unknown>-12683 (-----) [004] .... 1920260.584304: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347409 ofs=0
-       <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1428681 ofs=4096
-       <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1259106 ofs=8192
-       <unknown>-12683 (-----) [004] .... 1920260.584308: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1343229 ofs=12288
-       <unknown>-12694 (-----) [005] .... 1920260.584622: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1098733 ofs=1531904
-       <unknown>-12696 (-----) [006] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331319 ofs=1536000
-       <unknown>-12694 (-----) [005] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278537 ofs=1540096
-       <unknown>-12696 (-----) [006] .... 1920260.584631: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1492534 ofs=1544192
-       <unknown>-12694 (-----) [005] .... 1920260.584636: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1460878 ofs=1548288
-       <unknown>-12694 (-----) [005] .... 1920260.584640: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092973 ofs=1552384
-       <unknown>-12694 (-----) [005] .... 1920260.584641: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1103200 ofs=1556480
-       <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1257426 ofs=1560576
-       <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1219424 ofs=1564672
-       <unknown>-12683 (-----) [004] .... 1920260.584660: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279352 ofs=1568768
-       <unknown>-12696 (-----) [006] .... 1920260.584662: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260572 ofs=1572864
-       <unknown>-12683 (-----) [004] .... 1920260.584663: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1225809 ofs=1576960
-       <unknown>-12696 (-----) [006] .... 1920260.584665: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1350766 ofs=1585152
-       <unknown>-12697 (-----) [007] .... 1920260.584666: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1107173 ofs=1581056
-       <unknown>-12683 (-----) [004] .... 1920260.584668: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1305885 ofs=1589248
-       <unknown>-12694 (-----) [005] .... 1920260.584669: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1293385 ofs=1593344
-       <unknown>-12696 (-----) [006] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1173841 ofs=1597440
-       <unknown>-12697 (-----) [007] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080021 ofs=1601536
-       <unknown>-12683 (-----) [004] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1147419 ofs=1605632
-       <unknown>-12696 (-----) [006] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1252762 ofs=1609728
-       <unknown>-12694 (-----) [005] .... 1920260.584674: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1323916 ofs=1613824
-       <unknown>-12683 (-----) [004] .... 1920260.584675: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1155631 ofs=1617920
-       <unknown>-12696 (-----) [006] .... 1920260.584676: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449815 ofs=1622016
-       <unknown>-12694 (-----) [005] .... 1920260.584678: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1227069 ofs=1626112
-       <unknown>-12696 (-----) [006] .... 1920260.584680: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1317692 ofs=1630208
-       <unknown>-12694 (-----) [005] .... 1920260.584681: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1492244 ofs=1634304
-       <unknown>-12683 (-----) [004] .... 1920260.584682: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241876 ofs=1638400
-       <unknown>-12697 (-----) [007] .... 1920260.585446: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1402958 ofs=167936
-       <unknown>-12697 (-----) [007] .... 1920260.585449: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1133263 ofs=172032
-       <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1295502 ofs=176128
-       <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1249495 ofs=180224
-       <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237999 ofs=184320
-       <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1280965 ofs=188416
-       <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1208361 ofs=192512
-       <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1308840 ofs=196608
-       <unknown>-12695 (-----) [004] .... 1920260.585455: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1138875 ofs=569344
-       <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314886 ofs=573440
-       <unknown>-12697 (-----) [007] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242734 ofs=200704
-       <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447386 ofs=577536
-       <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241302 ofs=204800
-       <unknown>-12695 (-----) [004] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1328663 ofs=581632
-       <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1476101 ofs=208896
-       <unknown>-12695 (-----) [004] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209461 ofs=585728
-       <unknown>-12697 (-----) [007] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080147 ofs=212992
-       <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128509 ofs=217088
-       <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1371915 ofs=221184
-       <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1264015 ofs=225280
-       <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1211695 ofs=229376
-       <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1150386 ofs=233472
-       <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1135747 ofs=237568
-       <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128230 ofs=241664
-       <unknown>-12697 (-----) [007] .... 1920260.585464: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1155451 ofs=245760
-       <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1246841 ofs=249856
-       <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1462971 ofs=253952
-       <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1131333 ofs=258048
-       <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289407 ofs=262144
-       <unknown>-12695 (-----) [004] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1134730 ofs=589824
-       <unknown>-12697 (-----) [007] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289873 ofs=266240
-       <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448734 ofs=270336
-       <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1129776 ofs=593920
-       <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524090 ofs=274432
-       <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399725 ofs=598016
-       <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524081 ofs=278528
-       <unknown>-12695 (-----) [004] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1276535 ofs=602112
-       <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1524060 ofs=282624
-       <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449847 ofs=606208
-       <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1158944 ofs=286720
-       <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1384536 ofs=610304
-       <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1116785 ofs=290816
-       <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1308118 ofs=614400
-       <unknown>-12697 (-----) [007] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448669 ofs=294912
-       <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1227050 ofs=618496
-       <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289324 ofs=622592
-       <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1187869 ofs=626688
-       <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1400523 ofs=630784
-       <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1344176 ofs=634880
-       <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092871 ofs=638976
-       <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092021 ofs=643072
-       <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1198169 ofs=647168
-       <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1371540 ofs=651264
-       <unknown>-12683 (-----) [005] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1195003 ofs=348160
-       <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1228787 ofs=655360
-       <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1236123 ofs=659456
-       <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1137213 ofs=663552
-       <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1294618 ofs=667648
-       <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241048 ofs=671744
-       <unknown>-12695 (-----) [004] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1228779 ofs=675840
-       <unknown>-12683 (-----) [005] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1199292 ofs=352256
-       <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200861 ofs=356352
-       <unknown>-12695 (-----) [004] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1309572 ofs=679936
-       <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1215770 ofs=360448
-       <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1409002 ofs=684032
-       <unknown>-12683 (-----) [005] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1151883 ofs=364544
-       <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1103729 ofs=688128
-       <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1468126 ofs=368640
-       <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1162720 ofs=692224
-       <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1251672 ofs=372736
-       <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1199221 ofs=696320
-       <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1283325 ofs=376832
-       <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1190489 ofs=380928
-       <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1489117 ofs=385024
-       <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1273899 ofs=389120
-       <unknown>-12683 (-----) [005] .... 1920260.585485: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1274459 ofs=393216
-       <unknown>-12683 (-----) [005] .... 1920260.585486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1316649 ofs=397312
-       <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1375678 ofs=401408
-       <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1483317 ofs=405504
-       <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1240286 ofs=409600
-       <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1131345 ofs=413696
-       <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200483 ofs=417792
-       <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1384693 ofs=421888
-       <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1161385 ofs=425984
-       <unknown>-12683 (-----) [005] .... 1920260.585494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1452025 ofs=430080
-       <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1253654 ofs=434176
-       <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1116697 ofs=438272
-       <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1432645 ofs=442368
-       <unknown>-12694 (-----) [006] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1337397 ofs=16384
-       <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1304229 ofs=446464
-       <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1419147 ofs=450560
-       <unknown>-12683 (-----) [005] .... 1920260.585498: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1349246 ofs=454656
-       <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1128519 ofs=458752
-       <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1125168 ofs=462848
-       <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1081031 ofs=20480
-       <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1293022 ofs=24576
-       <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1113007 ofs=28672
-       <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1339312 ofs=32768
-       <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1412311 ofs=36864
-       <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260960 ofs=40960
-       <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189529 ofs=45056
-       <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1412184 ofs=49152
-       <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1481227 ofs=53248
-       <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1455940 ofs=57344
-       <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299132 ofs=61440
-       <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1337375 ofs=65536
-       <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1328742 ofs=69632
-       <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1315646 ofs=73728
-       <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1225475 ofs=77824
-       <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1146097 ofs=81920
-       <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1318775 ofs=86016
-       <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1448391 ofs=90112
-       <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1441412 ofs=94208
-       <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1138111 ofs=98304
-       <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1143223 ofs=102400
-       <unknown>-12683 (-----) [005] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1079876 ofs=466944
-       <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447637 ofs=106496
-       <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1220585 ofs=110592
-       <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449051 ofs=114688
-       <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313180 ofs=118784
-       <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313166 ofs=122880
-       <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1313154 ofs=126976
-       <unknown>-12683 (-----) [005] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1218394 ofs=471040
-       <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1144047 ofs=131072
-       <unknown>-12683 (-----) [005] .... 1920260.585537: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1218579 ofs=475136
-       <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1241332 ofs=135168
-       <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1097199 ofs=139264
-       <unknown>-12694 (-----) [006] .... 1920260.585545: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1214197 ofs=143360
-       <unknown>-12694 (-----) [006] .... 1920260.585645: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197633 ofs=147456
-       <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1311536 ofs=151552
-       <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1322952 ofs=155648
-       <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346974 ofs=159744
-       <unknown>-12694 (-----) [006] .... 1920260.585648: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1257232 ofs=163840
-       <unknown>-12695 (-----) [004] .... 1920260.586355: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1204484 ofs=700416
-       <unknown>-12695 (-----) [004] .... 1920260.586357: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1326426 ofs=704512
-       <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1151808 ofs=708608
-       <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209422 ofs=712704
-       <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1408387 ofs=716800
-       <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197336 ofs=720896
-       <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1205652 ofs=724992
-       <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1133421 ofs=729088
-       <unknown>-12695 (-----) [004] .... 1920260.586364: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092173 ofs=733184
-       <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1124430 ofs=737280
-       <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1143926 ofs=741376
-       <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1090109 ofs=745472
-       <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1102012 ofs=749568
-       <unknown>-12695 (-----) [004] .... 1920260.586367: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1154930 ofs=753664
-       <unknown>-12695 (-----) [004] .... 1920260.586368: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1132993 ofs=757760
-       <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1430780 ofs=761856
-       <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1197452 ofs=765952
-       <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075111 ofs=770048
-       <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1275616 ofs=774144
-       <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1444981 ofs=778240
-       <unknown>-12695 (-----) [004] .... 1920260.586371: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1452592 ofs=782336
-       <unknown>-12695 (-----) [004] .... 1920260.586374: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1102857 ofs=786432
-       <unknown>-12695 (-----) [004] .... 1920260.586376: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406969 ofs=790528
-       <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1522553 ofs=794624
-       <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1260771 ofs=798720
-       <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1474649 ofs=802816
-       <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1268708 ofs=806912
-       <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346144 ofs=811008
-       <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1081167 ofs=815104
-       <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1137677 ofs=819200
-       <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1161175 ofs=823296
-       <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1461331 ofs=827392
-       <unknown>-12695 (-----) [004] .... 1920260.586492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347219 ofs=831488
-       <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1290004 ofs=835584
-       <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299174 ofs=839680
-       <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1317595 ofs=843776
-       <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1484924 ofs=847872
-       <unknown>-12695 (-----) [004] .... 1920260.586497: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1169920 ofs=851968
-       <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1359189 ofs=856064
-       <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1307842 ofs=860160
-       <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237858 ofs=864256
-       <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189461 ofs=868352
-       <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1223232 ofs=872448
-       <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1104076 ofs=876544
-       <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1079223 ofs=880640
-       <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1092537 ofs=884736
-       <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1353960 ofs=888832
-       <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1346330 ofs=892928
-       <unknown>-12695 (-----) [004] .... 1920260.586506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345764 ofs=897024
-       <unknown>-12695 (-----) [004] .... 1920260.586507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1363913 ofs=901120
-       <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1319570 ofs=905216
-       <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1367024 ofs=909312
-       <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1333808 ofs=913408
-       <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1158627 ofs=917504
-       <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1300368 ofs=921600
-       <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1245363 ofs=925696
-       <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345609 ofs=929792
-       <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1393826 ofs=933888
-       <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1200552 ofs=937984
-       <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1170885 ofs=942080
-       <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1536209 ofs=946176
-       <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189630 ofs=950272
-       <unknown>-12695 (-----) [004] .... 1920260.586513: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1121010 ofs=954368
-       <unknown>-12695 (-----) [004] .... 1920260.586514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324474 ofs=958464
-       <unknown>-12697 (-----) [007] .... 1920260.586578: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1129628 ofs=299008
-       <unknown>-12697 (-----) [007] .... 1920260.586579: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1307120 ofs=303104
-       <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1347284 ofs=307200
-       <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1312996 ofs=311296
-       <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1170623 ofs=315392
-       <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1359281 ofs=319488
-       <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1180021 ofs=323584
-       <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1195728 ofs=327680
-       <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1163642 ofs=331776
-       <unknown>-12697 (-----) [007] .... 1920260.586587: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1152538 ofs=335872
-       <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1345922 ofs=339968
-       <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1343604 ofs=344064
-       <unknown>-12697 (-----) [007] .... 1920260.586721: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399371 ofs=479232
-       <unknown>-12697 (-----) [007] .... 1920260.586723: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1106549 ofs=483328
-       <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331546 ofs=487424
-       <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1299299 ofs=491520
-       <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1288883 ofs=495616
-       <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1399049 ofs=499712
-       <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1146931 ofs=503808
-       <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1296592 ofs=507904
-       <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1468397 ofs=512000
-       <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1215698 ofs=516096
-       <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1177341 ofs=520192
-       <unknown>-12697 (-----) [007] .... 1920260.586731: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1189162 ofs=524288
-       <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1435997 ofs=528384
-       <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1209896 ofs=532480
-       <unknown>-12697 (-----) [007] .... 1920260.586733: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1255888 ofs=536576
-       <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1234200 ofs=540672
-       <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1422854 ofs=544768
-       <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1435794 ofs=548864
-       <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1236279 ofs=552960
-       <unknown>-12697 (-----) [007] .... 1920260.586736: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1485732 ofs=557056
-       <unknown>-12683 (-----) [005] .... 1920260.586743: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1417198 ofs=561152
-       <unknown>-12683 (-----) [005] .... 1920260.586746: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1469450 ofs=565248
-       <unknown>-12696 (-----) [004] .... 1920260.587465: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1489023 ofs=1040384
-       <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1449498 ofs=1044480
-       <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1447737 ofs=1048576
-       <unknown>-12696 (-----) [004] .... 1920260.587470: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1124530 ofs=1052672
-       <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1246743 ofs=1056768
-       <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1441927 ofs=1060864
-       <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1280581 ofs=1064960
-       <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1289438 ofs=1069056
-       <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1464236 ofs=1073152
-       <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1125808 ofs=1077248
-       <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1329385 ofs=1081344
-       <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314093 ofs=1085440
-       <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1201837 ofs=1089536
-       <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1327734 ofs=1093632
-       <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406568 ofs=1097728
-       <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331873 ofs=1101824
-       <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331898 ofs=1105920
-       <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1331917 ofs=1110016
-       <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1332091 ofs=1114112
-       <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1108186 ofs=1118208
-       <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1182631 ofs=1122304
-       <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1085941 ofs=1126400
-       <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1433982 ofs=1130496
-       <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1387028 ofs=1134592
-       <unknown>-12696 (-----) [004] .... 1920260.587488: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1353117 ofs=1138688
-       <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1352364 ofs=1142784
-       <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1144513 ofs=1146880
-       <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1403984 ofs=1150976
-       <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278970 ofs=1155072
-       <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1326743 ofs=1159168
-       <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1221809 ofs=1163264
-       <unknown>-12696 (-----) [004] .... 1920260.587492: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1268668 ofs=1167360
-       <unknown>-12695 (-----) [005] .... 1920260.587502: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1074544 ofs=962560
-       <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1074294 ofs=966656
-       <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075097 ofs=970752
-       <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1162407 ofs=974848
-       <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1141370 ofs=978944
-       <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306487 ofs=983040
-       <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306434 ofs=987136
-       <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306347 ofs=991232
-       <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306247 ofs=995328
-       <unknown>-12695 (-----) [005] .... 1920260.587515: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306195 ofs=999424
-       <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1306039 ofs=1003520
-       <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1305983 ofs=1007616
-       <unknown>-12694 (-----) [006] .... 1920260.587701: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1216391 ofs=1171456
-       <unknown>-12694 (-----) [006] .... 1920260.587705: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1262462 ofs=1175552
-       <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1358114 ofs=1179648
-       <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1357898 ofs=1183744
-       <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1237003 ofs=1187840
-       <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1126319 ofs=1191936
-       <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1415489 ofs=1196032
-       <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279558 ofs=1200128
-       <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1434022 ofs=1204224
-       <unknown>-12694 (-----) [006] .... 1920260.587709: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1220130 ofs=1208320
-       <unknown>-12694 (-----) [006] .... 1920260.587710: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1163037 ofs=1212416
-       <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1404501 ofs=1216512
-       <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1406287 ofs=1220608
-       <unknown>-12697 (-----) [007] .... 1920260.588132: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1355143 ofs=1376256
-       <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1213923 ofs=1380352
-       <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1243190 ofs=1384448
-       <unknown>-12697 (-----) [007] .... 1920260.588143: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1300698 ofs=1388544
-       <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1482568 ofs=1392640
-       <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1461789 ofs=1396736
-       <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242314 ofs=1400832
-       <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1471996 ofs=1404928
-       <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242742 ofs=1409024
-       <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242579 ofs=1413120
-       <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1242553 ofs=1417216
-       <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1457332 ofs=1421312
-       <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1315431 ofs=1425408
-       <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1080653 ofs=1429504
-       <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324174 ofs=1433600
-       <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1324142 ofs=1437696
-       <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1157760 ofs=1441792
-       <unknown>-12697 (-----) [007] .... 1920260.588151: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1075059 ofs=1445888
-       <unknown>-12683 (-----) [006] .... 1920260.589785: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1279192 ofs=1486848
-       <unknown>-12683 (-----) [006] .... 1920260.589790: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1278527 ofs=1490944
-       <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1091778 ofs=1495040
-       <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1339447 ofs=1499136
-       <unknown>-12683 (-----) [006] .... 1920260.589792: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1254007 ofs=1503232
-       <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1115173 ofs=1507328
-       <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1393985 ofs=1511424
-       <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1369123 ofs=1515520
-       <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1314257 ofs=1519616
-       <unknown>-12683 (-----) [006] .... 1920260.589802: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1404487 ofs=1523712
-       <unknown>-12683 (-----) [006] .... 1920260.589803: mm_filemap_add_to_page_cache: dev 0:64771 ino e745 page=0000000000000000 pfn=1354554 ofs=1527808
-       <unknown>-12683 (-----) [006] .... 1920260.594312: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1141445 ofs=9801728
-       <unknown>-12683 (-----) [006] .... 1920260.594322: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323774 ofs=231460864
-       <unknown>-12683 (-----) [006] .... 1920260.594326: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323772 ofs=10993664
-       <unknown>-12683 (-----) [006] .... 1920260.595212: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481305 ofs=9805824
-       <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481306 ofs=9809920
-       <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481316 ofs=9814016
-       <unknown>-12683 (-----) [006] .... 1920260.595215: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1481340 ofs=9818112
-       <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1394587 ofs=9822208
-       <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103455 ofs=9826304
-       <unknown>-12683 (-----) [006] .... 1920260.595217: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103271 ofs=9830400
-       <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103168 ofs=9834496
-       <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103145 ofs=9838592
-       <unknown>-12683 (-----) [006] .... 1920260.595219: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103115 ofs=9842688
-       <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103057 ofs=9846784
-       <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1331958 ofs=9850880
-       <unknown>-12683 (-----) [006] .... 1920260.595227: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1356305 ofs=9854976
-       <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103708 ofs=9859072
-       <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1099286 ofs=9863168
-       <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1435190 ofs=9867264
-       <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1395504 ofs=9871360
-       <unknown>-12683 (-----) [006] .... 1920260.595230: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1352916 ofs=9875456
-       <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1255529 ofs=9879552
-       <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1336145 ofs=9883648
-       <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1334143 ofs=9887744
-       <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1328548 ofs=9891840
-       <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1222215 ofs=9895936
-       <unknown>-12683 (-----) [006] .... 1920260.595233: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1461056 ofs=9900032
-       <unknown>-12683 (-----) [006] .... 1920260.595234: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1228276 ofs=9904128
-       <unknown>-12683 (-----) [006] .... 1920260.595235: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1151188 ofs=9908224
-       <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1443605 ofs=9912320
-       <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1146821 ofs=9916416
-       <unknown>-12683 (-----) [006] .... 1920260.595237: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103669 ofs=9920512
-       <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103744 ofs=9924608
-       <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1103868 ofs=9928704
-       <unknown>-12683 (-----) [006] .... 1920260.595789: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1465942 ofs=15855616
-       <unknown>-12683 (-----) [006] .... 1920260.595792: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323712 ofs=261189632
-       <unknown>-12683 (-----) [006] .... 1920260.595998: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323701 ofs=262094848
-       <unknown>-12683 (-----) [006] .... 1920260.596191: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1222287 ofs=15859712
-       <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1213146 ofs=15863808
-       <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1310396 ofs=15867904
-       <unknown>-12683 (-----) [006] .... 1920260.596193: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1310177 ofs=15872000
-       <unknown>-12683 (-----) [006] .... 1920260.596194: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1187914 ofs=15876096
-       <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1322409 ofs=15880192
-       <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1282484 ofs=15884288
-       <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1097245 ofs=15888384
-       <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1416816 ofs=15892480
-       <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1257125 ofs=15896576
-       <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1403527 ofs=15900672
-       <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1218006 ofs=15904768
-       <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1153893 ofs=15908864
-       <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1328023 ofs=15912960
-       <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1465412 ofs=15917056
-       <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1092448 ofs=15921152
-       <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1239220 ofs=15925248
-       <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1276491 ofs=15929344
-       <unknown>-12683 (-----) [006] .... 1920260.596205: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1262240 ofs=15933440
-       <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1323793 ofs=15937536
-       <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1074937 ofs=15941632
-       <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1311157 ofs=15945728
-       <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1308442 ofs=15949824
-       <unknown>-12683 (-----) [006] .... 1920260.596210: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1467709 ofs=15953920
-       <unknown>-12683 (-----) [006] .... 1920260.596211: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1394299 ofs=15958016
-       <unknown>-12683 (-----) [004] .... 1920260.612586: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1316156 ofs=344064
-       <unknown>-12683 (-----) [004] .... 1920260.612591: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1406323 ofs=348160
-       <unknown>-12683 (-----) [004] .... 1920260.612601: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1216972 ofs=352256
-       <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1271924 ofs=356352
-       <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1369225 ofs=360448
-       <unknown>-12683 (-----) [004] .... 1920260.612608: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1318474 ofs=364544
-       <unknown>-12683 (-----) [004] .... 1920260.612609: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1227283 ofs=368640
-       <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1364376 ofs=372736
-       <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 180a page=0000000000000000 pfn=1073400 ofs=376832
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
deleted file mode 100644
index ab3df45..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_with_duration.TraceFile.pb
+++ /dev/null
Binary files differ
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb b/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
deleted file mode 100644
index 17cb116..0000000
--- a/startop/scripts/iorap/test_fixtures/compiler/test_result_without_duration.TraceFile.pb
+++ /dev/null
Binary files differ
diff --git a/startop/scripts/lib/cmd_utils.py b/startop/scripts/lib/cmd_utils.py
deleted file mode 100644
index 6071f14..0000000
--- a/startop/scripts/lib/cmd_utils.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Helper util libraries for command line operations."""
-
-import asyncio
-import sys
-import time
-from typing import Tuple, Optional, List
-
-import lib.print_utils as print_utils
-
-TIMEOUT = 50
-SIMULATE = False
-
-def run_command_nofail(cmd: List[str], **kwargs) -> None:
-  """Runs cmd list with default timeout.
-
-     Throws exception if the execution fails.
-  """
-  my_kwargs = {"timeout": TIMEOUT, "shell": False, "simulate": False}
-  my_kwargs.update(kwargs)
-  passed, out = execute_arbitrary_command(cmd, **my_kwargs)
-  if not passed:
-    raise RuntimeError(
-      "Failed to execute %s (kwargs=%s), output=%s" % (cmd, kwargs, out))
-
-def run_adb_shell_command(cmd: str) -> Tuple[bool, str]:
-  """Runs command using adb shell.
-
-  Returns:
-    A tuple of running status (True=succeeded, False=failed or timed out) and
-    std output (string contents of stdout with trailing whitespace removed).
-  """
-  return run_shell_command('adb shell "{}"'.format(cmd))
-
-def run_shell_func(script_path: str,
-                   func: str,
-                   args: List[str]) -> Tuple[bool, str]:
-  """Runs shell function with default timeout.
-
-  Returns:
-    A tuple of running status (True=succeeded, False=failed or timed out) and
-    std output (string contents of stdout with trailing whitespace removed) .
-  """
-  if args:
-    cmd = 'bash -c "source {script_path}; {func} {args}"'.format(
-      script_path=script_path,
-      func=func,
-      args=' '.join("'{}'".format(arg) for arg in args))
-  else:
-    cmd = 'bash -c "source {script_path}; {func}"'.format(
-      script_path=script_path,
-      func=func)
-
-  print_utils.debug_print(cmd)
-  return run_shell_command(cmd)
-
-def run_shell_command(cmd: str) -> Tuple[bool, str]:
-  """Runs shell command with default timeout.
-
-  Returns:
-    A tuple of running status (True=succeeded, False=failed or timed out) and
-    std output (string contents of stdout with trailing whitespace removed) .
-  """
-  return execute_arbitrary_command([cmd],
-                                   TIMEOUT,
-                                   shell=True,
-                                   simulate=SIMULATE)
-
-def execute_arbitrary_command(cmd: List[str],
-                              timeout: int,
-                              shell: bool,
-                              simulate: bool) -> Tuple[bool, str]:
-  """Run arbitrary shell command with default timeout.
-
-    Mostly copy from
-    frameworks/base/startop/scripts/app_startup/app_startup_runner.py.
-
-  Args:
-    cmd: list of cmd strings.
-    timeout: the time limit of running cmd.
-    shell: indicate if the cmd is a shell command.
-    simulate: if it's true, do not run the command and assume the running is
-        successful.
-
-  Returns:
-    A tuple of running status (True=succeeded, False=failed or timed out) and
-    std output (string contents of stdout with trailing whitespace removed) .
-  """
-  if simulate:
-    print(cmd)
-    return True, ''
-
-  print_utils.debug_print('[EXECUTE]', cmd)
-  # block until either command finishes or the timeout occurs.
-  loop = asyncio.get_event_loop()
-
-  (return_code, script_output) = loop.run_until_complete(
-    _run_command(*cmd, shell=shell, timeout=timeout))
-
-  script_output = script_output.decode()  # convert bytes to str
-
-  passed = (return_code == 0)
-  print_utils.debug_print('[$?]', return_code)
-  if not passed:
-    print('[FAILED, code:%s]' % (return_code), script_output, file=sys.stderr)
-
-  return passed, script_output.rstrip()
-
-async def _run_command(*args: List[str],
-                       shell: bool = False,
-                       timeout: Optional[int] = None) -> Tuple[int, bytes]:
-  if shell:
-    process = await asyncio.create_subprocess_shell(
-      *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
-  else:
-    process = await asyncio.create_subprocess_exec(
-      *args, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT)
-
-  script_output = b''
-
-  print_utils.debug_print('[PID]', process.pid)
-
-  timeout_remaining = timeout
-  time_started = time.time()
-
-  # read line (sequence of bytes ending with b'\n') asynchronously
-  while True:
-    try:
-      line = await asyncio.wait_for(process.stdout.readline(),
-                                    timeout_remaining)
-      print_utils.debug_print('[STDOUT]', line)
-      script_output += line
-
-      if timeout_remaining:
-        time_elapsed = time.time() - time_started
-        timeout_remaining = timeout - time_elapsed
-    except asyncio.TimeoutError:
-      print_utils.debug_print('[TIMEDOUT] Process ', process.pid)
-
-      print_utils.debug_print('[TIMEDOUT] Sending SIGTERM.')
-      process.terminate()
-
-      # 5 second timeout for process to handle SIGTERM nicely.
-      try:
-        (remaining_stdout,
-         remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
-        script_output += remaining_stdout
-      except asyncio.TimeoutError:
-        print_utils.debug_print('[TIMEDOUT] Sending SIGKILL.')
-        process.kill()
-
-      # 5 second timeout to finish with SIGKILL.
-      try:
-        (remaining_stdout,
-         remaining_stderr) = await asyncio.wait_for(process.communicate(), 5)
-        script_output += remaining_stdout
-      except asyncio.TimeoutError:
-        # give up, this will leave a zombie process.
-        print_utils.debug_print('[TIMEDOUT] SIGKILL failed for process ',
-                                process.pid)
-        time.sleep(100)
-
-      return -1, script_output
-    else:
-      if not line:  # EOF
-        break
-
-  code = await process.wait()  # wait for child process to exit
-  return code, script_output
diff --git a/startop/scripts/lib/logcat_utils.py b/startop/scripts/lib/logcat_utils.py
deleted file mode 100644
index 8a3d00b..0000000
--- a/startop/scripts/lib/logcat_utils.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Helper util libraries for parsing logcat logs."""
-
-import asyncio
-import re
-from datetime import datetime
-from typing import Optional, Pattern
-
-# local import
-import lib.print_utils as print_utils
-
-def parse_logcat_datetime(timestamp: str) -> Optional[datetime]:
-  """Parses the timestamp of logcat.
-
-  Params:
-    timestamp: for example "2019-07-01 16:13:55.221".
-
-  Returns:
-    a datetime of timestamp with the year now.
-  """
-  try:
-    # Match the format of logcat. For example: "2019-07-01 16:13:55.221",
-    # because it doesn't have year, set current year to it.
-    timestamp = datetime.strptime(timestamp,
-                                  '%Y-%m-%d %H:%M:%S.%f')
-    return timestamp
-  except ValueError as ve:
-    print_utils.debug_print('Invalid line: ' + timestamp)
-    return None
-
-def _is_time_out(timeout: datetime, line: str) -> bool:
-  """Checks if the timestamp of this line exceeds the timeout.
-
-  Returns:
-    true if the timestamp exceeds the timeout.
-  """
-  # Get the timestampe string.
-  cur_timestamp_str = ' '.join(re.split(r'\s+', line)[0:2])
-  timestamp = parse_logcat_datetime(cur_timestamp_str)
-  if not timestamp:
-    return False
-
-  return timestamp > timeout
-
-async def _blocking_wait_for_logcat_pattern(timestamp: datetime,
-                                            pattern: Pattern,
-                                            timeout: datetime) -> Optional[str]:
-  # Show the year in the timestampe.
-  logcat_cmd = 'adb logcat -v UTC -v year -v threadtime -T'.split()
-  logcat_cmd.append(str(timestamp))
-  print_utils.debug_print('[LOGCAT]:' + ' '.join(logcat_cmd))
-
-  # Create subprocess
-  process = await asyncio.create_subprocess_exec(
-      *logcat_cmd,
-      # stdout must a pipe to be accessible as process.stdout
-      stdout=asyncio.subprocess.PIPE)
-
-  while (True):
-    # Read one line of output.
-    data = await process.stdout.readline()
-    line = data.decode('utf-8').rstrip()
-
-    # 2019-07-01 14:54:21.946 27365 27392 I ActivityTaskManager: Displayed
-    # com.android.settings/.Settings: +927ms
-    # TODO: Detect timeouts even when there is no logcat output.
-    if _is_time_out(timeout, line):
-      print_utils.debug_print('DID TIMEOUT BEFORE SEEING ANYTHING ('
-                              'timeout={timeout} seconds << {pattern} '
-                              '>>'.format(timeout=timeout, pattern=pattern))
-      return None
-
-    if pattern.match(line):
-      print_utils.debug_print(
-          'WE DID SEE PATTERN << "{}" >>.'.format(pattern))
-      return line
-
-def blocking_wait_for_logcat_pattern(timestamp: datetime,
-                                     pattern: Pattern,
-                                     timeout: datetime) -> Optional[str]:
-  """Selects the line that matches the pattern and within the timeout.
-
-  Returns:
-    the line that matches the pattern and within the timeout.
-  """
-  loop = asyncio.get_event_loop()
-  result = loop.run_until_complete(
-      _blocking_wait_for_logcat_pattern(timestamp, pattern, timeout))
-  return result
diff --git a/startop/scripts/lib/logcat_utils_test.py b/startop/scripts/lib/logcat_utils_test.py
deleted file mode 100644
index ab82515..0000000
--- a/startop/scripts/lib/logcat_utils_test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-"""Unit tests for the logcat_utils.py script."""
-
-import asyncio
-import datetime
-import re
-
-import logcat_utils
-from mock import MagicMock, patch
-
-def test_parse_logcat_datatime():
-  # Act
-  result = logcat_utils.parse_logcat_datetime('2019-07-01 16:13:55.221')
-
-  # Assert
-  assert result == datetime.datetime(2019, 7, 1, 16, 13, 55, 221000)
-
-class AsyncMock(MagicMock):
-  async def __call__(self, *args, **kwargs):
-    return super(AsyncMock, self).__call__(*args, **kwargs)
-
-def _async_return():
-  f = asyncio.Future()
-  f.set_result(
-      b'2019-07-01 15:51:53.290 27365 27392 I ActivityTaskManager: '
-      b'Displayed com.google.android.music/com.android.music.activitymanagement.'
-      b'TopLevelActivity: +1s7ms')
-  return f
-
-def test_parse_displayed_time_succeed():
-  # Act
-  with patch('asyncio.create_subprocess_exec',
-             new_callable=AsyncMock) as asyncio_mock:
-    asyncio_mock.return_value.stdout.readline = _async_return
-    timestamp = datetime.datetime(datetime.datetime.now().year, 7, 1, 16, 13,
-                                  55, 221000)
-    timeout_dt = timestamp + datetime.timedelta(0, 10)
-    pattern = re.compile('.*ActivityTaskManager: Displayed '
-                         'com.google.android.music/com.android.music.*')
-    result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
-                                                           pattern,
-                                                           timeout_dt)
-
-    # Assert
-    assert result == '2019-07-01 15:51:53.290 27365 27392 I ' \
-                     'ActivityTaskManager: ' \
-                     'Displayed com.google.android.music/com.android.music.' \
-                     'activitymanagement.TopLevelActivity: +1s7ms'
-
-def _async_timeout_return():
-  f = asyncio.Future()
-  f.set_result(
-      b'2019-07-01 17:51:53.290 27365 27392 I ActivityTaskManager: '
-      b'Displayed com.google.android.music/com.android.music.activitymanagement.'
-      b'TopLevelActivity: +1s7ms')
-  return f
-
-def test_parse_displayed_time_timeout():
-  # Act
-  with patch('asyncio.create_subprocess_exec',
-             new_callable=AsyncMock) as asyncio_mock:
-    asyncio_mock.return_value.stdout.readline = _async_timeout_return
-    timestamp = datetime.datetime(datetime.datetime.now().year,
-                                  7, 1, 16, 13, 55, 221000)
-    timeout_dt = timestamp + datetime.timedelta(0, 10)
-    pattern = re.compile('.*ActivityTaskManager: Displayed '
-                         'com.google.android.music/com.android.music.*')
-    result = logcat_utils.blocking_wait_for_logcat_pattern(timestamp,
-                                                           pattern,
-                                                           timeout_dt)
-
-    # Assert
-    assert result == None
diff --git a/startop/scripts/lib/print_utils.py b/startop/scripts/lib/print_utils.py
deleted file mode 100644
index 8c5999d..0000000
--- a/startop/scripts/lib/print_utils.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Helper util libraries for debug printing."""
-
-import sys
-
-DEBUG = False
-
-def debug_print(*args, **kwargs):
-  """Prints the args to sys.stderr if the DEBUG is set."""
-  if DEBUG:
-    print(*args, **kwargs, file=sys.stderr)
-
-def error_print(*args, **kwargs):
-  print('[ERROR]:', *args, file=sys.stderr, **kwargs)
-
-def _expand_gen_repr(args):
-  """Like repr but any generator-like object has its iterator consumed
-  and then called repr on."""
-  new_args_list = []
-  for i in args:
-    # detect iterable objects that do not have their own override of __str__
-    if hasattr(i, '__iter__'):
-      to_str = getattr(i, '__str__')
-      if to_str.__objclass__ == object:
-        # the repr for a generator is just type+address, expand it out instead.
-        new_args_list.append([_expand_gen_repr([j])[0] for j in i])
-        continue
-    # normal case: uses the built-in to-string
-    new_args_list.append(i)
-  return new_args_list
-
-def debug_print_gen(*args, **kwargs):
-  """Like _debug_print but will turn any iterable args into a list."""
-  if not DEBUG:
-    return
-
-  new_args_list = _expand_gen_repr(args)
-  debug_print(*new_args_list, **kwargs)
-
-def debug_print_nd(*args, **kwargs):
-  """Like _debug_print but will turn any NamedTuple-type args into a string."""
-  if not DEBUG:
-    return
-
-  new_args_list = []
-  for i in args:
-    if hasattr(i, '_field_types'):
-      new_args_list.append("%s: %s" % (i.__name__, i._field_types))
-    else:
-      new_args_list.append(i)
-
-  debug_print(*new_args_list, **kwargs)
diff --git a/startop/scripts/trace_analyzer/lib/trace2db.py b/startop/scripts/trace_analyzer/lib/trace2db.py
deleted file mode 100644
index 42a33af..0000000
--- a/startop/scripts/trace_analyzer/lib/trace2db.py
+++ /dev/null
@@ -1,355 +0,0 @@
-#!/usr/bin/python3
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import re
-import sys
-
-from sqlalchemy import create_engine
-from sqlalchemy import Column, Date, Integer, Float, String, ForeignKey
-from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy.orm import relationship
-
-from sqlalchemy.orm import sessionmaker
-
-import sqlalchemy
-
-from typing import Optional, Tuple
-
-_DEBUG = False        # print sql commands to console
-_FLUSH_LIMIT = 10000  # how many entries are parsed before flushing to DB from memory
-
-Base = declarative_base()
-
-class RawFtraceEntry(Base):
-  __tablename__ = 'raw_ftrace_entries'
-
-  id = Column(Integer, primary_key=True)
-  task_name = Column(String, nullable=True) # <...> -> None.
-  task_pid = Column(String, nullable=False)
-  tgid = Column(Integer, nullable=True)     # ----- -> None.
-  cpu = Column(Integer, nullable=False)
-  timestamp = Column(Float, nullable=False)
-  function = Column(String, nullable=False)
-  function_args = Column(String, nullable=False)
-
-  # 1:1 relation with MmFilemapAddToPageCache.
-  mm_filemap_add_to_page_cache = relationship("MmFilemapAddToPageCache",
-                                              back_populates="raw_ftrace_entry")
-
-  @staticmethod
-  def parse_dict(line):
-    # '           <...>-5521  (-----) [003] ...1 17148.446877: tracing_mark_write: trace_event_clock_sync: parent_ts=17148.447266'
-    m = re.match('\s*(.*)-(\d+)\s+\(([^\)]+)\)\s+\[(\d+)\]\s+([\w.]{4})\s+(\d+[.]\d+):\s+(\w+):\s+(.*)', line)
-    if not m:
-      return None
-
-    groups = m.groups()
-    # groups example:
-    # ('<...>',
-    #  '5521',
-    #  '-----',
-    #  '003',
-    #  '...1',
-    #  '17148.446877',
-    #  'tracing_mark_write',
-    #  'trace_event_clock_sync: parent_ts=17148.447266')
-    task_name = groups[0]
-    if task_name == '<...>':
-      task_name = None
-
-    task_pid = int(groups[1])
-    tgid = groups[2]
-    if tgid == '-----':
-      tgid = None
-
-    cpu = int(groups[3])
-    # irq_flags = groups[4]
-    timestamp = float(groups[5])
-    function = groups[6]
-    function_args = groups[7]
-
-    return {'task_name': task_name, 'task_pid': task_pid, 'tgid': tgid, 'cpu': cpu, 'timestamp': timestamp, 'function': function, 'function_args': function_args}
-
-class SchedSwitch(Base):
-  __tablename__ = 'sched_switches'
-
-  id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
-
-  prev_comm = Column(String, nullable=False)
-  prev_pid = Column(Integer, nullable=False)
-  prev_prio = Column(Integer, nullable=False)
-  prev_state = Column(String, nullable=False)
-
-  next_comm = Column(String, nullable=False)
-  next_pid = Column(Integer, nullable=False)
-  next_prio = Column(Integer, nullable=False)
-
-  @staticmethod
-  def parse_dict(function_args, id = None):
-    # 'prev_comm=kworker/u16:5 prev_pid=13971 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120'
-    m = re.match("prev_comm=(.*) prev_pid=(\d+) prev_prio=(\d+) prev_state=(.*) ==> next_comm=(.*) next_pid=(\d+) next_prio=(\d+) ?", function_args)
-    if not m:
-      return None
-
-    groups = m.groups()
-    # ('kworker/u16:5', '13971', '120', 'S', 'swapper/4', '0', '120')
-    d = {}
-    if id is not None:
-      d['id'] = id
-    d['prev_comm'] = groups[0]
-    d['prev_pid'] = int(groups[1])
-    d['prev_prio'] = int(groups[2])
-    d['prev_state'] = groups[3]
-    d['next_comm'] = groups[4]
-    d['next_pid'] = int(groups[5])
-    d['next_prio'] = int(groups[6])
-
-    return d
-
-class SchedBlockedReason(Base):
-  __tablename__ = 'sched_blocked_reasons'
-
-  id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
-
-  pid = Column(Integer, nullable=False)
-  iowait = Column(Integer, nullable=False)
-  caller = Column(String, nullable=False)
-
-  @staticmethod
-  def parse_dict(function_args, id = None):
-    # 'pid=2289 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f'
-    m = re.match("pid=(\d+) iowait=(\d+) caller=(.*) ?", function_args)
-    if not m:
-      return None
-
-    groups = m.groups()
-    # ('2289', '1', 'wait_on_page_bit_common+0x2a8/0x5f8')
-    d = {}
-    if id is not None:
-      d['id'] = id
-    d['pid'] = int(groups[0])
-    d['iowait'] = int(groups[1])
-    d['caller'] = groups[2]
-
-    return d
-
-class MmFilemapAddToPageCache(Base):
-  __tablename__ = 'mm_filemap_add_to_page_caches'
-
-  id = Column(Integer, ForeignKey('raw_ftrace_entries.id'), primary_key=True)
-
-  dev = Column(Integer, nullable=False)        # decoded from ${major}:${minor} syntax.
-  dev_major = Column(Integer, nullable=False)  # original ${major} value.
-  dev_minor = Column(Integer, nullable=False)  # original ${minor} value.
-
-  ino = Column(Integer, nullable=False)  # decoded from hex to base 10
-  page = Column(Integer, nullable=False) # decoded from hex to base 10
-
-  pfn = Column(Integer, nullable=False)
-  ofs = Column(Integer, nullable=False)
-
-  # 1:1 relation with RawFtraceEntry.
-  raw_ftrace_entry = relationship("RawFtraceEntry", uselist=False)
-
-  @staticmethod
-  def parse_dict(function_args, id = None):
-    # dev 253:6 ino b2c7 page=00000000ec787cd9 pfn=1478539 ofs=4096
-    m = re.match("dev (\d+):(\d+) ino ([0-9a-fA-F]+) page=([0-9a-fA-F]+) pfn=(\d+) ofs=(\d+)", function_args)
-    if not m:
-      return None
-
-    groups = m.groups()
-    # ('253', '6', 'b2c7', '00000000ec787cd9', '1478539', '4096')
-    d = {}
-    if id is not None:
-      d['id'] = id
-
-    device_major = d['dev_major'] = int(groups[0])
-    device_minor = d['dev_minor'] = int(groups[1])
-    d['dev'] = device_major << 8 | device_minor
-    d['ino'] = int(groups[2], 16)
-    d['page'] = int(groups[3], 16)
-    d['pfn'] = int(groups[4])
-    d['ofs'] = int(groups[5])
-
-    return d
-
-class Trace2Db:
-  def __init__(self, db_filename: str):
-    (s, e) = self._init_sqlalchemy(db_filename)
-    self._session = s
-    self._engine = e
-    self._raw_ftrace_entry_filter = lambda x: True
-
-  def set_raw_ftrace_entry_filter(self, flt):
-    """
-    Install a function dict(RawFtraceEntry) -> bool
-
-    If this returns 'false', then we skip adding the RawFtraceEntry to the database.
-    """
-    self._raw_ftrace_entry_filter = flt
-
-  @staticmethod
-  def _init_sqlalchemy(db_filename: str) -> Tuple[object, object]:
-    global _DEBUG
-    engine = create_engine('sqlite:///' + db_filename, echo=_DEBUG)
-
-    # CREATE ... (tables)
-    Base.metadata.create_all(engine)
-
-    Session = sessionmaker(bind=engine)
-    session = Session()
-    return (session, engine)
-
-  def parse_file_into_db(self, filename: str, limit: Optional[int] = None):
-    """
-    Parse the ftrace/systrace at 'filename',
-    inserting the values into the current sqlite database.
-
-    :return: number of RawFtraceEntry inserted.
-    """
-    return parse_file(filename, self._session, self._engine, self._raw_ftrace_entry_filter, limit)
-
-  def parse_file_buf_into_db(self, file_buf, limit: Optional[int] = None):
-    """
-    Parse the ftrace/systrace at 'filename',
-    inserting the values into the current sqlite database.
-
-    :return: number of RawFtraceEntry inserted.
-    """
-    return parse_file_buf(file_buf, self._session, self._engine, self._raw_ftrace_entry_filter, limit)
-
-
-  @property
-  def session(self):
-    return self._session
-
-def insert_pending_entries(engine, kls, lst):
-  if len(lst) > 0:
-    # for some reason, it tries to generate an empty INSERT statement with len=0,
-    # which of course violates the first non-null constraint.
-    try:
-      # Performance-sensitive parsing according to:
-      # https://docs.sqlalchemy.org/en/13/faq/performance.html#i-m-inserting-400-000-rows-with-the-orm-and-it-s-really-slow
-      engine.execute(kls.__table__.insert(), lst)
-      lst.clear()
-    except sqlalchemy.exc.IntegrityError as err:
-      # possibly violating some SQL constraint, print data here.
-      print(err)
-      print(lst)
-      raise
-
-def parse_file(filename: str, *args, **kwargs) -> int:
-  # use explicit encoding to avoid UnicodeDecodeError.
-  with open(filename, encoding="ISO-8859-1") as f:
-    return parse_file_buf(f, *args, **kwargs)
-
-def parse_file_buf(filebuf, session, engine, raw_ftrace_entry_filter, limit=None) -> int:
-  global _FLUSH_LIMIT
-  count = 0
-  # count and id are not equal, because count still increases for invalid lines.
-  id = 0
-
-  pending_entries = []
-  pending_sched_switch = []
-  pending_sched_blocked_reasons = []
-  pending_mm_filemap_add_to_pagecaches = []
-
-  def insert_all_pending_entries():
-    insert_pending_entries(engine, RawFtraceEntry, pending_entries)
-    insert_pending_entries(engine, SchedSwitch, pending_sched_switch)
-    insert_pending_entries(engine, SchedBlockedReason, pending_sched_blocked_reasons)
-    insert_pending_entries(engine, MmFilemapAddToPageCache, pending_mm_filemap_add_to_pagecaches)
-
-  # for trace.html files produced by systrace,
-  # the actual ftrace is in the 'second' trace-data script class.
-  parsing_trace_data = 0
-  parsing_systrace_file = False
-
-  f = filebuf
-  for l in f:
-    if parsing_trace_data == 0 and l == "<!DOCTYPE html>\n":
-      parsing_systrace_file = True
-      continue
-    if parsing_trace_data != 2 and parsing_systrace_file:
-      if l == '  <script class="trace-data" type="application/text">\n':
-        parsing_trace_data = parsing_trace_data + 1
-      continue
-
-    if parsing_systrace_file and parsing_trace_data != 2:
-      continue
-    elif parsing_systrace_file and parsing_trace_data == 2 and l == "  </script>\n":
-      # the rest of this file is just random html
-      break
-
-    # now parsing the ftrace data.
-    if len(l) > 1 and l[0] == '#':
-      continue
-
-    count = count + 1
-
-    if limit and count >= limit:
-      break
-
-    raw_ftrace_entry = RawFtraceEntry.parse_dict(l)
-    if not raw_ftrace_entry:
-      print("WARNING: Failed to parse raw ftrace entry: " + l)
-      continue
-
-    if not raw_ftrace_entry_filter(raw_ftrace_entry):
-      # Skip processing raw ftrace entries that don't match a filter.
-      # This is an optimization for when Trace2Db is used programatically
-      # to avoid having an overly large database.
-      continue
-
-    pending_entries.append(raw_ftrace_entry)
-    id = id + 1
-
-    if raw_ftrace_entry['function'] == 'sched_switch':
-      sched_switch = SchedSwitch.parse_dict(raw_ftrace_entry['function_args'], id)
-
-      if not sched_switch:
-        print("WARNING: Failed to parse sched_switch: " + l)
-      else:
-        pending_sched_switch.append(sched_switch)
-
-    elif raw_ftrace_entry['function'] == 'sched_blocked_reason':
-      sbr = SchedBlockedReason.parse_dict(raw_ftrace_entry['function_args'], id)
-
-      if not sbr:
-        print("WARNING: Failed to parse sched_blocked_reason: " + l)
-      else:
-        pending_sched_blocked_reasons.append(sbr)
-
-    elif raw_ftrace_entry['function'] == 'mm_filemap_add_to_page_cache':
-      d = MmFilemapAddToPageCache.parse_dict(raw_ftrace_entry['function_args'],
-                                             id)
-      if not d:
-        print("WARNING: Failed to parse mm_filemap_add_to_page_cache: " + l)
-      else:
-        pending_mm_filemap_add_to_pagecaches.append(d)
-
-    # Objects are cached in python memory, not yet sent to SQL database.
-
-    # Send INSERT/UPDATE/etc statements to the underlying SQL database.
-    if count % _FLUSH_LIMIT == 0:
-      insert_all_pending_entries()
-
-  insert_all_pending_entries()
-
-  # Ensure underlying database commits changes from memory to disk.
-  session.commit()
-
-  return count
diff --git a/startop/scripts/trace_analyzer/lib/trace2db_test.py b/startop/scripts/trace_analyzer/lib/trace2db_test.py
deleted file mode 100755
index 3b326f0..0000000
--- a/startop/scripts/trace_analyzer/lib/trace2db_test.py
+++ /dev/null
@@ -1,222 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for inode2filename module.
-
-Install:
-  $> sudo apt-get install python3-pytest   ##  OR
-  $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
-  $> ./inode2filename_test.py
-  $> pytest inode2filename_test.py
-  $> python -m pytest inode2filename_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-import io
-from copy import deepcopy
-
-# pip imports
-# local imports
-from trace2db import *
-
-# This pretty-prints the raw dictionary of the sqlalchemy object if it fails.
-class EqualsSqlAlchemyObject:
-  # For convenience to write shorter tests, we also add 'ignore_fields' which allow us to specify
-  # which fields to ignore when doing the comparison.
-  def __init__(self_, self, ignore_fields=[]):
-    self_.self = self
-    self_.ignore_fields = ignore_fields
-
-  # Do field-by-field comparison.
-  # It seems that SQLAlchemy does not implement __eq__ itself so we have to do it ourselves.
-  def __eq__(self_, other):
-    if isinstance(other, EqualsSqlAlchemyObject):
-      other = other.self
-
-    self = self_.self
-
-    classes_match = isinstance(other, self.__class__)
-    a, b = deepcopy(self.__dict__), deepcopy(other.__dict__)
-
-    #compare based on equality our attributes, ignoring SQLAlchemy internal stuff
-
-    a.pop('_sa_instance_state', None)
-    b.pop('_sa_instance_state', None)
-
-    for f in self_.ignore_fields:
-      a.pop(f, None)
-      b.pop(f, None)
-
-    attrs_match = (a == b)
-    return classes_match and attrs_match
-
-  def __repr__(self):
-    return repr(self.self.__dict__)
-
-
-def assert_eq_ignore_id(left, right):
-  # This pretty-prints the raw dictionary of the sqlalchemy object if it fails.
-  # It does field-by-field comparison, but ignores the 'id' field.
-  assert EqualsSqlAlchemyObject(left, ignore_fields=['id']) == EqualsSqlAlchemyObject(right)
-
-def parse_trace_file_to_db(*contents):
-  """
-  Make temporary in-memory sqlite3 database by parsing the string contents as a trace.
-
-  :return: Trace2Db instance
-  """
-  buf = io.StringIO()
-
-  for c in contents:
-    buf.write(c)
-    buf.write("\n")
-
-  buf.seek(0)
-
-  t2d = Trace2Db(":memory:")
-  t2d.parse_file_buf_into_db(buf)
-
-  buf.close()
-
-  return t2d
-
-def test_ftrace_mm_filemap_add_to_pagecache():
-  test_contents = """
-MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
-MediaStoreImpor-27212 (27176) [000] .... 16136.595920: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000048e2e156 pfn=677645 ofs=126976
-MediaStoreImpor-27212 (27176) [000] .... 16136.597793: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000051eabfb2 pfn=677644 ofs=122880
-MediaStoreImpor-27212 (27176) [000] .... 16136.597815: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000ce7cd606 pfn=677643 ofs=131072
-MediaStoreImpor-27212 (27176) [000] .... 16136.603732: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=000000008ffd3030 pfn=730119 ofs=186482688
-MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
-          <...>-27197 (-----) [002] .... 16136.613471: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000aca88a97 pfn=743346 ofs=241664
-          <...>-27197 (-----) [002] .... 16136.615979: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000351f2bc1 pfn=777799 ofs=106496
-          <...>-27224 (-----) [006] .... 16137.400090: mm_filemap_add_to_page_cache: dev 253:6 ino 712d page=000000006ff7ffdb pfn=754861 ofs=0
-          <...>-1396  (-----) [000] .... 16137.451660: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000ba0cbb34 pfn=769173 ofs=187191296
-          <...>-1396  (-----) [000] .... 16137.453020: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000f6ef038e pfn=820291 ofs=0
-          <...>-1396  (-----) [000] .... 16137.453067: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000083ebc446 pfn=956463 ofs=4096
-          <...>-1396  (-----) [000] .... 16137.453101: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009dc2cd25 pfn=822813 ofs=8192
-          <...>-1396  (-----) [000] .... 16137.453113: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000a11167fb pfn=928650 ofs=12288
-          <...>-1396  (-----) [000] .... 16137.453126: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000c1c3311b pfn=621110 ofs=16384
-          <...>-1396  (-----) [000] .... 16137.453139: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000009aa78342 pfn=689370 ofs=20480
-          <...>-1396  (-----) [000] .... 16137.453151: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=0000000082cddcd6 pfn=755584 ofs=24576
-          <...>-1396  (-----) [000] .... 16137.453162: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=00000000b0249bc7 pfn=691431 ofs=28672
-          <...>-1396  (-----) [000] .... 16137.453183: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000006a776ff0 pfn=795084 ofs=32768
-          <...>-1396  (-----) [000] .... 16137.453203: mm_filemap_add_to_page_cache: dev 253:6 ino b285 page=000000001a4918a7 pfn=806998 ofs=36864
-          <...>-2578  (-----) [002] .... 16137.561871: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=187015168
-          <...>-2578  (-----) [002] .... 16137.562846: mm_filemap_add_to_page_cache: dev 253:6 ino b25a page=000000002f6ba74f pfn=864982 ofs=0
-          <...>-2578  (-----) [000] .... 16138.104500: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000f888d0f6 pfn=805812 ofs=192794624
-          <...>-2578  (-----) [000] .... 16138.105836: mm_filemap_add_to_page_cache: dev 253:6 ino b7dd page=000000003749523b pfn=977196 ofs=0
-          <...>-27215 (-----) [001] .... 16138.256881: mm_filemap_add_to_page_cache: dev 253:6 ino 758f page=000000001b375de1 pfn=755928 ofs=0
-          <...>-27215 (-----) [001] .... 16138.257526: mm_filemap_add_to_page_cache: dev 253:6 ino 7591 page=000000004e039481 pfn=841534 ofs=0
- NonUserFacing6-5246  ( 1322) [005] .... 16138.356491: mm_filemap_add_to_page_cache: dev 253:6 ino 1 page=00000000d65af9d2 pfn=719246 ofs=161890304
- NonUserFacing6-5246  ( 1322) [005] .... 16138.357538: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000002f6ba74f pfn=864982 ofs=0
- NonUserFacing6-5246  ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
-          <...>-27197 (-----) [005] .... 16140.143224: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=00000000a42527c6 pfn=1076669 ofs=32768
-  """
-
-  t2d = parse_trace_file_to_db(test_contents)
-  session = t2d.session
-
-  first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first()
-
-  #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
-  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
-      ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row)
-
-  second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first()
-
-  # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
-  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
-      ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
-
-def test_systrace_mm_filemap_add_to_pagecache():
-  test_contents = """
-<!DOCTYPE html>
-<html>
-<head i18n-values="dir:textdirection;">
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<meta charset="utf-8"/>
-<title>Android System Trace</title>
-  <script class="trace-data" type="application/text">
-PROCESS DUMP
-USER           PID  PPID     VSZ    RSS WCHAN  PC S NAME                        COMM
-root             1     0   62148   5976 0       0 S init                        [init]
-root             2     0       0      0 0       0 S [kthreadd]                  [kthreadd]
-  </script>
-
-  <script class="trace-data" type="application/text">
-MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
-NonUserFacing6-5246  ( 1322) [005] .... 16138.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
-  </script>
-
-  <script class="trace-data" type="application/text">
-{"traceEvents": [{"category": "process_argv", "name": "process_argv", "args": {"argv": ["/mnt/ssd3/workspace/master/external/chromium-trace/systrace.py", "-t", "5", "pagecache"]}, "pid": 160383, "ts": 1037300940509.7991, "tid": 139628672526080, "ph": "M"}, {"category": "python", "name": "clock_sync", "args": {"issue_ts": 1037307346185.212, "sync_id": "9a7e4fe3-89ad-441f-8226-8fe533fe973e"}, "pid": 160383, "ts": 1037307351643.906, "tid": 139628726089536, "ph": "c"}], "metadata": {"clock-domain": "SYSTRACE"}}
-  </script>
-<!-- END TRACE -->
-  """
-
-  t2d = parse_trace_file_to_db(test_contents)
-  session = t2d.session
-
-  first_row = session.query(MmFilemapAddToPageCache).order_by(MmFilemapAddToPageCache.id).first()
-
-  #dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
-  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
-      ino=0x7580, page=0x0000000060e990c7, pfn=677646, ofs=159744), first_row)
-
-  second_to_last_row = session.query(MmFilemapAddToPageCache).filter(MmFilemapAddToPageCache.page.in_([0x000000006e0f8322])).first()
-
-  # dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
-  assert_eq_ignore_id(MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
-      ino=0x9a64, page=0x000000006e0f8322, pfn=797894, ofs=4096), second_to_last_row)
-
-def test_timestamp_filter():
-  test_contents = """
-    MediaStoreImpor-27212 (27176) [000] .... 16136.595194: mm_filemap_add_to_page_cache: dev 253:6 ino 7580 page=0000000060e990c7 pfn=677646 ofs=159744
-    NonUserFacing6-5246  ( 1322) [005] .... 16139.357581: mm_filemap_add_to_page_cache: dev 253:6 ino 9a64 page=000000006e0f8322 pfn=797894 ofs=4096
-    MediaStoreImpor-27212 (27176) [000] .... 16136.604126: mm_filemap_add_to_page_cache: dev 253:6 ino b1d8 page=0000000098d4d2e2 pfn=829676 ofs=0
-  """
-
-  t2d = parse_trace_file_to_db(test_contents)
-  session = t2d.session
-
-  end_time = 16137.0
-
-  results = session.query(MmFilemapAddToPageCache).join(
-      MmFilemapAddToPageCache.raw_ftrace_entry).filter(
-      RawFtraceEntry.timestamp <= end_time).order_by(
-      MmFilemapAddToPageCache.id).all()
-
-  assert len(results) == 2
-  assert_eq_ignore_id(
-      MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
-                              ino=0x7580, page=0x0000000060e990c7, pfn=677646,
-                              ofs=159744), results[0])
-  assert_eq_ignore_id(
-      MmFilemapAddToPageCache(dev=64774, dev_major=253, dev_minor=6,
-                              ino=0xb1d8, page=0x0000000098d4d2e2, pfn=829676,
-                              ofs=0), results[1])
-
-
-if __name__ == '__main__':
-  pytest.main()
diff --git a/startop/scripts/trace_analyzer/queries_all.sql b/startop/scripts/trace_analyzer/queries_all.sql
deleted file mode 100644
index 41d1c08..0000000
--- a/startop/scripts/trace_analyzer/queries_all.sql
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
--- filter for atrace writes
-CREATE VIEW IF NOT EXISTS tracing_mark_writes AS
-    SELECT *
-      FROM raw_ftrace_entries
-     WHERE function = 'tracing_mark_write';
-
--- split the tracing_mark_write function args by ||s
-DROP TABLE IF exists tracing_mark_write_split_array;
-
-CREATE TABLE tracing_mark_write_split_array (
-    predictorset_id INT REFERENCES raw_ftrace_entries (id),
-    predictor_name,
-    rest,
-    gen,
-    
-    UNIQUE(predictorset_id, gen) -- drops redundant inserts into table
-);
-
-CREATE INDEX "tracing_mark_write_split_array_id" ON tracing_mark_write_split_array (
-    predictorset_id COLLATE BINARY COLLATE BINARY
-);
-
-INSERT INTO tracing_mark_write_split_array
-  WITH 
-    split(predictorset_id, predictor_name, rest, gen) AS (
-      -- split by |
-      SELECT id, '', function_args || '|', 0 FROM tracing_mark_writes WHERE id
-       UNION ALL
-      SELECT predictorset_id, 
-             substr(rest, 0, instr(rest, '|')),
-             substr(rest, instr(rest, '|')+1),
-             gen + 1
-        FROM split
-       WHERE rest <> ''),
-     split_results AS (
-       SELECT * FROM split WHERE predictor_name <> ''
-     )
-  SELECT * from split_results
-;
-
-
diff --git a/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql b/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql
deleted file mode 100644
index c28475e..0000000
--- a/startop/scripts/trace_analyzer/queries_app_launch_spans_with_name.sql
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
--- use the 'launching: $process_name' async slice to figure out launch duration.
-DROP VIEW IF EXISTS launch_durations_named;
-
-CREATE VIEW launch_durations_named AS
-WITH
-    launch_traces_raw AS (
-        SELECT *
-        FROM tracing_mark_write_split AS tmw,
-             raw_ftrace_entries AS rfe
-        WHERE atrace_message LIKE 'launching: %' AND rfe.id = tmw.raw_ftrace_entry_id
-    ),
-    launch_traces_joined AS (
-        SELECT started.timestamp AS started_timestamp,
-               finished.timestamp AS finished_timestamp,
-               started.id AS started_id,
-               finished.id AS finished_id,
-               SUBSTR(started.atrace_message, 12) AS proc_name   -- crop out "launching: " from the string.
-        FROM launch_traces_raw AS started,
-             launch_traces_raw AS finished
-        -- async slices ('S' -> 'F') have matching counters given the same PID.
-        WHERE started.atrace_type == 'S'
-              AND finished.atrace_type == 'F'
-              AND started.atrace_count == finished.atrace_count
-              AND started.atrace_pid == finished.atrace_pid
-    )
-SELECT * from launch_traces_joined;
-
-SELECT * FROM launch_durations_named;
diff --git a/startop/scripts/trace_analyzer/queries_block_launch.sql b/startop/scripts/trace_analyzer/queries_block_launch.sql
deleted file mode 100644
index 34e5f03..0000000
--- a/startop/scripts/trace_analyzer/queries_block_launch.sql
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-DROP VIEW IF EXISTS blocked_iowait_for_app_launches;
-
-CREATE VIEW blocked_iowait_for_app_launches AS
-WITH
-    block_launch_join AS (
-        SELECT *
-        FROM blocking_durations AS bd,
-             launch_durations_named AS ld
-        WHERE bd.block_timestamp >= ld.started_timestamp
-              AND bd.unblock_timestamp <= ld.finished_timestamp
-    ),
-    blocked_ui_threads AS (
-        SELECT *
-        FROM start_process_ui_threads AS sp,
-             block_launch_join AS blj
-        WHERE sp.atm_ui_thread_tid == unblock_pid
-              AND sp.process_name = blj.proc_name
-    ),
-    summed_raw AS (
-        SELECT SUM(unblock_timestamp-block_timestamp)*1000 AS sum_block_duration_ms,
-               *
-        FROM blocked_ui_threads
-        GROUP BY unblock_pid
-    ),
-    summed_neat AS (
-        SELECT sum_block_duration_ms AS blocked_iowait_duration_ms,
-               process_name,
-               (finished_timestamp - started_timestamp) * 1000 AS launching_duration_ms,
-               started_timestamp * 1000 AS launching_started_timestamp_ms,
-               finished_timestamp * 1000 AS launching_finished_timestamp_ms
-                -- filter out the rest because its just selecting 1 arbitrary row (due to the SUM aggregate).,
-        FROM summed_raw
-    )
-SELECT * FROM summed_neat;
-
-SELECT * FROM blocked_iowait_for_app_launches;
diff --git a/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql b/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql
deleted file mode 100644
index 788d0da..0000000
--- a/startop/scripts/trace_analyzer/queries_find_sched_switch_unblocked.sql
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-DROP VIEW IF EXISTS sched_switch_iowaits_pre;
-
--- scan for the closest pair such that:
---                  sched_block_reason pid=$PID iowait=1 ...
---                  ...
---                  sched_switch next_pid=$PID
-CREATE VIEW sched_switch_iowaits_pre AS
-    SELECT MAX(sbr.id) AS blocked_id,
-           ss.id AS sched_switch_id,
-           pid,         -- iow.pid
-           iowait,      -- iowait=0 or iowait=1
-           caller,
-           sbr_f.timestamp AS blocked_timestamp,
-           ss_f.timestamp AS sched_switch_timestamp,
-           next_comm,   -- name of next_pid
-           next_pid     -- same as iow.pid
-    FROM sched_blocked_reasons AS sbr,
-         raw_ftrace_entries AS sbr_f,
-         sched_switches AS ss,
-         raw_ftrace_entries AS ss_f
-    WHERE sbr_f.id == sbr.id
-          AND ss_f.id == ss.id
-          AND sbr.pid == ss.next_pid
-          AND sbr.iowait = 1
-          AND sbr_f.timestamp < ss_f.timestamp     -- ensures the 'closest' sched_blocked_reason is selected.
-    GROUP BY ss.id
-;
-
-DROP VIEW IF EXISTS sched_switch_iowaits;
-
-CREATE VIEW sched_switch_iowaits AS
-    SELECT *, MIN(sched_switch_timestamp) AS ss_timestamp      -- drop all of the 'too large' sched_switch entries except the closest one.
-    FROM sched_switch_iowaits_pre
-    GROUP BY blocked_id;
-
-SELECT * FROM sched_switch_iowaits;
-
--- use a real table here instead of a view, otherwise SQLiteStudio segfaults for some reason.
-DROP TABLE IF EXISTS blocking_durations;
-
-CREATE TABLE blocking_durations AS
-WITH
-    blocking_durations_raw AS (
-        SELECT MAX(ss.id) AS block_id,
-               ssf.timestamp AS block_timestamp,
-               iow.sched_switch_timestamp AS unblock_timestamp,
-               ss.prev_comm as block_prev_comm,
-               iow.next_comm AS unblock_next_comm,
-               ss.prev_state AS block_prev_state,
-               iow.sched_switch_id AS unblock_id,
-               iow.pid AS unblock_pid,
-               iow.caller AS unblock_caller
-        FROM sched_switches AS ss,          -- this is the sched_switch that caused a block (in the future when it unblocks, the reason is iowait=1).
-             sched_switch_iowaits AS iow,    -- this is the sched_switch that removes the block (it is now running again).
-             raw_ftrace_entries AS ssf
-        WHERE ssf.id = ss.id AND ss.prev_pid == iow.next_pid AND ssf.timestamp < iow.sched_switch_timestamp
-        GROUP BY unblock_timestamp 
-    ),
-    blocking_durations_tmp AS (
-        SELECT block_id,
-               unblock_timestamp,
-               block_timestamp,
-               block_prev_comm as comm,
-               block_prev_state as block_state,
-               unblock_id,
-               unblock_pid,
-               unblock_caller
-        FROM blocking_durations_raw
-    )
-    SELECT * FROM blocking_durations_tmp;-- ORDER BY block_id ASC;
-    --SELECT SUM(block_duration_ms) AS sum, * FROM blocking_durations GROUP BY unblock_pid ORDER BY sum DESC;
-
-DROP INDEX IF EXISTS "blocking_durations_block_timestamp";
-
-CREATE INDEX "blocking_durations_block_timestamp" ON blocking_durations (
-    block_timestamp COLLATE BINARY COLLATE BINARY
-);
-
-DROP INDEX IF EXISTS "blocking_durations_unblock_timestamp";
-
-CREATE INDEX "blocking_durations_unblock_timestamp" ON blocking_durations (
-    unblock_timestamp COLLATE BINARY COLLATE BINARY
-);
-
-SELECT * FROM blocking_durations;
diff --git a/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql b/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql
deleted file mode 100644
index 0c166b0..0000000
--- a/startop/scripts/trace_analyzer/queries_get_comm_and_pids.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-DROP VIEW IF EXISTS sched_switch_next_comm_pids;
-
-CREATE VIEW IF NOT EXISTS sched_switch_next_comm_pids AS
-
--- TODO: switch to using sched_switches table.
-
-WITH
-    sched_switchs AS (
-        SELECT * FROM raw_ftrace_entries WHERE function = 'sched_switch' AND function_args LIKE '% next_pid=%' AND function_args NOT LIKE '% next_comm=main %'
-    ),
-    comm_and_pids_raws AS (
-        SELECT id,
-               SUBSTR(function_args, instr(function_args, "next_comm="), instr(function_args, "next_pid=") - instr(function_args, "next_comm=")) AS next_comm_raw,
-               SUBSTR(function_args, instr(function_args, "next_pid="), instr(function_args, "next_prio=") - instr(function_args, "next_pid=")) AS next_pid_raw
-        FROM sched_switchs
-    ),
-    comm_and_pids AS (
-        SELECT id,
-               id AS raw_ftrace_entry_id,
-               TRIM(SUBSTR(next_pid_raw, 10)) AS next_pid, -- len("next_pid=") is 10
-               TRIM(SUBSTR(next_comm_raw, 11)) AS next_comm -- len("next_comm=") is 11
-        FROM comm_and_pids_raws
-    )
-SELECT * from comm_and_pids;
-
-SELECT * from sched_switch_next_comm_pids;
diff --git a/startop/scripts/trace_analyzer/queries_get_procs.sql b/startop/scripts/trace_analyzer/queries_get_procs.sql
deleted file mode 100644
index 06871c6..0000000
--- a/startop/scripts/trace_analyzer/queries_get_procs.sql
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-DROP VIEW IF EXISTS start_procs;
-
-CREATE VIEW IF NOT EXISTS start_procs AS
-WITH
-  start_procs_raw AS (
-      SELECT * from tracing_mark_write_split WHERE atrace_message LIKE 'Start proc: %'
-  ),
-  start_procs_substr AS (
-      -- note: "12" is len("Start proc: ")+1. sqlite indices start at 1.
-      SELECT raw_ftrace_entry_id, atrace_pid, SUBSTR(atrace_message, 13) AS process_name FROM start_procs_raw
-  )
-SELECT * from start_procs_substr;
-
-SELECT * from start_procs;
diff --git a/startop/scripts/trace_analyzer/queries_get_ui_threads.sql b/startop/scripts/trace_analyzer/queries_get_ui_threads.sql
deleted file mode 100644
index 876e50e..0000000
--- a/startop/scripts/trace_analyzer/queries_get_ui_threads.sql
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
--- note: These queries do comparisons based on raw_ftrace_entries.id by treating it as if it was equivalent to the temporal timestamp.
--- in practice, the ID of raw_ftrace_entries is based on its order in the ftrace buffer [and on the same cpu its equivalent].
--- we can always resort raw_ftrace_entries to ensure id order matches timestamp order. We should rarely need to compare by timestamp directly.
--- accessing 'floats' is inferior as they are harder to index, and will result in slower queries.
---
--- Naming convention note: '_fid' corresponds to 'raw_ftrace_entry.id'.
-DROP VIEW IF EXISTS start_process_ui_threads;
-
--- Map of started process names to their UI thread's TID (as returned by gettid).
-CREATE VIEW IF NOT EXISTS start_process_ui_threads AS
-WITH
-  start_proc_tids AS (
-    SELECT sp.raw_ftrace_entry_id AS start_proc_fid,
-           sp.atrace_pid AS atrace_pid,
-           sp.process_name AS process_name,
-           --MIN(nc.raw_ftrace_entry_id) as next_comm_fid,
-           nc.raw_ftrace_entry_id AS next_comm_fid,
-           nc.next_pid as next_pid,
-           nc.next_comm as next_comm,
-           SUBSTR(sp.process_name, -15) AS cut      -- why -15? See TASK_MAX in kernel, the sched_switch name is truncated to 16 bytes.
-    FROM start_procs AS sp,
-         sched_switch_next_comm_pids AS nc
-    WHERE sp.process_name LIKE '%' || nc.next_comm  -- kernel truncates the sched_switch::next_comm event, so we must match the prefix of the full name.
-    --WHERE SUBSTR(sp.process_name, -16) == nc.next_comm
-    --WHERE cut == nc.next_comm
-  ),
-  start_proc_tids_filtered AS (
-      SELECT *
-      FROM start_proc_tids
-      WHERE next_comm_fid > start_proc_fid        -- safeguard that avoids choosing "earlier" sched_switch before process was even started.
-      --ORDER BY start_proc_fid, next_comm_fid
-  ),
-  start_proc_all_threads AS (
-    SELECT DISTINCT
-        start_proc_fid, -- this is the ftrace entry of the system server 'Start proc: $process_name'. only need this to join for timestamp.
-        process_name,               -- this is the '$process_name' from the system server entry.
-        -- next up we have all the possible thread IDs as parsed from sched_switch that corresponds most closest to the start proc.
-        next_pid AS ui_thread_tpid, -- sched_switch.next_pid. This can be any of the threads in that process, it's not necessarily the main UI thread yet.
-        next_comm,
-        MIN(next_comm_fid) AS next_comm_fid   -- don't pick the 'later' next_comm_fid because it could correspond to another app start.
-    FROM start_proc_tids_filtered
-    GROUP BY start_proc_fid, ui_thread_tpid
-  ),
-  activity_thread_mains AS (
-    SELECT * FROM tracing_mark_write_split WHERE atrace_message = 'ActivityThreadMain'
-  ),
-  start_proc_ui_threads AS (
-    SELECT start_proc_fid,
-           process_name,
-           ui_thread_tpid,
-           next_comm,
-           next_comm_fid,
-           atm.raw_ftrace_entry_id as atm_fid,
-           atm.atrace_pid as atm_ui_thread_tid
-    FROM start_proc_all_threads AS spt, 
-         activity_thread_mains AS atm
-    WHERE atm.atrace_pid == spt.ui_thread_tpid AND atm.raw_ftrace_entry_id > spt.start_proc_fid -- Ensure we ignore earlier ActivityThreadMains prior to their Start proc.
-  ),
-  start_proc_ui_threads_filtered AS (
-    SELECT start_proc_fid,
-           process_name,                -- e.g. 'com.android.settings'
-           --ui_thread_tpid,
-           --next_comm,
-           --next_comm_fid,
-           MIN(atm_fid) AS atm_fid,
-           atm_ui_thread_tid            -- equivalent to gettid() for the process's UI thread.
-    FROM start_proc_ui_threads
-    GROUP BY start_proc_fid, atm_ui_thread_tid    -- find the temporally closest ActivityTaskMain to a "Start proc: $process_name"
-  )
-SELECT * FROM start_proc_ui_threads_filtered;
-
-SELECT * FROM start_process_ui_threads;
diff --git a/startop/scripts/trace_analyzer/queries_mark_write_join.sql b/startop/scripts/trace_analyzer/queries_mark_write_join.sql
deleted file mode 100644
index 100f0740..0000000
--- a/startop/scripts/trace_analyzer/queries_mark_write_join.sql
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-DROP TABLE IF EXISTS tracing_mark_write_split;
-
-CREATE TABLE tracing_mark_write_split (
-    raw_ftrace_entry_id INT REFERENCES raw_ftrace_entries (id),
-    atrace_type CHAR(1), -- only null for the first 2 sync timers. usually 'B', 'C', E', ...
-    atrace_pid INT,      -- only null for first 2 sync timers
-    atrace_message,      -- usually null for type='E' etc.
-    atrace_count,        -- usually non-null only for 'C'
-
-    UNIQUE(raw_ftrace_entry_id) -- drops redundant inserts into table
-);
-
-INSERT INTO tracing_mark_write_split
-WITH
-    pivoted AS (
-        SELECT tx.predictorset_id,
-               --ty.predictorset_id,
-               --tz.predictorset_id,
-               --tzz.predictorset_id,
-               tx.predictor_name AS atrace_type,
-               CAST(ty.predictor_name  AS integer) AS atrace_pid,
-               tz.predictor_name AS atrace_message,
-               CAST(tzz.predictor_name AS integer) AS atrace_count
-        FROM (SELECT * from tracing_mark_write_split_array WHERE gen = 1) AS tx
-        LEFT JOIN
-             (SELECT * FROM tracing_mark_write_split_array WHERE gen = 2) AS ty
-        ON tx.predictorset_id = ty.predictorset_id
-        LEFT JOIN
-             (SELECT * FROM tracing_mark_write_split_array WHERE gen = 3) AS tz
-        ON tx.predictorset_id = tz.predictorset_id
-        LEFT JOIN
-             (SELECT * FROM tracing_mark_write_split_array WHERE gen = 4) AS tzz
-        ON tx.predictorset_id = tzz.predictorset_id
-    )
-SELECT * from pivoted ORDER BY predictorset_id;-- LIMIT 100;
-
-SELECT * FROM tracing_mark_write_split;
diff --git a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql b/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql
deleted file mode 100644
index bf5e3cc..0000000
--- a/startop/scripts/trace_analyzer/queries_pretty_print_block_launch.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-.headers on
-.mode quote
-
-SELECT * FROM blocked_iowait_for_app_launches;
-
-/*
-Output as CSV example:
-
-'blocked_iowait_duration_ms','process_name','launching_duration_ms','launching_started_timestamp_ms','launching_finished_timestamp_ms'
-125.33199995596078224,'com.android.settings',1022.4840000009862706,17149896.822000000626,17150919.305999998003
-
-*/
diff --git a/startop/scripts/trace_analyzer/run-sql-queries b/startop/scripts/trace_analyzer/run-sql-queries
deleted file mode 100755
index 61a0ad4..0000000
--- a/startop/scripts/trace_analyzer/run-sql-queries
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$(dirname "$0")" ; pwd -P )"
-
-if [[ $# -lt 1 ]]; then
-  echo "Usage: $0 <db-file>"
-fi
-
-DB_TARGET=$1
-
-if ! [[ -f $DB_TARGET ]]; then
-  echo "ERROR: File '$DB_TARGET' does not exist." >&2
-  exit 1
-fi
-
-exec_sql_file() {
-  local filename="$1"
-  if ! [[ -f $filename ]]; then
-    echo "ERROR: Can't exec SQL file, '$filename' does not exist." >&2
-    return 1
-  fi
-
-  sqlite3 "$DB_TARGET" < "$DIR"/"$filename"
-}
-
-exec_sql_file_quiet() {
-  exec_sql_file "$@" > /dev/null
-}
-
-# Some views/tables need other views already created, so order does matter.
-# x -> y , means x depends on y.
-
-# View: tracing_mark_writes
-# Table: tracing_mark_write_split_array -> tracing_mark_writes
-exec_sql_file_quiet "queries_all.sql"
-
-# Table: tracing_mark_write_split -> tracing_mark_write_split_array
-exec_sql_file_quiet "queries_mark_write_join.sql"
-
-# View: start_procs -> tracing_mark_write_split
-exec_sql_file_quiet "queries_get_procs.sql"
-
-# View: sched_switch_next_comm_pids
-exec_sql_file_quiet "queries_get_comm_and_pids.sql"
-
-# View: start_process_ui_threads -> start_procs, sched_switch_next_comm_pids
-exec_sql_file_quiet "queries_get_ui_threads.sql"
-
-# View: launch_durations_named -> tracing_mark_write_split
-exec_sql_file_quiet "queries_app_launch_spans_with_name.sql"
-
-# View: sched_switch_iowaits_pre
-# View: sched_switch_iowaits -> sched_switch_iowaits_pre
-# Table: blocking_durations -> sched_switch_iowaits
-exec_sql_file_quiet "queries_find_sched_switch_unblocked.sql"
-
-# View: blocked_iowait_for_app_launches -> launch_durations_named, blocking_durations
-exec_sql_file_quiet "queries_block_launch.sql"
-
-#####
-#####
-#####
-
-# Final queries
-
-exec_sql_file "queries_pretty_print_block_launch.sql"
diff --git a/startop/scripts/trace_analyzer/test_fixtures/common_systrace b/startop/scripts/trace_analyzer/test_fixtures/common_systrace
deleted file mode 100644
index 802cb55..0000000
--- a/startop/scripts/trace_analyzer/test_fixtures/common_systrace
+++ /dev/null
@@ -1,518 +0,0 @@
-# tracer: nop
-#
-# entries-in-buffer/entries-written: 411983/411983   #P:8
-#
-#                                      _-----=> irqs-off
-#                                     / _----=> need-resched
-#                                    | / _---=> hardirq/softirq
-#                                    || / _--=> preempt-depth
-#                                    ||| /     delay
-#           TASK-PID    TGID   CPU#  ||||    TIMESTAMP  FUNCTION
-#              | |        |      |   ||||       |         |
-           <...>-14603 (-----) [000] ...1 14592.893157: tracing_mark_write: trace_event_clock_sync: parent_ts=14592.892578
-           <...>-14603 (-----) [000] ...1 14592.893172: tracing_mark_write: trace_event_clock_sync: realtime_ts=1557129597951
-           <...>-18150 (-----) [004] d..2 14594.182110: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:16 next_pid=23269 next_prio=120
-  kworker/u16:16-23269 (23269) [004] d.h3 14594.182228: sched_blocked_reason: pid=18150 iowait=0 caller=a6xx_oob_set+0x194/0x3dc
-  kworker/u16:16-23269 (23269) [004] d..2 14594.182248: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.182312: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.182488: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
-  kworker/u16:16-23269 (23269) [005] d..2 14594.182610: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.182626: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.182755: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.182975: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.183209: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.183371: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=D ==> next_comm=swapper/4 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.184286: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
-  kworker/u16:16-23269 (23269) [005] d..2 14594.184495: sched_switch: prev_comm=kworker/u16:16 prev_pid=23269 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
-           <...>-18150 (-----) [004] d..2 14594.184498: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
-     ksoftirqd/4-47    (   47) [004] d..2 14594.185678: sched_switch: prev_comm=ksoftirqd/4 prev_pid=47 prev_prio=120 prev_state=S ==> next_comm=swapper/4 next_pid=0 next_prio=120
-     kworker/6:2-10610 (10610) [006] d..2 14594.186012: sched_switch: prev_comm=kworker/6:2 prev_pid=10610 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
-           <...>-656   (-----) [001] .... 14594.219464: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
-           <...>-1803  (-----) [000] d..2 14594.219595: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-           <...>-3359  (-----) [001] ...1 14594.219856: tracing_mark_write: S|1368|launching: com.google.android.dialer|0
-           <...>-3359  (-----) [001] ...1 14594.219863: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunched
-           <...>-3359  (-----) [001] ...1 14594.219869: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
-           <...>-1398  (-----) [006] ...1 14594.220160: tracing_mark_write: B|1368|updateInputWindows
-           <...>-3359  (-----) [001] .... 14594.220230: binder_set_priority: proc=1368 thread=3359 old=110 => new=120 desired=120
-           <...>-1398  (-----) [006] ...1 14594.220588: tracing_mark_write: B|1368|android.os.Handler: com.android.server.wm.AppWindowToken$1
-           <...>-1398  (-----) [006] ...1 14594.220722: tracing_mark_write: B|1368|ResourcesManager#getResources
-           <...>-1052  (-----) [002] d..2 14594.220884: sched_switch: prev_comm=statsd.writer prev_pid=1052 prev_prio=120 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
-           <...>-1398  (-----) [006] ...1 14594.220926: tracing_mark_write: B|1368|Theme::ApplyStyle
-           <...>-1398  (-----) [006] ...1 14594.220929: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-2007  (-----) [007] ...1 14594.220996: tracing_mark_write: B|2007|Choreographer#doFrame
-           <...>-2007  (-----) [007] ...1 14594.221005: tracing_mark_write: B|2007|animation
-           <...>-1398  (-----) [006] ...1 14594.221015: tracing_mark_write: B|1368|ResourcesManager#getResources
-           <...>-2045  (-----) [002] ...2 14594.221035: binder_set_priority: proc=1368 thread=1903 old=120 => new=118 desired=118
-           <...>-2045  (-----) [002] d..2 14594.221065: sched_switch: prev_comm=UiThreadHelper prev_pid=2045 prev_prio=118 prev_state=S ==> next_comm=Binder:1368_4 next_pid=1903 next_prio=118
-           <...>-1398  (-----) [006] ...1 14594.221080: tracing_mark_write: B|1368|AssetManager::SetApkAssets
-           <...>-2007  (-----) [007] ...1 14594.221110: tracing_mark_write: B|2007|traversal
-           <...>-656   (-----) [000] ...1 14594.221137: tracing_mark_write: B|625|requestNextVsync
-           <...>-656   (-----) [000] ...1 14594.221141: tracing_mark_write: B|625|resetIdleTimer
-           <...>-2007  (-----) [007] ...1 14594.221146: tracing_mark_write: B|2007|draw
-           <...>-2007  (-----) [007] ...1 14594.221160: tracing_mark_write: B|2007|Record View#draw()
-           <...>-660   (-----) [005] d..2 14594.221285: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
-           <...>-658   (-----) [004] d..2 14594.221327: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=android.display next_pid=1397 next_prio=117
-           <...>-2738  (-----) [005] ...1 14594.221342: tracing_mark_write: B|2007|notifyFramePending
-           <...>-2738  (-----) [005] ...1 14594.221362: tracing_mark_write: B|2007|DrawFrame
-           <...>-2738  (-----) [005] ...1 14594.221369: tracing_mark_write: B|2007|query
-           <...>-2007  (-----) [007] d..2 14594.221369: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
-           <...>-1903  (-----) [002] .... 14594.221397: binder_set_priority: proc=1368 thread=1903 old=118 => new=120 desired=120
-           <...>-2738  (-----) [005] ...2 14594.221400: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
-           <...>-2738  (-----) [005] d..2 14594.221430: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-1368  (-----) [003] ...1 14594.221431: tracing_mark_write: B|1368|Lock contention on GC thread flip lock (owner tid: 0)
-           <...>-656   (-----) [005] ...1 14594.221460: tracing_mark_write: B|625|query
-           <...>-656   (-----) [005] .... 14594.221528: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
-           <...>-2738  (-----) [007] ...1 14594.221552: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...2 14594.221563: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
-           <...>-2738  (-----) [007] d..2 14594.221600: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-1368  (-----) [003] d..2 14594.221623: sched_switch: prev_comm=system_server prev_pid=1368 prev_prio=118 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
-           <...>-656   (-----) [007] ...1 14594.221628: tracing_mark_write: B|625|query
-           <...>-23031 (-----) [001] d..2 14594.221643: sched_switch: prev_comm=UiAutomation prev_pid=23031 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-2738  (-----) [007] ...1 14594.221664: tracing_mark_write: B|2007|syncFrameState
-           <...>-2738  (-----) [007] ...1 14594.221697: tracing_mark_write: B|2007|prepareTree
-           <...>-23008 (-----) [005] d..2 14594.221706: sched_switch: prev_comm=hub.uiautomator prev_pid=23008 prev_prio=120 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
-           <...>-656   (-----) [000] .... 14594.221737: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
-           <...>-1803  (-----) [003] d..2 14594.221747: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
-           <...>-1397  (-----) [004] d..2 14594.221806: sched_switch: prev_comm=android.display prev_pid=1397 prev_prio=117 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
-           <...>-1398  (-----) [006] d..2 14594.221816: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=R ==> next_comm=s.nexuslauncher next_pid=2007 next_prio=110
-           <...>-2738  (-----) [007] ...1 14594.221824: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.221830: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.221834: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.221841: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.221843: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.221846: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.221850: tracing_mark_write: B|2007|dequeueBuffer
-           <...>-2738  (-----) [007] ...2 14594.221864: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
-           <...>-2738  (-----) [007] d..2 14594.221985: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=crtc_event:97 next_pid=303 next_prio=83
-           <...>-2007  (-----) [006] ...1 14594.221989: tracing_mark_write: B|2007|topResumedActivityChangeItem
-           <...>-303   (-----) [007] d..2 14594.222016: sched_switch: prev_comm=crtc_event:97 prev_pid=303 prev_prio=83 prev_state=S ==> next_comm=rcu_preempt next_pid=7 next_prio=120
-     rcu_preempt-7     (    7) [007] d..2 14594.222035: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
-     migration/4-46    (   46) [004] d..2 14594.222037: sched_switch: prev_comm=migration/4 prev_pid=46 prev_prio=0 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-2738  (-----) [007] d..2 14594.222039: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
-           <...>-656   (-----) [004] ...1 14594.222100: tracing_mark_write: B|625|dequeueBuffer
-           <...>-656   (-----) [004] ...1 14594.222114: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
-           <...>-2007  (-----) [006] ...2 14594.222131: binder_set_priority: proc=1368 thread=1903 old=120 => new=110 desired=110
-           <...>-2007  (-----) [006] d..2 14594.222143: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=UiThreadHelper next_pid=2045 next_prio=118
-           <...>-2613  (-----) [001] d..2 14594.222158: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-18150 (-----) [007] d..2 14594.222193: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
-           <...>-656   (-----) [004] .... 14594.222220: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
-           <...>-2738  (-----) [007] ...1 14594.222267: tracing_mark_write: B|2007|HWC release fence 36027 has signaled
-           <...>-656   (-----) [007] ...1 14594.223842: tracing_mark_write: B|625|queueBuffer
-           <...>-656   (-----) [007] ...1 14594.223845: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
-           <...>-656   (-----) [007] ...1 14594.223871: tracing_mark_write: B|625|requestNextVsync
-           <...>-656   (-----) [007] ...1 14594.223873: tracing_mark_write: B|625|resetIdleTimer
-           <...>-656   (-----) [007] ...1 14594.223881: tracing_mark_write: B|625|addAndGetFrameTimestamps
-           <...>-1395  (-----) [001] d..2 14594.223909: sched_switch: prev_comm=android.ui prev_pid=1395 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-2738  (-----) [007] ...1 14594.223959: tracing_mark_write: B|2007|Trace GPU completion fence 36027
-           <...>-11799 (-----) [006] ...1 14594.224006: tracing_mark_write: B|2007|waiting for GPU completion 36027
-           <...>-11799 (-----) [006] ...1 14594.224009: tracing_mark_write: B|2007|waitForever
-           <...>-2613  (-----) [004] d..2 14594.224014: sched_switch: prev_comm=ogle.android.as prev_pid=2613 prev_prio=120 prev_state=S ==> next_comm=Binder:1803_6 next_pid=2173 next_prio=120
-           <...>-11799 (-----) [006] d..1 14594.224014: fence_enable_signal: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78002
-           <...>-11799 (-----) [006] d..2 14594.224021: sched_switch: prev_comm=GPU completion prev_pid=11799 prev_prio=110 prev_state=S ==> next_comm=rcuop/6 next_pid=68 next_prio=120
-         rcuop/6-68    (   68) [006] d..2 14594.224044: sched_switch: prev_comm=rcuop/6 prev_pid=68 prev_prio=120 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
-           <...>-259   (-----) [006] d..2 14594.224132: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=Binder:2007_A next_pid=4180 next_prio=120
-           <...>-3206  (-----) [001] d..2 14594.224167: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=R ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
-    lowpool[847]-14589 ( 2446) [005] d..1 14594.224300: mm_filemap_delete_from_page_cache: dev 0:1 ino 3d0034 page=000000008247d586 pfn=676904 ofs=0
-           <...>-1803  (-----) [001] d..2 14594.224302: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=aiai-vc-0 next_pid=3206 next_prio=139
-           <...>-3206  (-----) [001] d..2 14594.224433: sched_switch: prev_comm=aiai-vc-0 prev_pid=3206 prev_prio=139 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-1903  (-----) [003] ...1 14594.224490: tracing_mark_write: B|1368|dispatchingStartProcess:com.google.android.dialer
-           <...>-1903  (-----) [003] ...1 14594.224659: tracing_mark_write: B|1368|wmLayout
-           <...>-1903  (-----) [003] ...1 14594.224666: tracing_mark_write: B|1368|performSurfacePlacement
-           <...>-1903  (-----) [003] ...1 14594.224683: tracing_mark_write: B|1368|applySurfaceChanges
-           <...>-1903  (-----) [003] ...1 14594.224688: tracing_mark_write: B|1368|openSurfaceTransaction
-           <...>-2738  (-----) [007] ...1 14594.224711: tracing_mark_write: B|2007|query
-           <...>-1903  (-----) [003] ...1 14594.224714: tracing_mark_write: B|1368|performLayout
-           <...>-2738  (-----) [007] ...1 14594.224714: tracing_mark_write: B|2007|query
-           <...>-1903  (-----) [003] ...1 14594.224723: tracing_mark_write: B|1368|applyPostLayoutPolicy
-           <...>-2738  (-----) [007] d..2 14594.224752: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-656   (-----) [007] .... 14594.224766: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
-           <...>-1398  (-----) [002] ...1 14594.224801: tracing_mark_write: B|1368|Theme::ApplyStyle
-           <...>-1398  (-----) [002] ...1 14594.224805: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224820: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224826: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224833: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224838: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224846: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224853: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224859: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-1398  (-----) [002] ...1 14594.224864: tracing_mark_write: B|1368|AssetManager::GetBag
-           <...>-18150 (-----) [006] d..2 14594.228407: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
-           <...>-2738  (-----) [007] d..2 14594.228411: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
-           <...>-1409  (-----) [004] ...1 14594.228417: tracing_mark_write: B|1368|Start proc: com.google.android.dialer
-           <...>-440   (-----) [006] d..2 14594.228418: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u16:18 next_pid=18150 next_prio=120
-           <...>-76    (-----) [007] d..2 14594.228430: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
-           <...>-440   (-----) [007] d..2 14594.228434: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/7:0H next_pid=76 next_prio=100
-           <...>-18150 (-----) [006] d..3 14594.228442: sched_blocked_reason: pid=1398 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
-           <...>-76    (-----) [007] d..2 14594.228442: sched_switch: prev_comm=kworker/7:0H prev_pid=76 prev_prio=100 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
-           <...>-2738  (-----) [007] ...2 14594.228446: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
-           <...>-18150 (-----) [006] d..2 14594.228447: sched_switch: prev_comm=kworker/u16:18 prev_pid=18150 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=110
-           <...>-2738  (-----) [007] d..2 14594.228479: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-1409  (-----) [004] d..2 14594.228499: sched_switch: prev_comm=ActivityManager prev_pid=1409 prev_prio=118 prev_state=D ==> next_comm=Binder:965_2 next_pid=1041 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.229271: tracing_mark_write: B|625|handleTransaction
-           <...>-1773  (-----) [004] .... 14594.229285: binder_set_priority: proc=625 thread=1773 old=110 => new=120 desired=120
-           <...>-440   (-----) [007] d..2 14594.229301: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
-           <...>-2738  (-----) [007] ...1 14594.229318: tracing_mark_write: B|2007|HWC release fence 36028 has signaled
-           <...>-2738  (-----) [007] ...1 14594.229331: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.229337: tracing_mark_write: B|2007|eglBeginFrame
-           <...>-2738  (-----) [007] ...1 14594.229352: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...1 14594.229354: tracing_mark_write: B|2007|query
-           <...>-791   (-----) [000] d..2 14594.229357: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.229440: tracing_mark_write: B|625|doTransaction
-           <...>-13916 (-----) [002] d..2 14594.229482: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=D|K ==> next_comm=swapper/2 next_pid=0 next_prio=120
-           <...>-13917 (-----) [001] d..2 14594.229492: sched_blocked_reason: pid=13916 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-625   (-----) [003] ...1 14594.229492: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229507: tracing_mark_write: B|625|doTransaction
-           <...>-13917 (-----) [001] d..2 14594.229523: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-13916 (-----) [002] d..2 14594.229535: sched_blocked_reason: pid=13917 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-625   (-----) [003] ...1 14594.229538: tracing_mark_write: B|625|doTransaction
-           <...>-2738  (-----) [007] ...1 14594.229543: tracing_mark_write: B|2007|flush commands
-           <...>-13916 (-----) [002] .... 14594.229562: sched_process_exit: comm=HeapTaskDaemon pid=13916 prio=124
-           <...>-625   (-----) [003] ...1 14594.229567: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229588: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229628: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229652: tracing_mark_write: B|625|doTransaction
-           <...>-13916 (-----) [002] d..2 14594.229676: sched_switch: prev_comm=HeapTaskDaemon prev_pid=13916 prev_prio=124 prev_state=x ==> next_comm=swapper/2 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.229676: tracing_mark_write: B|625|doTransaction
-           <...>-2007  (-----) [006] d..2 14594.229688: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.229703: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229725: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229750: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229772: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.229792: tracing_mark_write: B|625|doTransaction
-           <...>-791   (-----) [000] d..2 14594.229811: sched_switch: prev_comm=main prev_pid=791 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.229824: tracing_mark_write: B|625|doTransaction
-           <...>-2738  (-----) [007] ...1 14594.229827: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
-           <...>-13917 (-----) [001] d..2 14594.229836: sched_switch: prev_comm=ReferenceQueueD prev_pid=13917 prev_prio=124 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-2738  (-----) [007] ...1 14594.229837: tracing_mark_write: B|2007|setSurfaceDamage
-           <...>-625   (-----) [003] ...1 14594.229850: tracing_mark_write: B|625|doTransaction
-           <...>-13918 (-----) [002] d..2 14594.229856: sched_blocked_reason: pid=13917 iowait=0 caller=SyS_madvise+0xd34/0xd3c
-           <...>-5281  (-----) [001] d..2 14594.229932: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=D ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-89    (-----) [006] d..2 14594.229951: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.229982: tracing_mark_write: B|625|handleMessageInvalidate
-           <...>-625   (-----) [003] ...1 14594.229984: tracing_mark_write: B|625|handlePageFlip
-           <...>-625   (-----) [003] ...1 14594.230013: tracing_mark_write: B|625|latchBuffer
-           <...>-13917 (-----) [000] .... 14594.230015: sched_process_exit: comm=ReferenceQueueD pid=13917 prio=124
-           <...>-625   (-----) [003] ...1 14594.230020: tracing_mark_write: B|625|query
-           <...>-625   (-----) [003] ...1 14594.230028: tracing_mark_write: B|625|updateTexImage
-           <...>-625   (-----) [003] ...1 14594.230035: tracing_mark_write: B|625|acquireBuffer
-           <...>-625   (-----) [003] ...1 14594.230044: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
-           <...>-2738  (-----) [007] d..2 14594.230057: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=D ==> next_comm=smem_native_lpa next_pid=88 next_prio=120
-           <...>-14607 (-----) [000] d..2 14594.259609: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-2738  (-----) [005] d..2 14594.259620: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
-           <...>-1773  (-----) [005] ...1 14594.259649: tracing_mark_write: B|625|query
-           <...>-2738  (-----) [005] ...1 14594.259714: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] d..2 14594.259743: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
-           <...>-1773  (-----) [005] ...1 14594.259757: tracing_mark_write: B|625|query
-           <...>-2738  (-----) [005] ...1 14594.259810: tracing_mark_write: B|2007|syncFrameState
-           <...>-2738  (-----) [005] ...1 14594.259856: tracing_mark_write: B|2007|prepareTree
-  Binder:14607_1-14624 (14607) [002] ...1 14594.259863: tracing_mark_write: B|14607|AttachCurrentThread
-  Binder:14607_1-14624 (14607) [002] ...1 14594.259869: tracing_mark_write: B|14607|Thread::Attach
-  Binder:14607_1-14624 (14607) [002] ...1 14594.259873: tracing_mark_write: B|14607|Thread birth
-  Binder:14607_1-14624 (14607) [002] ...1 14594.259916: tracing_mark_write: B|14607|Thread::Init
-  Binder:14607_1-14624 (14607) [002] ...1 14594.259920: tracing_mark_write: B|14607|InitStackHwm
-           <...>-14607 (-----) [000] d..2 14594.259932: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_1-14624 (14607) [002] d..2 14594.259941: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-3198  (-----) [001] ...1 14594.259942: tracing_mark_write: B|2007|Update SurfaceView position
-  Binder:14607_1-14624 (14607) [002] ...1 14594.259963: tracing_mark_write: B|14607|InitTlsEntryPoints
-  Binder:14607_1-14624 (14607) [002] ...1 14594.259974: tracing_mark_write: B|14607|InitInterpreterTls
-           <...>-14607 (-----) [000] d..2 14594.260005: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-3198  (-----) [001] d..2 14594.260007: sched_switch: prev_comm=hwuiTask1 prev_pid=3198 prev_prio=118 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-14607 (-----) [000] d..2 14594.260024: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_1-14624 (14607) [002] d..2 14594.260038: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] d..2 14594.260064: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-  Binder:14607_1-14624 (14607) [002] ...1 14594.260101: tracing_mark_write: B|14607|ThreadList::Register
-           <...>-2738  (-----) [005] ...1 14594.260128: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260140: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260148: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260155: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260161: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260167: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260173: tracing_mark_write: B|2007|dequeueBuffer
-           <...>-2007  (-----) [001] d..2 14594.260201: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-2738  (-----) [005] d..2 14594.260214: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=120 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
-           <...>-1773  (-----) [005] ...1 14594.260236: tracing_mark_write: B|625|dequeueBuffer
-           <...>-1773  (-----) [005] ...1 14594.260249: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 2
-           <...>-14607 (-----) [000] d..2 14594.260334: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_1-14624 (14607) [002] d..2 14594.260343: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] d..2 14594.260376: sched_blocked_reason: pid=14624 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-14607 (-----) [000] d..2 14594.260387: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-           <...>-2738  (-----) [005] ...1 14594.260401: tracing_mark_write: B|2007|HWC release fence 36030 has signaled
-  Binder:14607_1-14624 (14607) [002] d..2 14594.260407: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-2738  (-----) [005] ...1 14594.260419: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260427: tracing_mark_write: B|2007|eglBeginFrame
-           <...>-2738  (-----) [005] ...1 14594.260445: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [005] ...1 14594.260450: tracing_mark_write: B|2007|query
-  Binder:14607_1-14624 (14607) [002] .... 14594.260472: task_newtask: pid=14625 comm=Binder:14607_1 clone_flags=3d0f00 oom_score_adj=-1000
-           <...>-14607 (-----) [000] d..2 14594.260517: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.260525: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] d..2 14594.260555: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-14607 (-----) [000] ...1 14594.260569: tracing_mark_write: B|14607|ActivityThreadMain
-           <...>-14607 (-----) [000] d..2 14594.260581: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.260588: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] d..2 14594.260611: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-14607 (-----) [000] d..2 14594.260623: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.260636: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] d..2 14594.260663: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-14607 (-----) [000] d..2 14594.260674: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.260694: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] d..2 14594.260724: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-2738  (-----) [005] ...1 14594.260734: tracing_mark_write: B|2007|flush commands
-           <...>-14607 (-----) [000] d..2 14594.260735: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.260753: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-  Binder:14607_2-14625 (14607) [001] ...1 14594.260925: tracing_mark_write: B|14607|AttachCurrentThread
-  Binder:14607_2-14625 (14607) [001] ...1 14594.260930: tracing_mark_write: B|14607|Thread::Attach
-  Binder:14607_2-14625 (14607) [001] ...1 14594.260933: tracing_mark_write: B|14607|Thread birth
-  Binder:14607_2-14625 (14607) [001] ...1 14594.260973: tracing_mark_write: B|14607|Thread::Init
-  Binder:14607_2-14625 (14607) [001] ...1 14594.260977: tracing_mark_write: B|14607|InitStackHwm
-           <...>-14607 (-----) [000] d..2 14594.260990: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.260998: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-  Binder:14607_2-14625 (14607) [001] ...1 14594.261023: tracing_mark_write: B|14607|InitTlsEntryPoints
-  Binder:14607_2-14625 (14607) [001] ...1 14594.261034: tracing_mark_write: B|14607|InitInterpreterTls
-           <...>-14607 (-----) [000] d..2 14594.261064: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-14607 (-----) [000] d..2 14594.261075: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.261094: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] d..2 14594.261120: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-14607 (-----) [000] d..2 14594.261132: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-  Binder:14607_2-14625 (14607) [001] d..2 14594.261146: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-  Binder:14607_2-14625 (14607) [001] ...1 14594.261167: tracing_mark_write: B|14607|ThreadList::Register
-           <...>-14607 (-----) [000] d..2 14594.261209: sched_blocked_reason: pid=14625 iowait=0 caller=__rwsem_down_write_failed_common+0x3e8/0x754
-           <...>-2738  (-----) [005] ...1 14594.261212: tracing_mark_write: B|2007|waitOnFences
-           <...>-14607 (-----) [000] d..2 14594.261220: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=120 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-           <...>-2738  (-----) [005] ...1 14594.261232: tracing_mark_write: B|2007|eglSwapBuffersWithDamageKHR
-           <...>-2738  (-----) [005] ...1 14594.261244: tracing_mark_write: B|2007|setSurfaceDamage
-  Binder:14607_2-14625 (14607) [001] d..2 14594.261246: sched_blocked_reason: pid=14607 iowait=0 caller=do_page_fault+0x550/0x5fc
-           <...>-14607 (-----) [000] ...1 14594.261326: tracing_mark_write: B|14607|VerifyClass com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
-           <...>-2738  (-----) [005] .... 14594.261621: fence_init: driver=kgsl-timeline timeline=kgsl-3d0_13-s.nexuslauncher(200 context=27 seqno=78005
-           <...>-625   (-----) [003] ...1 14594.263903: tracing_mark_write: B|625|resetIdleTimer
-           <...>-625   (-----) [003] ...1 14594.263912: tracing_mark_write: B|625|rebuildLayerStacks
-           <...>-625   (-----) [003] ...1 14594.263915: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
-           <...>-625   (-----) [003] ...1 14594.263919: tracing_mark_write: B|625|computeVisibleRegions
-           <...>-1398  (-----) [006] d..2 14594.263966: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=110 prev_state=S ==> next_comm=Binder:625_4 next_pid=1773 next_prio=120
-           <...>-1695  (-----) [001] d..2 14594.264086: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.264293: tracing_mark_write: B|625|calculateWorkingSet
-           <...>-625   (-----) [003] ...1 14594.264500: tracing_mark_write: B|625|prepare
-           <...>-625   (-----) [003] ...1 14594.264513: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
-           <...>-625   (-----) [003] ...2 14594.264584: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
-           <...>-625   (-----) [003] d..2 14594.264617: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=logd.writer next_pid=588 next_prio=130
-           <...>-588   (-----) [003] d..2 14594.264851: sched_switch: prev_comm=logd.writer prev_pid=588 prev_prio=130 prev_state=S ==> next_comm=swapper/3 next_pid=0 next_prio=120
-     rcu_preempt-7     (    7) [007] d..2 14594.265273: sched_switch: prev_comm=rcu_preempt prev_pid=7 prev_prio=120 prev_state=S ==> next_comm=kworker/u16:3 next_pid=18008 next_prio=120
-           <...>-18008 (-----) [007] d..2 14594.265404: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=D ==> next_comm=swapper/7 next_pid=0 next_prio=120
-           <...>-18008 (-----) [007] d..2 14594.265471: sched_switch: prev_comm=kworker/u16:3 prev_pid=18008 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.265496: tracing_mark_write: B|625|doComposition
-           <...>-625   (-----) [003] ...1 14594.265507: tracing_mark_write: B|625|doComposeSurfaces
-           <...>-625   (-----) [003] ...1 14594.265552: tracing_mark_write: B|625|acquireBuffer
-           <...>-625   (-----) [003] ...1 14594.265563: tracing_mark_write: B|625|postFramebuffer
-           <...>-625   (-----) [003] ...1 14594.265567: tracing_mark_write: B|625|presentAndGetReleaseFences
-           <...>-625   (-----) [003] d..1 14594.265601: fence_enable_signal: driver=sde_fence:crtc97:91650 timeline=crtc97 context=3 seqno=91650
-           <...>-625   (-----) [003] ...1 14594.265735: tracing_mark_write: B|625|logLayerStats
-           <...>-625   (-----) [003] ...1 14594.265744: tracing_mark_write: B|625|postComposition
-           <...>-625   (-----) [003] ...1 14594.265749: tracing_mark_write: B|625|releaseBuffer
-           <...>-625   (-----) [003] ...1 14594.265753: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
-           <...>-625   (-----) [003] ...1 14594.265791: tracing_mark_write: B|625|releaseBuffer
-           <...>-440   (-----) [007] d..2 14594.342366: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=kworker/u17:2 next_pid=1778 next_prio=100
-           <...>-2007  (-----) [006] ...1 14594.342375: tracing_mark_write: B|2007|input
-           <...>-2007  (-----) [006] ...1 14594.342399: tracing_mark_write: B|2007|animation
-           <...>-625   (-----) [003] ...1 14594.342447: tracing_mark_write: B|625|doTransaction
-           <...>-625   (-----) [003] ...1 14594.342489: tracing_mark_write: B|625|doTransaction
-   kworker/u17:2-1778  ( 1778) [007] d..3 14594.342532: sched_blocked_reason: pid=14607 iowait=1 caller=wait_on_page_bit_common+0x2a8/0x5f8
-   kworker/u17:2-1778  ( 1778) [007] d..2 14594.342544: sched_switch: prev_comm=kworker/u17:2 prev_pid=1778 prev_prio=100 prev_state=S ==> next_comm=kworker/u16:2 next_pid=27544 next_prio=120
-           <...>-1773  (-----) [000] ...1 14594.342575: tracing_mark_write: B|625|requestNextVsync
-           <...>-1773  (-----) [000] ...1 14594.342579: tracing_mark_write: B|625|resetIdleTimer
-           <...>-27544 (-----) [007] d..2 14594.342589: sched_switch: prev_comm=kworker/u16:2 prev_pid=27544 prev_prio=120 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
-           <...>-656   (-----) [002] d.h3 14594.342604: sched_blocked_reason: pid=1233 iowait=0 caller=geni_i2c_xfer+0x4d8/0x1398
-           <...>-1803  (-----) [001] d..2 14594.342605: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.342632: tracing_mark_write: B|625|handleMessageInvalidate
-           <...>-625   (-----) [003] ...1 14594.342634: tracing_mark_write: B|625|handlePageFlip
-           <...>-2738  (-----) [007] ...1 14594.342641: tracing_mark_write: B|2007|notifyFramePending
-           <...>-658   (-----) [002] d..2 14594.342653: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
-           <...>-656   (-----) [002] ...1 14594.342656: tracing_mark_write: B|625|requestNextVsync
-           <...>-2738  (-----) [007] d..2 14594.342658: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=S ==> next_comm=swapper/7 next_pid=0 next_prio=120
-           <...>-656   (-----) [002] ...1 14594.342660: tracing_mark_write: B|625|resetIdleTimer
-           <...>-660   (-----) [005] d..2 14594.342663: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.342665: tracing_mark_write: B|625|latchBuffer
-           <...>-625   (-----) [003] ...1 14594.342673: tracing_mark_write: B|625|query
-           <...>-625   (-----) [003] ...1 14594.342682: tracing_mark_write: B|625|updateTexImage
-           <...>-625   (-----) [003] ...1 14594.342693: tracing_mark_write: B|625|acquireBuffer
-           <...>-625   (-----) [003] ...1 14594.342703: tracing_mark_write: B|625|com.google.android.apps.nexuslauncher/com.google.android.apps.nexuslauncher.NexusLauncherActivity#1: 1
-           <...>-660   (-----) [005] d..2 14594.342709: sched_switch: prev_comm=app prev_pid=660 prev_prio=97 prev_state=S ==> next_comm=swapper/5 next_pid=0 next_prio=120
-           <...>-2007  (-----) [006] ...1 14594.342733: tracing_mark_write: B|2007|traversal
-           <...>-2007  (-----) [006] ...1 14594.342776: tracing_mark_write: B|2007|draw
-           <...>-2007  (-----) [006] ...1 14594.342791: tracing_mark_write: B|2007|Record View#draw()
-           <...>-625   (-----) [003] ...1 14594.342849: tracing_mark_write: B|625|updateInputFlinger
-           <...>-2007  (-----) [006] d..2 14594.342903: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=kworker/6:2H next_pid=24261 next_prio=100
-           <...>-2738  (-----) [007] ...1 14594.342910: tracing_mark_write: B|2007|DrawFrame
-           <...>-2738  (-----) [007] d..2 14594.342917: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
-           <...>-24261 (-----) [006] d..2 14594.342918: sched_switch: prev_comm=kworker/6:2H prev_pid=24261 prev_prio=100 prev_state=S ==> next_comm=.android.dialer next_pid=14607 next_prio=110
-           <...>-440   (-----) [007] d..2 14594.342926: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=RenderThread next_pid=2738 next_prio=110
-           <...>-2738  (-----) [007] ...1 14594.342927: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [007] ...2 14594.342959: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
-           <...>-2738  (-----) [007] d..2 14594.342975: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-656   (-----) [007] ...1 14594.343021: tracing_mark_write: B|625|query
-           <...>-656   (-----) [007] .... 14594.343033: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
-           <...>-2738  (-----) [007] ...1 14594.343070: tracing_mark_write: B|2007|query
-           <...>-1233  (-----) [004] d..2 14594.343074: sched_switch: prev_comm=sound trigger c prev_pid=1233 prev_prio=120 prev_state=R+ ==> next_comm=irq/144-1436400 next_pid=2522 next_prio=49
-           <...>-2738  (-----) [007] ...2 14594.343078: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
-           <...>-625   (-----) [003] ...1 14594.343084: tracing_mark_write: B|625|onMessageReceived
-           <...>-625   (-----) [003] ...1 14594.343087: tracing_mark_write: B|625|handleMessageRefresh
-           <...>-625   (-----) [003] ...1 14594.343090: tracing_mark_write: B|625|preComposition
-           <...>-2738  (-----) [007] d..2 14594.343090: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-625   (-----) [003] ...1 14594.343122: tracing_mark_write: B|625|rebuildLayerStacks
-           <...>-625   (-----) [003] ...1 14594.343124: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
-           <...>-89    (-----) [007] d..2 14594.343126: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-625   (-----) [003] ...1 14594.343129: tracing_mark_write: B|625|computeVisibleRegions
-           <...>-656   (-----) [007] ...1 14594.343136: tracing_mark_write: B|625|query
-           <...>-14607 (-----) [006] ...2 14594.343141: binder_set_priority: proc=1368 thread=3253 old=120 => new=110 desired=110
-                      <...>-2965  (-----) [001] .... 14596.746610: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002ae8fcff pfn=1522884 ofs=188416
-          <idle>-0     (-----) [002] d..2 14596.746619: sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=mmc-cmdqd/0 next_pid=440 next_prio=98
-           <...>-2965  (-----) [001] .... 14596.746629: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000679ee1ec pfn=1299913 ofs=192512
-           <...>-2965  (-----) [001] .... 14596.746664: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000006cd2fb7 pfn=1296251 ofs=196608
-           <...>-2965  (-----) [001] .... 14596.746677: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000af82f3d6 pfn=1419330 ofs=200704
-           <...>-2965  (-----) [001] .... 14596.746693: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000002840f054 pfn=1304928 ofs=204800
-           <...>-2965  (-----) [001] .... 14596.746706: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000004a59da17 pfn=1288069 ofs=208896
-           <...>-2965  (-----) [001] .... 14596.746717: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000023a80dca pfn=1419686 ofs=212992
-           <...>-2965  (-----) [001] .... 14596.746730: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000001cf89eab pfn=1315372 ofs=217088
-           <...>-2965  (-----) [001] .... 14596.746743: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=000000005b4c6cb6 pfn=1380698 ofs=221184
-           <...>-2965  (-----) [001] .... 14596.746760: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f8304ae7 pfn=1206753 ofs=225280
-           <...>-2965  (-----) [001] .... 14596.746773: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000cb912305 pfn=1325465 ofs=229376
-           <...>-2965  (-----) [001] .... 14596.746785: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f16f3774 pfn=1408056 ofs=233472
-           <...>-2965  (-----) [001] .... 14596.746801: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=0000000056d4c926 pfn=1418352 ofs=237568
-           <...>-2965  (-----) [001] .... 14596.746815: mm_filemap_add_to_page_cache: dev 253:6 ino a359 page=00000000f3eeb42c pfn=1320957 ofs=241664
-           <...>-440   (-----) [002] d..2 14596.746916: sched_switch: prev_comm=mmc-cmdqd/0 prev_pid=440 prev_prio=98 prev_state=D ==> next_comm=swapper/2 next_pid=0 next_prio=120
-
-           <...>-656   (-----) [007] .... 14594.343145: binder_set_priority: proc=625 thread=656 old=110 => new=120 desired=120
-           <...>-14607 (-----) [006] d..2 14594.343164: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
-           <...>-5281  (-----) [002] d..2 14594.343177: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2738 next_prio=110
- irq/144-1436400-2522  ( 2522) [004] d..2 14594.343223: sched_switch: prev_comm=irq/144-1436400 prev_pid=2522 prev_prio=49 prev_state=D ==> next_comm=sound trigger c next_pid=1233 next_prio=120
-           <...>-88    (-----) [006] d..2 14594.343240: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
-           <...>-1238  (-----) [001] d..2 14594.343243: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-2738  (-----) [002] ...1 14594.343244: tracing_mark_write: B|2007|syncFrameState
-           <...>-2738  (-----) [002] ...1 14594.343293: tracing_mark_write: B|2007|prepareTree
-           <...>-1695  (-----) [001] d..2 14594.343318: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
-           <...>-5281  (-----) [005] d..2 14594.343322: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:1368_14 next_pid=3253 next_prio=110
-           <...>-1238  (-----) [001] d..2 14594.343442: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=InputDispatcher next_pid=1695 next_prio=112
-           <...>-1695  (-----) [001] d..2 14594.343467: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=swapper/1 next_pid=0 next_prio=120
-           <...>-5281  (-----) [000] d..2 14594.343484: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-           <...>-625   (-----) [003] ...1 14594.343519: tracing_mark_write: B|625|calculateWorkingSet
-           <...>-2738  (-----) [002] ...1 14594.343568: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [002] ...1 14594.343577: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [002] ...1 14594.343586: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [002] ...1 14594.343591: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [002] ...1 14594.343597: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [002] ...1 14594.343602: tracing_mark_write: B|2007|query
-           <...>-2738  (-----) [002] ...1 14594.343609: tracing_mark_write: B|2007|dequeueBuffer
-           <...>-2007  (-----) [006] d..2 14594.343612: sched_switch: prev_comm=s.nexuslauncher prev_pid=2007 prev_prio=110 prev_state=S ==> next_comm=swapper/6 next_pid=0 next_prio=120
-           <...>-2738  (-----) [002] ...2 14594.343633: binder_set_priority: proc=625 thread=656 old=120 => new=110 desired=110
-           <...>-2738  (-----) [002] d..2 14594.343683: sched_switch: prev_comm=RenderThread prev_pid=2738 prev_prio=110 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=110
-           <...>-625   (-----) [003] ...1 14594.343704: tracing_mark_write: B|625|prepare
-           <...>-656   (-----) [002] ...1 14594.343707: tracing_mark_write: B|625|dequeueBuffer
-           <...>-625   (-----) [004] ...1 14594.812869: tracing_mark_write: B|625|com.google.android.dialer/com.google.android.dialer.extensions.GoogleDialtactsActivity#0: 2
-           <...>-2048  (-----) [000] d..2 14594.812895: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_3 next_pid=1431 next_prio=120
-           <...>-1431  (-----) [000] ...1 14594.812911: tracing_mark_write: B|625|query
-           <...>-625   (-----) [004] ...1 14594.812914: tracing_mark_write: B|625|latchBuffer
-           <...>-625   (-----) [004] ...1 14594.812919: tracing_mark_write: B|625|query
-           <...>-625   (-----) [004] ...1 14594.812925: tracing_mark_write: B|625|updateTexImage
-           <...>-625   (-----) [004] ...1 14594.812928: tracing_mark_write: B|625|acquireBuffer
-           <...>-625   (-----) [004] ...1 14594.812934: tracing_mark_write: B|625|StatusBar#0: 1
-           <...>-2048  (-----) [000] ...1 14594.812962: tracing_mark_write: B|1803|syncFrameState
-           <...>-656   (-----) [002] ...1 14594.813044: tracing_mark_write: B|625|setTransactionState
-           <...>-14607 (-----) [007] ...2 14594.813083: binder_set_priority: proc=10691 thread=18733 old=120 => new=110 desired=110
-           <...>-14607 (-----) [007] d..2 14594.813114: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
-           <...>-14655 (-----) [006] d..2 14594.813128: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=lpass_smem_glin next_pid=89 next_prio=98
-           <...>-89    (-----) [006] d..2 14594.813163: sched_switch: prev_comm=lpass_smem_glin prev_pid=89 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
-           <...>-656   (-----) [002] ...1 14594.813218: tracing_mark_write: B|625|requestNextVsync
-           <...>-656   (-----) [002] ...1 14594.813222: tracing_mark_write: B|625|resetIdleTimer
-     kworker/7:1-7092  ( 7092) [007] d..2 14594.813239: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
-           <...>-5281  (-----) [001] d..2 14594.813245: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
-           <...>-88    (-----) [007] d..2 14594.813248: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=R ==> next_comm=kgsl_worker_thr next_pid=259 next_prio=97
-           <...>-2048  (-----) [000] d..2 14594.813249: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
-           <...>-14655 (-----) [006] d..2 14594.813263: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R+ ==> next_comm=smem_native_lpa next_pid=88 next_prio=98
-           <...>-661   (-----) [002] d..2 14594.813265: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
-           <...>-259   (-----) [007] d..2 14594.813265: sched_switch: prev_comm=kgsl_worker_thr prev_pid=259 prev_prio=97 prev_state=S ==> next_comm=kworker/7:1 next_pid=7092 next_prio=120
-     kworker/7:1-7092  ( 7092) [007] d..2 14594.813271: sched_switch: prev_comm=kworker/7:1 prev_pid=7092 prev_prio=120 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
-           <...>-108   (-----) [007] .... 14594.813275: ion_heap_shrink: heap_name=system, len=9469952, total_allocated=189620224
-           <...>-88    (-----) [006] d..2 14594.813294: sched_switch: prev_comm=smem_native_lpa prev_pid=88 prev_prio=98 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
-           <...>-625   (-----) [004] ...1 14594.813310: tracing_mark_write: B|625|updateInputFlinger
-           <...>-1238  (-----) [000] d..2 14594.813312: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
-           <...>-661   (-----) [002] d..2 14594.813317: sched_switch: prev_comm=sf prev_pid=661 prev_prio=97 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
-           <...>-14640 (-----) [005] d..2 14594.813319: sched_switch: prev_comm=DialerExecutors prev_pid=14640 prev_prio=130 prev_state=R ==> next_comm=DispSync next_pid=658 next_prio=97
-           <...>-656   (-----) [002] ...1 14594.813336: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-658   (-----) [005] d..2 14594.813345: sched_switch: prev_comm=DispSync prev_pid=658 prev_prio=97 prev_state=S ==> next_comm=DialerExecutors next_pid=14640 next_prio=130
-           <...>-656   (-----) [002] ...1 14594.813345: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813353: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-2048  (-----) [000] d..2 14594.813358: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=FastMixer next_pid=1238 next_prio=96
-           <...>-656   (-----) [002] ...1 14594.813364: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-5281  (-----) [001] d..2 14594.813369: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:10691_B next_pid=18733 next_prio=110
-           <...>-656   (-----) [002] ...1 14594.813372: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813380: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813391: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813398: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813408: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813416: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813424: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813432: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] .n.1 14594.813443: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-1238  (-----) [000] d..2 14594.813464: sched_switch: prev_comm=FastMixer prev_pid=1238 prev_prio=96 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
-           <...>-5281  (-----) [002] d..2 14594.813525: sched_switch: prev_comm=writer prev_pid=5281 prev_prio=96 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
-           <...>-656   (-----) [002] ...1 14594.813544: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-656   (-----) [002] ...1 14594.813557: tracing_mark_write: B|625|~GraphicBuffer
-           <...>-2048  (-----) [000] d..2 14594.813594: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
-           <...>-18733 (-----) [001] ...2 14594.813635: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
-           <...>-656   (-----) [002] .... 14594.813637: binder_set_priority: proc=625 thread=656 old=116 => new=120 desired=120
-           <...>-108   (-----) [007] d..2 14594.813646: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
-           <...>-625   (-----) [004] ...1 14594.813646: tracing_mark_write: B|625|onMessageReceived
-           <...>-625   (-----) [004] ...1 14594.813649: tracing_mark_write: B|625|handleMessageRefresh
-           <...>-625   (-----) [004] ...1 14594.813651: tracing_mark_write: B|625|preComposition
-           <...>-625   (-----) [004] ...1 14594.813693: tracing_mark_write: B|625|rebuildLayerStacks
-           <...>-625   (-----) [004] ...1 14594.813696: tracing_mark_write: B|625|rebuildLayerStacks VR Dirty
-           <...>-625   (-----) [004] ...1 14594.813701: tracing_mark_write: B|625|computeVisibleRegions
-           <...>-1398  (-----) [007] d..2 14594.813718: sched_switch: prev_comm=android.anim prev_pid=1398 prev_prio=116 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
-           <...>-108   (-----) [007] d..2 14594.813739: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=android.anim next_pid=1398 next_prio=116
-           <...>-1695  (-----) [002] d..2 14594.813970: sched_switch: prev_comm=InputDispatcher prev_pid=1695 prev_prio=112 prev_state=S ==> next_comm=system next_pid=108 next_prio=120
-           <...>-1398  (-----) [007] ...1 14594.814029: tracing_mark_write: B|1368|wmLayout
-           <...>-1398  (-----) [007] ...1 14594.814033: tracing_mark_write: B|1368|performSurfacePlacement
-           <...>-1398  (-----) [007] ...1 14594.814040: tracing_mark_write: B|1368|applySurfaceChanges
-           <...>-1398  (-----) [007] ...1 14594.814043: tracing_mark_write: B|1368|openSurfaceTransaction
-           <...>-1398  (-----) [007] ...1 14594.814063: tracing_mark_write: B|1368|performLayout
-           <...>-625   (-----) [004] ...1 14594.814119: tracing_mark_write: B|625|calculateWorkingSet
-           <...>-1398  (-----) [007] ...1 14594.814241: tracing_mark_write: B|1368|layoutInputConsumer
-           <...>-2048  (-----) [000] ...1 14594.814260: tracing_mark_write: B|1803|prepareTree
-           <...>-1398  (-----) [007] ...1 14594.814263: tracing_mark_write: B|1368|applyPostLayoutPolicy
-           <...>-2048  (-----) [000] d..2 14594.814408: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R ==> next_comm=Binder:1368_15 next_pid=3359 next_prio=120
-           <...>-625   (-----) [004] ...1 14594.814411: tracing_mark_write: B|625|prepare
-           <...>-625   (-----) [004] ...1 14594.814428: tracing_mark_write: B|625|HIDL::IComposerClient::executeCommands_2_2::client
-           <...>-2048  (-----) [000] d..2 14594.814533: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
-           <...>-1803  (-----) [000] d..2 14594.814558: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
-           <...>-2048  (-----) [000] d..2 14594.814572: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=ndroid.systemui next_pid=1803 next_prio=120
-           <...>-625   (-----) [004] ...2 14594.814589: binder_set_priority: proc=627 thread=627 old=97 => new=98 desired=98
-           <...>-108   (-----) [002] d..2 14594.814650: sched_switch: prev_comm=system prev_pid=108 prev_prio=120 prev_state=R+ ==> next_comm=composer@2.2-se next_pid=627 next_prio=98
-           <...>-625   (-----) [004] d..2 14594.814664: sched_switch: prev_comm=surfaceflinger prev_pid=625 prev_prio=98 prev_state=S ==> next_comm=ashmemd next_pid=854 next_prio=129
-           <...>-1398  (-----) [007] ...1 14594.814723: tracing_mark_write: B|1368|applyWindowSurfaceChanges
-           <...>-854   (-----) [004] .... 14594.814746: binder_set_priority: proc=854 thread=854 old=129 => new=120 desired=120
-           <...>-854   (-----) [004] d..2 14594.814757: sched_switch: prev_comm=ashmemd prev_pid=854 prev_prio=120 prev_state=R+ ==> next_comm=highpool[0] next_pid=3493 next_prio=129
-           <...>-1803  (-----) [000] d..2 14594.814763: sched_switch: prev_comm=ndroid.systemui prev_pid=1803 prev_prio=120 prev_state=S ==> next_comm=RenderThread next_pid=2048 next_prio=120
-           <...>-18733 (-----) [001] d..1 14594.814819: mm_filemap_delete_from_page_cache: dev 0:1 ino 3ce5e7 page=0000000083f10c7a pfn=1298474 ofs=0
-           <...>-2048  (-----) [000] ...1 14594.814842: tracing_mark_write: B|1803|dequeueBuffer
-           <...>-1398  (-----) [007] ...1 14594.814850: tracing_mark_write: F|1368|launching: com.google.android.dialer|0
-           <...>-1398  (-----) [007] ...1 14594.814855: tracing_mark_write: B|1368|MetricsLogger:launchObserverNotifyActivityLaunchFinished
-           <...>-1398  (-----) [007] ...1 14594.814857: tracing_mark_write: B|1368|MetricsLogger:convertActivityRecordToProto
-           <...>-2048  (-----) [000] d..2 14594.814905: sched_switch: prev_comm=RenderThread prev_pid=2048 prev_prio=120 prev_state=R+ ==> next_comm=Binder:625_1 next_pid=656 next_prio=120
-           <...>-1410  (-----) [006] .... 14592.997816: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=00000000615a8f24 pfn=1134764 ofs=0
-           <...>-1410  (-----) [006] .... 14592.997831: mm_filemap_add_to_page_cache: dev 253:6 ino b785 page=000000008768a58f pfn=1134751 ofs=4096
-
-           <...>-18733 (-----) [001] .... 14594.814914: binder_set_priority: proc=10691 thread=18733 old=110 => new=120 desired=120
-           <...>-14655 (-----) [006] d..2 14594.814932: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=.android.dialer next_pid=14607 next_prio=110
-           <...>-656   (-----) [000] ...1 14594.814948: tracing_mark_write: B|625|dequeueBuffer
-           <...>-3514  (-----) [001] .... 14594.814954: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
-           <...>-656   (-----) [000] ...1 14594.814963: tracing_mark_write: B|625|NavigationBar0#0: 2
-           <...>-14607 (-----) [006] ...2 14594.815022: binder_set_priority: proc=1368 thread=3514 old=120 => new=110 desired=110
-           <...>-1398  (-----) [007] ...1 14594.815039: tracing_mark_write: B|1368|prepareSurfaces
-           <...>-14607 (-----) [006] d..2 14594.815041: sched_switch: prev_comm=.android.dialer prev_pid=14607 prev_prio=110 prev_state=S ==> next_comm=DialerExecutors next_pid=14655 next_prio=130
-           <...>-3493  (-----) [004] d..2 14594.815057: sched_switch: prev_comm=highpool[0] prev_pid=3493 prev_prio=129 prev_state=R ==> next_comm=Binder:1368_18 next_pid=3514 next_prio=110
-           <...>-2048  (-----) [000] ...1 14594.815088: tracing_mark_write: B|1803|HWC release fence 45750 has signaled
-           <...>-2048  (-----) [000] ...1 14594.815119: tracing_mark_write: B|1803|eglBeginFrame
-           <...>-14655 (-----) [006] d..2 14594.815190: sched_switch: prev_comm=DialerExecutors prev_pid=14655 prev_prio=130 prev_state=R ==> next_comm=crtc_commit:97 next_pid=301 next_prio=83
-           <...>-3514  (-----) [004] .... 14594.815193: binder_set_priority: proc=1368 thread=3514 old=110 => new=120 desired=120
-           <...>-1398  (-----) [007] ...1 14594.815322: tracing_mark_write: B|1368|closeSurfaceTransaction
-           <...>-3493  (-----) [004] .... 14594.815353: mm_filemap_add_to_page_cache: dev 253:6 ino 113b page=0000000069e2b98a pfn=628464 ofs=2723840
-           <...>-1398  (-----) [007] ...2 14594.815393: binder_set_priority: proc=625 thread=656 old=120 => new=116 desired=116
-       rcu_sched-8     (    8) [007] d..2 14594.815449: sched_switch: prev_comm=rcu_sched prev_pid=8 prev_prio=120 prev_state=S ==> next_comm=Binder:625_1 next_pid=656 next_prio=116
diff --git a/startop/scripts/trace_analyzer/trace_analyzer b/startop/scripts/trace_analyzer/trace_analyzer
deleted file mode 100755
index 8c03964..0000000
--- a/startop/scripts/trace_analyzer/trace_analyzer
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$(dirname "$0")" ; pwd -P )"
-
-if [[ "$#" -lt 2 ]]; then
-  echo "Usage: $0 <filename.trace> <sqlite-filename.db>" >&2
-  exit 1
-fi
-
-TRACE_FILENAME="$1"
-SQLITE_FILENAME="$2"
-
-#echo "Trace filename: $TRACE_FILENAME"
-#echo "SQLite filename: $SQLITE_FILENAME"
-
-if ! [[ -f "$TRACE_FILENAME" ]]; then
-  echo "Error: Trace '$TRACE_FILENAME' does not exist." >&2
-  exit 1
-fi
-
-if ! "$DIR/trace_analyzer.py" "$SQLITE_FILENAME" "$TRACE_FILENAME" > /dev/null; then
-  echo "Fatal: trace_analyzer.py failed, aborting." >&2
-  exit 1
-fi
-
-if ! "$DIR/run-sql-queries" "$SQLITE_FILENAME"; then
-  echo "Fatal: Failed to run sql queries, aborting." >&2
-  exit 1
-fi
diff --git a/startop/scripts/trace_analyzer/trace_analyzer.py b/startop/scripts/trace_analyzer/trace_analyzer.py
deleted file mode 100755
index 62ae018..0000000
--- a/startop/scripts/trace_analyzer/trace_analyzer.py
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/usr/bin/python3
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import re
-import sys
-import argparse
-
-from lib.trace2db import Trace2Db
-
-# This script requires 'sqlalchemy' to access the sqlite3 database.
-#
-# $> sudo apt-get install python3-pip
-# $> pip3 install --user sqlalchemy
-#
-
-def main(argv):
-  parser = argparse.ArgumentParser(description='Convert ftrace/systrace file into sqlite3 db.')
-  parser.add_argument('db_filename', metavar='sql_filename.db', type=str,
-                      help='path to sqlite3 db filename')
-  parser.add_argument('trace_filename', metavar='systrace.ftrace', type=str,
-                      help='path to ftrace/systrace filename')
-  parser.add_argument('--limit', type=int, help='limit the number of entries parsed [for debugging]')
-
-  args = parser.parse_args()
-
-  db_filename = args.db_filename
-  trace_filename = args.trace_filename
-
-  trace2db = Trace2Db(db_filename)
-  print("SQL Alchemy db initialized")
-
-  # parse 'raw_ftrace_entries' table
-  count = trace2db.parse_file_into_db(trace_filename, limit=args.limit)
-  print("Count was ", count)
-
-  return 0
-
-if __name__ == '__main__':
-  main(sys.argv)
diff --git a/startop/scripts/trace_analyzer/trace_analyzer_recursive b/startop/scripts/trace_analyzer/trace_analyzer_recursive
deleted file mode 100755
index 4d9ee0e..0000000
--- a/startop/scripts/trace_analyzer/trace_analyzer_recursive
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$(dirname "$0")" ; pwd -P )"
-
-if [[ "$#" -lt 3 ]]; then
-  echo "Usage: $0 <trace-dir> <db-dir> <output.csv>" >&2
-  exit 1
-fi
-
-simulate="n"
-
-TRACE_DIRNAME="$1"
-SQLITE_DIRNAME="$2"
-OUTPUT_FILENAME="$3"
-
-echo "Trace filename: $TRACE_DIRNAME"
-echo "SQLite filename: $SQLITE_DIRNAME"
-
-if ! [[ -d "$TRACE_DIRNAME" ]]; then
-  echo "Error: Trace '$TRACE_DIRNAME' does not exist." >&2
-  exit 1
-fi
-
-process_trace_file() {
-  local trace_filename="$1"
-  local db_dirname="$2"
-  local output_file="$3"
-
-  local db_filename="$db_dirname/$(basename "$trace_filename").db"
-
-  if [[ $simulate == y ]]; then
-    echo "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" "> /dev/null"
-  else
-    if ! "$DIR/trace_analyzer.py" "$db_filename" "$trace_filename" > /dev/null; then
-      echo "Fatal: trace_analyzer.py failed, aborting." >&2
-      return 1
-    fi
-  fi
-
-  if [[ $simulate == y ]]; then
-    echo "$DIR/run-sql-queries" "$db_filename" ">> '$output_file'"
-  else
-    # append name of trace to CSV, so we can see where data came from
-    echo "; $trace_filename" >> "$output_file"
-    if ! "$DIR/run-sql-queries" "$db_filename" >> "$output_file"; then
-      echo "Fatal: Failed to run sql queries, aborting." >&2
-      return 1
-    fi
-  fi
-
-  return 0
-}
-
-find "$TRACE_DIRNAME" -type f -name '*.trace' -print0 |
-while IFS= read -r -d '' file; do
-  if [[ $file == *#*.trace && $file != *#1.trace ]]; then
-    echo "Skip $file"
-    continue
-  fi
-
-  printf '%s\n' "$file"
-  process_trace_file "$file" "$SQLITE_DIRNAME" "$OUTPUT_FILENAME"
-done
-
-echo "Done"
diff --git a/startop/scripts/trace_analyzer/trace_analyzer_test.py b/startop/scripts/trace_analyzer/trace_analyzer_test.py
deleted file mode 100644
index 579529c..0000000
--- a/startop/scripts/trace_analyzer/trace_analyzer_test.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright 2019, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-"""
-Unit tests for trace_analyzer module.
-
-Install:
-  $> sudo apt-get install python3-pytest   ##  OR
-  $> pip install -U pytest
-See also https://docs.pytest.org/en/latest/getting-started.html
-
-Usage:
-  $> pytest trace_analyzer_test.py
-
-See also https://docs.pytest.org/en/latest/usage.html
-"""
-
-# global imports
-import os
-import sys
-
-DIR = os.path.abspath(os.path.dirname(__file__))
-
-sys.path.append(os.path.dirname(DIR))
-import lib.cmd_utils as cmd_utils
-
-def test_trace_analyzer(tmpdir):
-  # Setup
-  bin = os.path.join(DIR, 'trace_analyzer')
-  systrace = os.path.join(DIR, 'test_fixtures/common_systrace')
-  db_file = tmpdir.mkdir('trace_analyzer').join('test.db')
-
-  # Act
-  passed, output = cmd_utils.execute_arbitrary_command([bin, systrace,
-                                                        str(db_file)],
-                                                       timeout=300,
-                                                       shell=False,
-                                                       simulate=False)
-
-  # Assert
-  assert passed
-  assert output == """\
-'blocked_iowait_duration_ms',\
-'process_name',\
-'launching_duration_ms',\
-'launching_started_timestamp_ms',\
-'launching_finished_timestamp_ms'
-81.697999999960302375,\
-'com.google.android.dialer',\
-594.99400000095192808,\
-14594219.85600000061,\
-14594814.85000000149"""
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index ce9530c..980ea5c 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -701,15 +701,8 @@
          */
         public static final int PROPERTY_CROSS_SIM = 0x00004000;
 
-        /**
-         * Connection is a tethered external call.
-         * Indicates that the {@link Connection} is fixed on this device but the audio streams are
-         * re-routed to another device.
-         */
-        public static final int PROPERTY_TETHERED_CALL = 0x00008000;
-
         //******************************************************************************************
-        // Next PROPERTY value: 0x00010000
+        // Next PROPERTY value: 0x00004000
         //******************************************************************************************
 
         private final @CallState int mState;
@@ -906,9 +899,6 @@
             if (hasProperty(properties, PROPERTY_CROSS_SIM)) {
                 builder.append(" PROPERTY_CROSS_SIM");
             }
-            if (hasProperty(properties, PROPERTY_TETHERED_CALL)) {
-                builder.append(" PROPERTY_TETHERED_CALL");
-            }
             builder.append("]");
             return builder.toString();
         }
@@ -1486,12 +1476,21 @@
         /**
          * Invoked when the RTT session failed to initiate for some reason, including rejection
          * by the remote party.
+         * <p>
+         * This callback will ONLY be invoked to report a failure related to a user initiated
+         * session modification request (i.e. {@link Call#sendRttRequest()}).
+         * <p>
+         * If a call is initiated with {@link TelecomManager#EXTRA_START_CALL_WITH_RTT} specified,
+         * the availability of RTT can be determined by checking {@link Details#PROPERTY_RTT}
+         * once the call enters state {@link Details#STATE_ACTIVE}.
+         *
          * @param call The call which the RTT initiation failure occurred on.
          * @param reason One of the status codes defined in
-         *               {@link android.telecom.Connection.RttModifyStatus}, with the exception of
-         *               {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
+         *      {@link android.telecom.Connection.RttModifyStatus}, with the exception of
+         *      {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
          */
-        public void onRttInitiationFailure(Call call, int reason) {}
+        public void onRttInitiationFailure(Call call,
+                @android.telecom.Connection.RttModifyStatus.RttSessionModifyStatus int reason) {}
 
         /**
          * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index 389df80..fccdf76 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -27,6 +27,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -41,8 +42,7 @@
 public final class CallAudioState implements Parcelable {
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {ROUTE_EARPIECE, ROUTE_BLUETOOTH, ROUTE_WIRED_HEADSET, ROUTE_SPEAKER,
-            ROUTE_EXTERNAL},
+    @IntDef(value={ROUTE_EARPIECE, ROUTE_BLUETOOTH, ROUTE_WIRED_HEADSET, ROUTE_SPEAKER},
             flag=true)
     public @interface CallAudioRoute {}
 
@@ -58,9 +58,6 @@
     /** Direct the audio stream through the device's speakerphone. */
     public static final int ROUTE_SPEAKER       = 0x00000008;
 
-    /** Direct the audio stream through another device. */
-    public static final int ROUTE_EXTERNAL       = 0x00000010;
-
     /**
      * Direct the audio stream through the device's earpiece or wired headset if one is
      * connected.
@@ -73,7 +70,7 @@
      * @hide
      **/
     public static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
-            ROUTE_SPEAKER | ROUTE_EXTERNAL;
+            ROUTE_SPEAKER;
 
     private final boolean isMuted;
     private final int route;
@@ -192,11 +189,7 @@
      */
     @CallAudioRoute
     public int getSupportedRouteMask() {
-        if (route == ROUTE_EXTERNAL) {
-            return ROUTE_EXTERNAL;
-        } else {
-            return supportedRouteMask;
-        }
+        return supportedRouteMask;
     }
 
     /**
@@ -240,10 +233,6 @@
             listAppend(buffer, "SPEAKER");
         }
 
-        if ((route & ROUTE_EXTERNAL) == ROUTE_EXTERNAL) {
-            listAppend(buffer, "EXTERNAL");
-        }
-
         return buffer.toString();
     }
 
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 30d4959..6a283df 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -561,15 +561,6 @@
      */
     public static final int PROPERTY_CROSS_SIM = 1 << 13;
 
-    /**
-     * Connection is a tethered external call.
-     * <p>
-     * Indicates that the {@link Connection} is fixed on this device but the audio streams are
-     * re-routed to another device.
-     * <p>
-     */
-    public static final int PROPERTY_TETHERED_CALL = 1 << 14;
-
     //**********************************************************************************************
     // Next PROPERTY value: 1<<14
     //**********************************************************************************************
@@ -1408,6 +1399,18 @@
          * Session modify request rejected by remote user.
          */
         public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5;
+
+
+        /**@hide*/
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(prefix = "SESSION_MODIFY_REQUEST_", value = {
+                SESSION_MODIFY_REQUEST_SUCCESS,
+                SESSION_MODIFY_REQUEST_FAIL,
+                SESSION_MODIFY_REQUEST_INVALID,
+                SESSION_MODIFY_REQUEST_TIMED_OUT,
+                SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE
+        })
+        public @interface RttSessionModifyStatus {}
     }
 
     /**
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index f43e5aa..df114db 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1292,31 +1292,22 @@
     }
 
     /**
-     * Returns a list of {@link PhoneAccountHandle}s for self-managed {@link ConnectionService}s.
+     * Returns a list of {@link PhoneAccountHandle}s for all self-managed
+     * {@link ConnectionService}s owned by the calling {@link UserHandle}.
      * <p>
      * Self-Managed {@link ConnectionService}s have a {@link PhoneAccount} with
      * {@link PhoneAccount#CAPABILITY_SELF_MANAGED}.
      * <p>
      * Requires permission {@link android.Manifest.permission#READ_PHONE_STATE}, or that the caller
-     * is the default dialer app to get all phone account handles.
-     * <P>
-     * If the caller doesn't meet any of the above requirements and has {@link
-     * android.Manifest.permission#MANAGE_OWN_CALLS}, the caller can get only the phone account
-     * handles they have registered.
+     * is the default dialer app.
      * <p>
-     * A {@link SecurityException} will be thrown if the caller is not the default dialer
-     * or the caller does not have at least one of the following permissions:
-     * {@link android.Manifest.permission#READ_PHONE_STATE} permission,
-     * {@link android.Manifest.permission#MANAGE_OWN_CALLS} permission
+     * A {@link SecurityException} will be thrown if a called is not the default dialer, or lacks
+     * the {@link android.Manifest.permission#READ_PHONE_STATE} permission.
      *
      * @return A list of {@code PhoneAccountHandle} objects.
      */
-    @RequiresPermission(anyOf = {
-            READ_PRIVILEGED_PHONE_STATE,
-            android.Manifest.permission.READ_PHONE_STATE,
-            android.Manifest.permission.MANAGE_OWN_CALLS
-    })
-    public List<PhoneAccountHandle> getSelfManagedPhoneAccounts() {
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public @NonNull List<PhoneAccountHandle> getSelfManagedPhoneAccounts() {
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
@@ -1330,6 +1321,34 @@
     }
 
     /**
+     * Returns a list of {@link PhoneAccountHandle}s owned by the calling self-managed
+     * {@link ConnectionService}.
+     * <p>
+     * Self-Managed {@link ConnectionService}s have a {@link PhoneAccount} with
+     * {@link PhoneAccount#CAPABILITY_SELF_MANAGED}.
+     * <p>
+     * Requires permission {@link android.Manifest.permission#MANAGE_OWN_CALLS}
+     * <p>
+     * A {@link SecurityException} will be thrown if a caller lacks the
+     * {@link android.Manifest.permission#MANAGE_OWN_CALLS} permission.
+     *
+     * @return A list of {@code PhoneAccountHandle} objects.
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_OWN_CALLS)
+    public @NonNull List<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts() {
+        ITelecomService service = getTelecomService();
+        if (service != null) {
+            try {
+                return service.getOwnSelfManagedPhoneAccounts(mContext.getOpPackageName(),
+                        mContext.getAttributionTag());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        throw new IllegalStateException("Telecom is not available");
+    }
+
+    /**
      * Returns a list of {@link PhoneAccountHandle}s including those which have not been enabled
      * by the user.
      *
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index b9936ce..9999c89 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -66,6 +66,12 @@
             String callingFeatureId);
 
     /**
+     * @see TelecomServiceImpl#getOwnSelfManagedPhoneAccounts
+     */
+    List<PhoneAccountHandle> getOwnSelfManagedPhoneAccounts(String callingPackage,
+            String callingFeatureId);
+
+    /**
      * @see TelecomManager#getPhoneAccountsSupportingScheme
      */
     List<PhoneAccountHandle> getPhoneAccountsSupportingScheme(in String uriScheme,
diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java
index 8d92520..dc695d6 100644
--- a/telephony/java/android/service/euicc/EuiccService.java
+++ b/telephony/java/android/service/euicc/EuiccService.java
@@ -29,7 +29,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.telephony.TelephonyManager;
 import android.telephony.euicc.DownloadableSubscription;
 import android.telephony.euicc.EuiccInfo;
 import android.telephony.euicc.EuiccManager;
@@ -744,18 +743,16 @@
                 public void run() {
                     DownloadSubscriptionResult result;
                     try {
-                        result =
-                            EuiccService.this.onDownloadSubscription(
-                                slotId, subscription, switchAfterDownload, forceDeactivateSim,
-                                resolvedBundle);
-                    } catch (AbstractMethodError e) {
-                        Log.w(TAG, "The new onDownloadSubscription(int, "
+                        result = EuiccService.this.onDownloadSubscription(
+                                slotId, portIndex, subscription, switchAfterDownload,
+                                forceDeactivateSim, resolvedBundle);
+                    } catch (UnsupportedOperationException | AbstractMethodError e) {
+                        Log.w(TAG, "The new onDownloadSubscription(int, int, "
                                 + "DownloadableSubscription, boolean, boolean, Bundle) is not "
                                 + "implemented. Fall back to the old one.", e);
-                        int resultCode = EuiccService.this.onDownloadSubscription(
-                                slotId, subscription, switchAfterDownload, forceDeactivateSim);
-                        result = new DownloadSubscriptionResult(resultCode,
-                            0 /* resolvableErrors */, TelephonyManager.UNSUPPORTED_CARD_ID);
+                        result = EuiccService.this.onDownloadSubscription(
+                                slotId, subscription, switchAfterDownload,
+                                forceDeactivateSim, resolvedBundle);
                     }
                     try {
                         callback.onComplete(result);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index adb51c4..837cf8b 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -3850,30 +3850,42 @@
     public static final String KEY_OPPORTUNISTIC_ESIM_DOWNLOAD_VIA_WIFI_ONLY_BOOL =
             "opportunistic_esim_download_via_wifi_only_bool";
 
-    /**
-     * Controls RSRP threshold at which OpportunisticNetworkService will decide whether
+/**
+     * Controls RSRP threshold, in dBm, at which OpportunisticNetworkService will decide whether
      * the opportunistic network is good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRsrp()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT =
             "opportunistic_network_entry_threshold_rsrp_int";
 
     /**
-     * Controls RSSNR threshold at which OpportunisticNetworkService will decide whether
-     * the opportunistic network is good enough for internet data.
+     * Controls RSSNR threshold, in dB, at which OpportunisticNetworkService will
+     * decide whether the opportunistic network is good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRssnr()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT =
             "opportunistic_network_entry_threshold_rssnr_int";
 
     /**
-     * Controls RSRP threshold below which OpportunisticNetworkService will decide whether
+     * Controls RSRP threshold, in dBm, below which OpportunisticNetworkService will decide whether
      * the opportunistic network available is not good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRsrp()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT =
             "opportunistic_network_exit_threshold_rsrp_int";
 
     /**
-     * Controls RSSNR threshold below which OpportunisticNetworkService will decide whether
-     * the opportunistic network available is not good enough for internet data.
+     * Controls RSSNR threshold, in dB, below which OpportunisticNetworkService will
+     * decide whether the opportunistic network available is not good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRssnr()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT =
             "opportunistic_network_exit_threshold_rssnr_int";
@@ -3971,7 +3983,7 @@
          * good enough for internet data. Note other factors may be considered for the final
          * decision.
          *
-         * <p>The value of {@link CellSignalStrengthNr#getSsRsrp} will be compared with this
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrp()} will be compared with this
          * threshold.
          *
          * @hide
@@ -3998,7 +4010,7 @@
          * good enough for internet data. Note other factors may be considered for the final
          * decision.
          *
-         * <p>The value of {@link CellSignalStrengthNr#getSsRsrq} will be compared with this
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrq()} will be compared with this
          * threshold.
          *
          * @hide
@@ -4025,6 +4037,9 @@
          * be considered good enough for internet data. Note other factors may be considered
          * for the final decision.
          *
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrp()} will be compared with this
+         * threshold.
+         *
          * @hide
          */
         public static final String KEY_EXIT_THRESHOLD_SS_RSRP_INT =
@@ -4048,6 +4063,9 @@
          * be considered good enough for internet data. Note other factors may be considered
          * for the final decision.
          *
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrq()} will be compared with this
+         * threshold.
+         *
          * @hide
          */
         public static final String KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE =
@@ -8995,9 +9013,9 @@
         /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */
         sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT, -118);
         /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_GOOD */
-        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 45);
+        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 5);
         /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_MODERATE */
-        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, 10);
+        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, 1);
         /* Default value is 1024 kbps */
         sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_BANDWIDTH_INT, 1024);
         /* Default value is 10 seconds */
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 947dc01..5e90261 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -125,13 +125,13 @@
     /**
      * Construct a cell signal strength
      *
-     * @param rssi in dBm [-113,-51], UNKNOWN
-     * @param rsrp in dBm [-140,-43], UNKNOWN
-     * @param rsrq in dB [-34, 3], UNKNOWN
-     * @param rssnr in dB [-20, +30], UNKNOWN
-     * @param cqiTableIndex [1, 6], UNKNOWN
-     * @param cqi [0, 15], UNKNOWN
-     * @param timingAdvance [0, 1282], UNKNOWN
+     * @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
+     * @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
+     * @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
+     * @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
+     * @param cqiTableIndex [1, 6], {@link CellInfo#UNAVAILABLE}
+     * @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
+     * @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
      *
      */
     /** @hide */
@@ -151,12 +151,12 @@
     /**
      * Construct a cell signal strength
      *
-     * @param rssi in dBm [-113,-51], UNKNOWN
-     * @param rsrp in dBm [-140,-43], UNKNOWN
-     * @param rsrq in dB [-34, 3], UNKNOWN
-     * @param rssnr in dB [-20, +30], UNKNOWN
-     * @param cqi [0, 15], UNKNOWN
-     * @param timingAdvance [0, 1282], UNKNOWN
+     * @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
+     * @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
+     * @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
+     * @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
+     * @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
+     * @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
      *
      */
     /** @hide */
@@ -403,10 +403,11 @@
     }
 
     /**
-     * Get reference signal signal-to-noise ratio
+     * Get reference signal signal-to-noise ratio in dB
+     * Range: -20 dB to +30 dB.
      *
      * @return the RSSNR if available or
-     *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
+     *         {@link android.telephony.CellInfo#UNAVAILABLE} if unavailable.
      */
     public int getRssnr() {
         return mRssnr;
@@ -414,8 +415,10 @@
 
     /**
      * Get reference signal received power in dBm
+     * Range: -140 dBm to -43 dBm.
      *
-     * @return the RSRP of the measured cell.
+     * @return the RSRP of the measured cell or {@link CellInfo#UNAVAILABLE} if
+     * unavailable.
      */
     public int getRsrp() {
         return mRsrp;
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 0394a54..1eb391d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -48,6 +48,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.ContextParams;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
@@ -143,6 +144,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.concurrent.RejectedExecutionException;
@@ -388,16 +390,8 @@
     @UnsupportedAppUsage
     public TelephonyManager(Context context, int subId) {
         mSubId = subId;
-        Context appContext = context.getApplicationContext();
-        if (appContext != null) {
-            if (Objects.equals(context.getAttributionTag(), appContext.getAttributionTag())) {
-                mContext = appContext;
-            } else {
-                mContext = appContext.createAttributionContext(context.getAttributionTag());
-            }
-        } else {
-            mContext = context;
-        }
+        mContext = mergeAttributionAndRenouncedPermissions(context.getApplicationContext(),
+            context);
         mSubscriptionManager = SubscriptionManager.from(mContext);
     }
 
@@ -418,6 +412,34 @@
         return sInstance;
     }
 
+    // This method takes the Application context and adds the attributionTag
+    // and renouncedPermissions from the given context.
+    private Context mergeAttributionAndRenouncedPermissions(Context to, Context from) {
+        Context contextToReturn = from;
+        if (to != null) {
+            if (!Objects.equals(from.getAttributionTag(), to.getAttributionTag())) {
+                contextToReturn = to.createAttributionContext(from.getAttributionTag());
+            } else {
+                contextToReturn = to;
+            }
+
+            Set<String> renouncedPermissions =
+                    from.getAttributionSource().getRenouncedPermissions();
+            if (!renouncedPermissions.isEmpty()) {
+                if (to.getParams() != null) {
+                    contextToReturn = contextToReturn.createContext(
+                            new ContextParams.Builder(to.getParams())
+                                    .setRenouncedPermissions(renouncedPermissions).build());
+                } else {
+                    contextToReturn = contextToReturn.createContext(
+                            new ContextParams.Builder()
+                                    .setRenouncedPermissions(renouncedPermissions).build());
+                }
+            }
+        }
+        return contextToReturn;
+    }
+
     private String getOpPackageName() {
         // For legacy reasons the TelephonyManager has API for getting
         // a static instance with no context set preventing us from
@@ -448,6 +470,16 @@
         return null;
     }
 
+    private Set<String> getRenouncedPermissions() {
+        // For legacy reasons the TelephonyManager has API for getting
+        // a static instance with no context set preventing us from
+        // getting the attribution source.
+        if (mContext != null) {
+            return mContext.getAttributionSource().getRenouncedPermissions();
+        }
+        return Collections.emptySet();
+    }
+
     /**
      * Post a runnable to the BackgroundThread.
      *
@@ -6308,8 +6340,14 @@
                 (TelephonyRegistryManager)
                         mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
         if (telephonyRegistry != null) {
-            telephonyRegistry.listenFromListener(mSubId, getOpPackageName(),
-                    getAttributionTag(), listener, events, notifyNow);
+            Set<String> renouncedPermissions = getRenouncedPermissions();
+            boolean renounceFineLocationAccess = renouncedPermissions
+                    .contains(Manifest.permission.ACCESS_FINE_LOCATION);
+            boolean renounceCoarseLocationAccess = renouncedPermissions
+                    .contains(Manifest.permission.ACCESS_COARSE_LOCATION);
+            telephonyRegistry.listenFromListener(mSubId, renounceFineLocationAccess,
+                    renounceCoarseLocationAccess, getOpPackageName(), getAttributionTag(),
+                    listener, events, notifyNow);
         } else {
             Rlog.w(TAG, "telephony registry not ready.");
         }
@@ -12132,7 +12170,10 @@
     })
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
     public @Nullable ServiceState getServiceState() {
-        return getServiceState(false, false);
+        return getServiceState(getRenouncedPermissions()
+                    .contains(Manifest.permission.ACCESS_FINE_LOCATION),
+                               getRenouncedPermissions()
+                    .contains(Manifest.permission.ACCESS_COARSE_LOCATION));
     }
 
     /**
@@ -12144,6 +12185,11 @@
      * If you want continuous updates of service state info, register a {@link PhoneStateListener}
      * via {@link #listen} with the {@link PhoneStateListener#LISTEN_SERVICE_STATE} event.
      *
+     * There's another way to renounce permissions with a custom context
+     * {@code AttributionSource.Builder#setRenouncedPermissions(Set<String>)} but only for system
+     * apps. To avoid confusion, calling this method supersede renouncing permissions with a
+     * custom context.
+     *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges})
      * and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
@@ -12187,8 +12233,7 @@
             ITelephony service = getITelephony();
             if (service != null) {
                 return service.getServiceStateForSubscriber(subId, renounceFineLocationAccess,
-                        renounceCoarseLocationAccess,
-                        getOpPackageName(), getAttributionTag());
+                        renounceCoarseLocationAccess, getOpPackageName(), getAttributionTag());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#getServiceStateForSubscriber", e);
@@ -16123,7 +16168,10 @@
      */
     public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull TelephonyCallback callback) {
-        registerTelephonyCallback(false, false, executor, callback);
+        registerTelephonyCallback(
+                getRenouncedPermissions().contains(Manifest.permission.ACCESS_FINE_LOCATION),
+                getRenouncedPermissions().contains(Manifest.permission.ACCESS_COARSE_LOCATION),
+                executor, callback);
     }
 
     /**
@@ -16153,6 +16201,12 @@
      * instability. If a process has registered too many callbacks without unregistering them, it
      * may encounter an {@link IllegalStateException} when trying to register more callbacks.
      *
+     * <p>
+     * There's another way to renounce permissions with a custom context
+     * {@code AttributionSource.Builder#setRenouncedPermissions(Set<String>)} but only for system
+     * apps. To avoid confusion, calling this method supersede renouncing permissions with a
+     * custom context.
+     *
      * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
      * location related information which will be sent if the caller already possess
      * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permissions.
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 8e10f6b..fc94ebf 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -369,6 +369,10 @@
     public @interface AuthType {}
 
     // Possible values for protocol which is defined in TS 27.007 section 10.1.1.
+    /** Unknown protocol.
+     * @hide
+     */
+    public static final int PROTOCOL_UNKNOWN = -1;
     /** Internet protocol. */
     public static final int PROTOCOL_IP = 0;
     /** Internet protocol, version 6. */
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/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/test-runner/src/android/test/IsolatedContext.java b/test-runner/src/android/test/IsolatedContext.java
index dd4a9a3..d5f92a3 100644
--- a/test-runner/src/android/test/IsolatedContext.java
+++ b/test-runner/src/android/test/IsolatedContext.java
@@ -17,6 +17,7 @@
 package android.test;
 
 import android.accounts.AccountManager;
+import android.content.AttributionSource;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -26,6 +27,7 @@
 import android.content.ServiceConnection;
 import android.content.pm.PackageManager;
 import android.net.Uri;
+import android.os.Process;
 import android.test.mock.MockAccountManager;
 
 import java.io.File;
@@ -64,6 +66,15 @@
     }
 
     @Override
+    public AttributionSource getAttributionSource() {
+        AttributionSource attributionSource = super.getAttributionSource();
+        if (attributionSource == null) {
+            return new AttributionSource.Builder(Process.myUid()).build();
+        }
+        return attributionSource;
+    }
+
+    @Override
     public ContentResolver getContentResolver() {
         // We need to return the real resolver so that MailEngine.makeRight can get to the
         // subscribed feeds provider. TODO: mock out subscribed feeds too.
diff --git a/tests/AttestationVerificationTest/Android.bp b/tests/AttestationVerificationTest/Android.bp
index a4741eed..b98f8cb 100644
--- a/tests/AttestationVerificationTest/Android.bp
+++ b/tests/AttestationVerificationTest/Android.bp
@@ -40,5 +40,6 @@
         "androidx.test.rules",
         "androidx.test.ext.junit",
         "platform-test-annotations",
+        "services.core",
     ],
 }
diff --git a/tests/AttestationVerificationTest/AndroidManifest.xml b/tests/AttestationVerificationTest/AndroidManifest.xml
index c42bde9..37321ad8 100755
--- a/tests/AttestationVerificationTest/AndroidManifest.xml
+++ b/tests/AttestationVerificationTest/AndroidManifest.xml
@@ -24,6 +24,7 @@
     <application>
         <uses-library android:name="android.test.runner"/>
         <activity android:name=".SystemAttestationVerificationTest$TestActivity" />
+        <activity android:name=".PeerDeviceSystemAttestationVerificationTest$TestActivity" />
     </application>
 
     <!--  self-instrumenting test package. -->
diff --git a/tests/AttestationVerificationTest/assets/test_attestation_with_root_certs.pem b/tests/AttestationVerificationTest/assets/test_attestation_with_root_certs.pem
new file mode 100644
index 0000000..e29ff48
--- /dev/null
+++ b/tests/AttestationVerificationTest/assets/test_attestation_with_root_certs.pem
@@ -0,0 +1,81 @@
+-----BEGIN CERTIFICATE-----
+MIICkjCCAjmgAwIBAgIBATAKBggqhkjOPQQDAjA5MQwwCgYDVQQMDANURUUxKTAn
+BgNVBAUTIDg2ZTQ0MjRhMjY2NDlhZDcyZWZhNWM0MWEwM2IyN2QxMCAXDTcwMDEw
+MTAwMDAwMFoYDzIxMDYwMjA3MDYyODE1WjAfMR0wGwYDVQQDDBRBbmRyb2lkIEtl
+eXN0b3JlIEtleTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIlTwcvhe+DLV45X
+RCTO7HoN20Ib7IbCEhV5+YdMiYOp/0AdKk8oYvsri1XODeC4zcoPfHNdQGt/68i0
+ADbilJmjggFIMIIBRDAOBgNVHQ8BAf8EBAMCB4AwggEwBgorBgEEAdZ5AgERBIIB
+IDCCARwCAQMKAQECAQQKAQEECXBsYXllcjQ1NgQAMFe/hT0IAgYBfvkgVei/hUVH
+BEUwQzEdMBsEFmNvbS5nb29nbGUuYXR0ZXN0YXRpb24CAQExIgQgOqyVXRJUdAGY
+/XVx8y/uRPiebqlyELt1EpqIz29h5tUwgaehCDEGAgECAgEDogMCAQOjBAICAQCl
+CDEGAgEEAgEGqgMCAQG/g3cCBQC/hT4DAgEAv4VATDBKBCCEZx8qY8Ys0HC2TqPq
+74eYPzh5L/agxD7Bn7zVBQHoNAEB/woBAAQguJwoDfWBjRaedzQ6TJPFJJKs+ytr
++8Vu2CSmqifFBHW/hUEFAgMB1MC/hUIFAgMDFdm/hU4GAgQBNIjJv4VPBgIEATSI
+yTAKBggqhkjOPQQDAgNHADBEAiBdGxfMEx59k5+zo+hV3Q9kgjbGi0zU3WH355P5
+JZttBwIgY4FZsSreUJL8RY3JvfvD8BRw8GuXcB1OQ600hwaYYC4=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIB8zCCAXqgAwIBAgIRAOuuukN0OHbNQvKngECkewEwCgYIKoZIzj0EAwIwOTEM
+MAoGA1UEDAwDVEVFMSkwJwYDVQQFEyA3MDkxMmRmNDYxMDRmYWFlOTQ3ODY0ZTU4
+MDRmMWY4ZDAeFw0yMDA5MjgyMDI3NTZaFw0zMDA5MjYyMDI3NTZaMDkxDDAKBgNV
+BAwMA1RFRTEpMCcGA1UEBRMgODZlNDQyNGEyNjY0OWFkNzJlZmE1YzQxYTAzYjI3
+ZDEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT3Mjl05ewv6G8zAR4fXJy2iadU
+yK7rNvzlECy2+nhEieL8BFXDvo0tx5fYs8qr67j/KvluFBfp2r9s+ckWz3Kzo2Mw
+YTAdBgNVHQ4EFgQUsVKBzAs1lMXAauQ3mGAJZJqK5tAwHwYDVR0jBBgwFoAUEsQA
+i8d2oLULSi5Ix4BTGGbvUEkwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AgQwCgYIKoZIzj0EAwIDZwAwZAIwfFziBCwuM1thLUSUNI61Xx/vnDnNkSv/aX5D
+yLjxbLlgnFSzIrc+6vf6h6L/+TjYAjAq6h9GKtMn4R0286MoqYqzp/rHn6JD2sqH
+iM8KZ0oA+Ut242EcmGjAoNfGZGZGddQ=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDkzCCAXugAwIBAgIQNTAX5z3CBac6nD3hQiMDcDANBgkqhkiG9w0BAQsFADAb
+MRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MB4XDTIwMDkyODIwMjUwMloXDTMw
+MDkyNjIwMjUwMlowOTEMMAoGA1UEDAwDVEVFMSkwJwYDVQQFEyA3MDkxMmRmNDYx
+MDRmYWFlOTQ3ODY0ZTU4MDRmMWY4ZDB2MBAGByqGSM49AgEGBSuBBAAiA2IABA/7
+xZFlFtTjdy2B3p7E+FsrBjyhBSqY4a9FywawXMJRSja3HAK36ruzJjWlEkD+D0vq
+HI2joY39FHmWoZWwm2cq9gOleFGYOSCpMr4ib7xtq/6nefvKTP5rutxudF97t6Nj
+MGEwHQYDVR0OBBYEFBLEAIvHdqC1C0ouSMeAUxhm71BJMB8GA1UdIwQYMBaAFDZh
+4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
+AgIEMA0GCSqGSIb3DQEBCwUAA4ICAQAaMONDQxJz3PRn9gHQW5KP+TIoBPJZyGa1
+QFuEBcMDTtIxBxEh5Pj3ivPBc76PrdYu5U47Ve5YYCPsTpUTj7dOxbzGSZjfjvHF
+fNwy24g1Lah2iAdQRVErhWKBlpnQhBnnRrrNmTTmzhl8NvSExqAPP746dqwm1kQ7
+YesC5yoEAHpxamhlZpIKAjSxSZeHWace2qV00M8qWd/7lIpqttJjFFrhCjzR0dtr
+oIIpC5EtmqIWdLeg6yZjJkX+Cjv4F8mRfBtwuNuxFsfALQ3D5l8WKw3iwPebmCy1
+kEby8Eoq88FxzXQp/XgAaljlrKXyuxptrc1noRuob4g42Oh6wetueYRSCtO6Bkym
+0UMnld/kG77aeiHOMVVb86wrhNuAGir1vgDGOBsclITVyuu9ka0YVQjjDm3phTpd
+O8JV16gbei2Phn+FfRV1MSDsZo/wu0i2KVzgs27bfJocMHXv+GzvwfefYgMJ/rYq
+Bg27lpsWzmFEPv2cyhA5PwwbG8ceswa3RZE/2eS9o7STkz93jr/KsKLcMBY6cX2C
+q4CBJByKFJtVANOVj+neFNxc2sQgeTT33yYNKbe4b5bm7Ki1FbrhFVckpzUGDnKs
+gL+AxvALWOoryDGwNbJiW8PRiD3HHByiMvSEQ7e7BSc2KjbsaWbCfYZAMZJEhEsc
+P1l8lcUVuA==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFHDCCAwSgAwIBAgIJANUP8luj8tazMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
+BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTkxMTIyMjAzNzU4WhcNMzQxMTE4MjAz
+NzU4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS
+Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7
+tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj
+nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq
+C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ
+oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O
+JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg
+sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi
+igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M
+RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E
+aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um
+AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud
+IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBOMaBc8oumXb2voc7XCWnu
+XKhBBK3e2KMGz39t7lA3XXRe2ZLLAkLM5y3J7tURkf5a1SutfdOyXAmeE6SRo83U
+h6WszodmMkxK5GM4JGrnt4pBisu5igXEydaW7qq2CdC6DOGjG+mEkN8/TA6p3cno
+L/sPyz6evdjLlSeJ8rFBH6xWyIZCbrcpYEJzXaUOEaxxXxgYz5/cTiVKN2M1G2ok
+QBUIYSY6bjEL4aUN5cfo7ogP3UvliEo3Eo0YgwuzR2v0KR6C1cZqZJSTnghIC/vA
+D32KdNQ+c3N+vl2OTsUVMC1GiWkngNx1OO1+kXW+YTnnTUOtOIswUP/Vqd5SYgAI
+mMAfY8U9/iIgkQj6T2W6FsScy94IN9fFhE1UtzmLoBIuUFsVXJMTz+Jucth+IqoW
+Fua9v1R93/k98p41pjtFX+H8DslVgfP097vju4KDlqN64xV1grw3ZLl4CiOe/A91
+oeLm2UHOq6wn3esB4r2EIQKb6jTVGu5sYCcdWpXr0AUVqcABPdgL+H7qJguBw09o
+jm6xNIrw2OocrDKsudk/okr/AwqEyPKw9WnMlQgLIKw1rODG2NvU9oR3GVGdMkUB
+ZutL8VuFkERQGt6vQ2OCw0sV47VMkuYbacK/xyZFiRcrPJPb41zgbQj9XAEyLKCH
+ex0SdDrx+tWUDqG8At2JHA==
+-----END CERTIFICATE-----
diff --git a/tests/AttestationVerificationTest/assets/test_attestation_wrong_root_certs.pem b/tests/AttestationVerificationTest/assets/test_attestation_wrong_root_certs.pem
new file mode 100644
index 0000000..3d6410a
--- /dev/null
+++ b/tests/AttestationVerificationTest/assets/test_attestation_wrong_root_certs.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIGCDCCBHCgAwIBAgIBATANBgkqhkiG9w0BAQsFADApMRkwFwYDVQQFExAyZGM1OGIyZDFhMjQx
+MzI2MQwwCgYDVQQMDANURUUwIBcNNzAwMTAxMDAwMDAwWhgPMjEwNjAyMDcwNjI4MTVaMB8xHTAb
+BgNVBAMMFEFuZHJvaWQgS2V5c3RvcmUgS2V5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
+AQEApNVcnyN40MANMbbo2nMGNq2NNysDSjfLm0W3i6wPKf0ffCYkhWM4dCmQKKf50uAZTBeTit4c
+NwXeZn3qellMlOsIN3Qc384rfN/8cikrRvUAgibz0Jy7STykjwa7x6tKwqITxbO8HqAhKo8/BQXU
+xzrOdIg5ciy+UM7Vgh7a7ogen0KL2iGgrsalb1ti7Vlzb6vIJ4WzIC3TGD2sCkoPahghwqFDZZCo
+/FzaLoNY0jAUX2mL+kf8aUaoxz7xA9FTvgara+1pLBR1s4c8xPS2HdZipcVXWfey0wujv1VAKs4+
+tXjKlHkYBHBBceEjxUtEmrapSQEdpHPv7Xh9Uanq4QIDAQABo4ICwTCCAr0wDgYDVR0PAQH/BAQD
+AgeAMIICqQYKKwYBBAHWeQIBEQSCApkwggKVAgEDCgEBAgEECgEBBANhYmMEADCCAc2/hT0IAgYB
+ZOYGEYe/hUWCAbsEggG3MIIBszGCAYswDAQHYW5kcm9pZAIBHTAZBBRjb20uYW5kcm9pZC5rZXlj
+aGFpbgIBHTAZBBRjb20uYW5kcm9pZC5zZXR0aW5ncwIBHTAZBBRjb20ucXRpLmRpYWdzZXJ2aWNl
+cwIBHTAaBBVjb20uYW5kcm9pZC5keW5zeXN0ZW0CAR0wHQQYY29tLmFuZHJvaWQuaW5wdXRkZXZp
+Y2VzAgEdMB8EGmNvbS5hbmRyb2lkLmxvY2FsdHJhbnNwb3J0AgEdMB8EGmNvbS5hbmRyb2lkLmxv
+Y2F0aW9uLmZ1c2VkAgEdMB8EGmNvbS5hbmRyb2lkLnNlcnZlci50ZWxlY29tAgEdMCAEG2NvbS5h
+bmRyb2lkLndhbGxwYXBlcmJhY2t1cAIBHTAhBBxjb20uZ29vZ2xlLlNTUmVzdGFydERldGVjdG9y
+AgEdMCIEHWNvbS5nb29nbGUuYW5kcm9pZC5oaWRkZW5tZW51AgEBMCMEHmNvbS5hbmRyb2lkLnBy
+b3ZpZGVycy5zZXR0aW5ncwIBHTEiBCAwGqPLCBE0UBxF8UIqvGbCQiT9Xe1f3I8X5pcXb9hmqjCB
+rqEIMQYCAQICAQOiAwIBAaMEAgIIAKUFMQMCAQSmCDEGAgEDAgEFv4FIBQIDAQABv4N3AgUAv4U+
+AwIBAL+FQEwwSgQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQAKAQIEIHKNsSdP
+HxzxVx3kOAsEilVKxKOA529TVQg1KQhKk3gBv4VBAwIBAL+FQgUCAwMUs7+FTgUCAwMUs7+FTwUC
+AwMUszANBgkqhkiG9w0BAQsFAAOCAYEAJMIuzdNUdfrE6sIdmsnMn/scSG2odbphj8FkX9JGdF2S
+OT599HuDY9qhvkru2Dza4sLKK3f4ViBhuR9lpfeprKvstxbtBO7jkLYfVn0ZRzHRHVEyiW5IVKh+
+qOXVJ9S1lMShOTlsaYJytLKIlcrRAZBEXZiNbzTuVh1CH6X9Ni1dog14snm+lcOeORdL9fht2CHa
+u/caRnpWiZbjoAoJp0O89uBrRkXPpln51+3jPY6AFny30grNAvKguauDcPPhNV1yR+ylSsQi2gm3
+Rs4pgtlxFLMfZLgT0cbkl+9zk/QUqlpBP8ftUBsOI0ARr8xhFN3cvq9kXGLtJ9hEP9PRaflAFREk
+DK3IBIbVcAFZBFoAQOdE9zy0+F5bQrznPGaZg4Dzhcx33qMDUTgHtWoy+k3ePGQMEtmoTTLgQywW
+OIkXEoFqqGi9GKJXUT1KYi5NsigaYqu7FoN4Qsvs61pMUEfZSPP2AFwkA8uNFbmb9uxcxaGHCA8i
+3i9VM6yOLIrP
+-----END CERTIFICATE-----
diff --git a/tests/AttestationVerificationTest/assets/test_no_attestation_ext_certs.pem b/tests/AttestationVerificationTest/assets/test_no_attestation_ext_certs.pem
new file mode 100644
index 0000000..6d261fa
--- /dev/null
+++ b/tests/AttestationVerificationTest/assets/test_no_attestation_ext_certs.pem
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFoDCCA4igAwIBAgIQTfpKgAsLZJhp2V4xUriMADANBgkqhkiG9w0BAQ0FADBp
+MQswCQYDVQQGEwJVUzEUMBIGA1UECgwLR29vZ2xlIEluYy4xFzAVBgNVBAsMDkFu
+ZHJvaWQgVGhpbmdzMSswKQYDVQQDDCJBbmRyb2lkIFRoaW5ncyBBdHRlc3RhdGlv
+biBSb290IENBMCAXDTE3MDYyMTIwMjQzN1oYDzIwNTcwNjExMjAyNDM3WjBpMQsw
+CQYDVQQGEwJVUzEUMBIGA1UECgwLR29vZ2xlIEluYy4xFzAVBgNVBAsMDkFuZHJv
+aWQgVGhpbmdzMSswKQYDVQQDDCJBbmRyb2lkIFRoaW5ncyBBdHRlc3RhdGlvbiBS
+b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuO82oerGivb9
+G9bWyM8Pg0y6SOnAC8/8b92dp1v4Npnc+QpjPRUKgn8lzjQ9Jo6IGY3OShRBiQYl
+bbZYkfJnC5HtqbOETdPLZclErVE/G6Oda1IeZWvQVMjNImEYOLL5ct2RxiPttd8v
+SLyOSNFPf5/SeFqX/La0NcmXMOvPSrTW3qO34brnC+ih7mlpJFLz6Up93N3Umxsl
+IElz2wCG72t6k3+caWLyIPVgIPmsQrfTeBK/hN5dAJgAN65BsTevLHRP9J610wj3
+RagSIK1NdTuJRnr5ZyTQrwE2nA8H3IJ7/eo6IlGhXPwLKDhbdxYygPxdlCq6Rl96
+aVLjfpqDPtJ9ow+QKZuEDbYJ4z4olNXC6O5G7vqnCuULA/2E7y7DZObjzXOrdx2z
+9YKd8BrIDMTN/5mmw2us8tywiaQhbl8vOtjU+A+iBBnkj/wt9TYyLKopdrDlo5mz
+wy5l750HOkVZXC3VkeECnp+9duSHdS4qeUf/W1j9nPM7kY0HFLPUVX9AFVp2JXnC
+iKZC32GQAVsDc1iyAZWAVTqA7E0fBHhk9jUnA0W9b5Lq06oW95ngNR1MIFY871i8
+aLHCBpIix8DuMe8NB9spCIP6WCQqGiWQQpzbeuBPtoi424xwZTO4oectTd77bs9V
+Rvunn49fz308KnoWjk/by1N7gWyTb38CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMDQ1I0RKwFCI+Fy9uIIJ/HrXuqu
+MA0GCSqGSIb3DQEBDQUAA4ICAQB09qkyEpEDocdN5pPeXqtjj9d0AXREUGH2LhnC
+z9KZcUFR+JskwEMHCaOENOmKI3zWRmxT7d8cVywwGk+ExE7EBQoeHlh3Yo44M8aj
+ZL7RHCvHRYsePhAJkYpJ02IMR60TV+1jhMqE8+BnqFivS7kft4t295EyrnLRZE3b
+Nfc0t011j02RwUrioR57mdvS9EZBRnMQkobhn+jWt9O+V3mtplW+1A2n4ec6uni1
+2MMgAWHuO1sKVYd5Sp4JMUpNnfmQAMnNiOMF6VxkpaoF1lZWo4TrLxuDKJG3O8h1
+fByjCpNVY8kOvvYEadbldzh6Agy/3ppb9yfG7X7FtHr1ghNjuNT6w5VgvbRtoRja
+/ZSKuJMaKm5emMWNkls/cwVSPJIvTOzPTeYK1BKSyAL2LDJ93HI7x8h79/Q7gKRi
+kL8qT7GW2FqpWTK0253sJHqCJJP4A5Rxtf2+Afwqadfc6Ga4jJHb7rPXngz4j1ZB
+gl5yjXgWF9wHGxqrjKWe2EA3d47BC4HG3Rf5L56KQiRPhTqTk5vtZwtwLRLFDLt7
+Hdff13O1oLhn+2z9xkASUL3rFE/qWajZP7fk3CvzcuXwKDTZomIC4nNaglx4nLdj
+lHhOq+6ON8MZC46sLStD+D4a9A1HOoihJgI/yGGkwdrp4KQIveRkEBO/x9v3NNBE
+bMwG9w==
+-----END CERTIFICATE-----
diff --git a/tests/AttestationVerificationTest/assets/test_root_certs.pem b/tests/AttestationVerificationTest/assets/test_root_certs.pem
new file mode 100644
index 0000000..c51851fe
--- /dev/null
+++ b/tests/AttestationVerificationTest/assets/test_root_certs.pem
@@ -0,0 +1,61 @@
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
+BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYy
+ODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS
+Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7
+tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj
+nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq
+C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ
+oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O
+JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg
+sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi
+igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M
+RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E
+aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um
+AGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYD
+VR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAO
+BgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lk
+Lmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQAD
+ggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfB
+Pb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00m
+qC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rY
+DBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPm
+QUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4u
+JU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyD
+CdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79Iy
+ZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxD
+qwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23Uaic
+MDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1
+wDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIFHDCCAwSgAwIBAgIJANUP8luj8tazMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
+BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTkxMTIyMjAzNzU4WhcNMzQxMTE4MjAz
+NzU4WjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS
+Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7
+tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj
+nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq
+C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ
+oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O
+JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg
+sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi
+igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M
+RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E
+aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um
+AGMCAwEAAaNjMGEwHQYDVR0OBBYEFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMB8GA1Ud
+IwQYMBaAFDZh4QB8iAUJUYtEbEf/GkzJ6k8SMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4ICAQBOMaBc8oumXb2voc7XCWnu
+XKhBBK3e2KMGz39t7lA3XXRe2ZLLAkLM5y3J7tURkf5a1SutfdOyXAmeE6SRo83U
+h6WszodmMkxK5GM4JGrnt4pBisu5igXEydaW7qq2CdC6DOGjG+mEkN8/TA6p3cno
+L/sPyz6evdjLlSeJ8rFBH6xWyIZCbrcpYEJzXaUOEaxxXxgYz5/cTiVKN2M1G2ok
+QBUIYSY6bjEL4aUN5cfo7ogP3UvliEo3Eo0YgwuzR2v0KR6C1cZqZJSTnghIC/vA
+D32KdNQ+c3N+vl2OTsUVMC1GiWkngNx1OO1+kXW+YTnnTUOtOIswUP/Vqd5SYgAI
+mMAfY8U9/iIgkQj6T2W6FsScy94IN9fFhE1UtzmLoBIuUFsVXJMTz+Jucth+IqoW
+Fua9v1R93/k98p41pjtFX+H8DslVgfP097vju4KDlqN64xV1grw3ZLl4CiOe/A91
+oeLm2UHOq6wn3esB4r2EIQKb6jTVGu5sYCcdWpXr0AUVqcABPdgL+H7qJguBw09o
+jm6xNIrw2OocrDKsudk/okr/AwqEyPKw9WnMlQgLIKw1rODG2NvU9oR3GVGdMkUB
+ZutL8VuFkERQGt6vQ2OCw0sV47VMkuYbacK/xyZFiRcrPJPb41zgbQj9XAEyLKCH
+ex0SdDrx+tWUDqG8At2JHA==
+-----END CERTIFICATE-----
diff --git a/tests/AttestationVerificationTest/assets/test_virtual_device_attestation_certs.pem b/tests/AttestationVerificationTest/assets/test_virtual_device_attestation_certs.pem
new file mode 100644
index 0000000..2827710
--- /dev/null
+++ b/tests/AttestationVerificationTest/assets/test_virtual_device_attestation_certs.pem
@@ -0,0 +1,50 @@
+-----BEGIN CERTIFICATE-----
+MIIC7DCCApGgAwIBAgIBATAKBggqhkjOPQQDAjCBiDELMAkGA1UEBhMCVVMxEzAR
+BgNVBAgMCkNhbGlmb3JuaWExFTATBgNVBAoMDEdvb2dsZSwgSW5jLjEQMA4GA1UE
+CwwHQW5kcm9pZDE7MDkGA1UEAwwyQW5kcm9pZCBLZXlzdG9yZSBTb2Z0d2FyZSBB
+dHRlc3RhdGlvbiBJbnRlcm1lZGlhdGUwHhcNNzAwMTAxMDAwMDAwWhcNNjkxMjMx
+MjM1OTU5WjAfMR0wGwYDVQQDDBRBbmRyb2lkIEtleXN0b3JlIEtleTBZMBMGByqG
+SM49AgEGCCqGSM49AwEHA0IABEYtCH28qu+St0F0TixVsQz0L/Y7DcRHgYAU98E6
+edwOpACFmmseYxMjvmZv/4jURSG2/Z0J1s3A/qFzIY96/tyjggFSMIIBTjALBgNV
+HQ8EBAMCB4AwggEcBgorBgEEAdZ5AgERBIIBDDCCAQgCAQQKAQACASkKAQAECXBs
+YXllcjQ1NgQAMIHqoQgxBgIBAgIBA6IDAgEDowQCAgEApQgxBgIBBAIBBqoDAgEB
+v4N3AgUAv4U9CAIGAX8DoY9Qv4U+AwIBAL+FQEwwSgQgAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAABAQAKAQIEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAv4VBBQIDAa2wv4VCBQIDAxUbv4VFRwRFMEMxHTAbBBZjb20uZ29v
+Z2xlLmF0dGVzdGF0aW9uAgEBMSIEIDqslV0SVHQBmP11cfMv7kT4nm6pchC7dRKa
+iM9vYebVMAAwHwYDVR0jBBgwFoAUP/ys1hqxOp6BILjVJRzFZbsekakwCgYIKoZI
+zj0EAwIDSQAwRgIhAMzs7gWWBIITpeLeEEx9B8ihdhkFqpMGlsYLRO01ZIOeAiEA
+uKs9xfK3fIOpVAhDmsrp+zE8KUwyvqCU/IS13tXz7Ng=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICeDCCAh6gAwIBAgICEAEwCgYIKoZIzj0EAwIwgZgxCzAJBgNVBAYTAlVTMRMw
+EQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYD
+VQQKDAxHb29nbGUsIEluYy4xEDAOBgNVBAsMB0FuZHJvaWQxMzAxBgNVBAMMKkFu
+ZHJvaWQgS2V5c3RvcmUgU29mdHdhcmUgQXR0ZXN0YXRpb24gUm9vdDAeFw0xNjAx
+MTEwMDQ2MDlaFw0yNjAxMDgwMDQ2MDlaMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE
+CAwKQ2FsaWZvcm5pYTEVMBMGA1UECgwMR29vZ2xlLCBJbmMuMRAwDgYDVQQLDAdB
+bmRyb2lkMTswOQYDVQQDDDJBbmRyb2lkIEtleXN0b3JlIFNvZnR3YXJlIEF0dGVz
+dGF0aW9uIEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABOue
+efhCY1msyyqRTImGzHCtkGaTgqlzJhP+rMv4ISdMIXSXSir+pblNf2bU4GUQZjW8
+U7ego6ZxWD7bPhGuEBSjZjBkMB0GA1UdDgQWBBQ//KzWGrE6noEguNUlHMVlux6R
+qTAfBgNVHSMEGDAWgBTIrel3TEXDo88NFhDkeUM6IVowzzASBgNVHRMBAf8ECDAG
+AQH/AgEAMA4GA1UdDwEB/wQEAwIChDAKBggqhkjOPQQDAgNIADBFAiBLipt77oK8
+wDOHri/AiZi03cONqycqRZ9pDMfDktQPjgIhAO7aAV229DLp1IQ7YkyUBO86fMy9
+Xvsiu+f+uXc/WT/7
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIICizCCAjKgAwIBAgIJAKIFntEOQ1tXMAoGCCqGSM49BAMCMIGYMQswCQYDVQQG
+EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmll
+dzEVMBMGA1UECgwMR29vZ2xlLCBJbmMuMRAwDgYDVQQLDAdBbmRyb2lkMTMwMQYD
+VQQDDCpBbmRyb2lkIEtleXN0b3JlIFNvZnR3YXJlIEF0dGVzdGF0aW9uIFJvb3Qw
+HhcNMTYwMTExMDA0MzUwWhcNMzYwMTA2MDA0MzUwWjCBmDELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT
+BgNVBAoMDEdvb2dsZSwgSW5jLjEQMA4GA1UECwwHQW5kcm9pZDEzMDEGA1UEAwwq
+QW5kcm9pZCBLZXlzdG9yZSBTb2Z0d2FyZSBBdHRlc3RhdGlvbiBSb290MFkwEwYH
+KoZIzj0CAQYIKoZIzj0DAQcDQgAE7l1ex+HA220Dpn7mthvsTWpdamguD/9/SQ59
+dx9EIm29sa/6FsvHrcV30lacqrewLVQBXT5DKyqO107sSHVBpKNjMGEwHQYDVR0O
+BBYEFMit6XdMRcOjzw0WEOR5QzohWjDPMB8GA1UdIwQYMBaAFMit6XdMRcOjzw0W
+EOR5QzohWjDPMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgKEMAoGCCqG
+SM49BAMCA0cAMEQCIDUho++LNEYenNVg8x1YiSBq3KNlQfYNns6KGYxmSGB7AiBN
+C/NR2TB8fVvaNTQdqEcbY6WFZTytTySn502vQX3xvw==
+-----END CERTIFICATE-----
diff --git a/tests/AttestationVerificationTest/src/android/security/attestationverification/PeerDeviceSystemAttestationVerificationTest.kt b/tests/AttestationVerificationTest/src/android/security/attestationverification/PeerDeviceSystemAttestationVerificationTest.kt
new file mode 100644
index 0000000..32c2230
--- /dev/null
+++ b/tests/AttestationVerificationTest/src/android/security/attestationverification/PeerDeviceSystemAttestationVerificationTest.kt
@@ -0,0 +1,161 @@
+package android.security.attestationverification
+
+import android.app.Activity
+import android.os.Bundle
+import android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE
+import android.security.attestationverification.AttestationVerificationManager.PARAM_PUBLIC_KEY
+import android.security.attestationverification.AttestationVerificationManager.PROFILE_PEER_DEVICE
+import android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE
+import android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE
+import android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY
+import android.security.attestationverification.AttestationVerificationManager.TYPE_UNKNOWN
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+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 java.io.ByteArrayOutputStream
+import java.security.cert.CertificateFactory
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.TimeUnit
+
+/** Test for system-defined attestation verifiers. */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class PeerDeviceSystemAttestationVerificationTest {
+
+    @get:Rule
+    val rule = ActivityScenarioRule(TestActivity::class.java)
+
+    private val certifcateFactory = CertificateFactory.getInstance("X.509")
+    private lateinit var activity: Activity
+    private lateinit var avm: AttestationVerificationManager
+    private lateinit var invalidAttestationByteArray: ByteArray
+
+    @Before
+    fun setup() {
+        rule.getScenario().onActivity {
+            avm = it.getSystemService(AttestationVerificationManager::class.java)
+            activity = it
+        }
+        invalidAttestationByteArray = TEST_ATTESTATION_CERT_FILENAME.fromPEMFileToByteArray()
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureWrongBindingType() {
+        val future = CompletableFuture<Int>()
+        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        avm.verifyAttestation(profile, TYPE_UNKNOWN, Bundle(),
+            invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
+            future.complete(result)
+        }
+
+        assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureEmptyRequirements() {
+        val future = CompletableFuture<Int>()
+        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(),
+            invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
+            future.complete(result)
+        }
+
+        assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureMismatchBindingType() {
+        val future = CompletableFuture<Int>()
+        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        val publicKeyRequirements = Bundle()
+        publicKeyRequirements.putByteArray(PARAM_PUBLIC_KEY, "publicKeyStr".encodeToByteArray())
+        avm.verifyAttestation(profile, TYPE_CHALLENGE, publicKeyRequirements,
+            invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
+            future.complete(result)
+        }
+
+        assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
+
+        val future2 = CompletableFuture<Int>()
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "challengeStr".encodeToByteArray())
+        avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, challengeRequirements,
+            invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
+            future2.complete(result)
+        }
+
+        assertThat(future2.getSoon()).isEqualTo(RESULT_FAILURE)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureWrongResourceKey() {
+        val future = CompletableFuture<Int>()
+        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        val wrongKeyRequirements = Bundle()
+        wrongKeyRequirements.putByteArray("wrongReqKey", "publicKeyStr".encodeToByteArray())
+        avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, wrongKeyRequirements,
+            invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
+            future.complete(result)
+        }
+
+        assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureEmptyAttestation() {
+        val future = CompletableFuture<Int>()
+        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        val requirements = Bundle()
+        requirements.putByteArray(PARAM_PUBLIC_KEY, "publicKeyStr".encodeToByteArray())
+        avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, requirements, ByteArray(0),
+            activity.mainExecutor) { result, _ ->
+            future.complete(result)
+        }
+
+        assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureTrustAnchorMismatch() {
+        val future = CompletableFuture<Int>()
+        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray())
+        avm.verifyAttestation(profile, TYPE_CHALLENGE, challengeRequirements,
+            invalidAttestationByteArray, activity.mainExecutor) { result, _ ->
+            future.complete(result)
+        }
+        assertThat(future.getSoon()).isEqualTo(RESULT_FAILURE)
+    }
+
+    private fun <T> CompletableFuture<T>.getSoon(): T {
+        return this.get(1, TimeUnit.SECONDS)
+    }
+
+    private fun String.fromPEMFileToByteArray(): ByteArray {
+        val certs = certifcateFactory.generateCertificates(
+            InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets()
+                .open(this))
+        val bos = ByteArrayOutputStream()
+        certs.forEach {
+            bos.write(it.encoded)
+        }
+        return bos.toByteArray()
+    }
+
+    class TestActivity : Activity() {
+        override fun onCreate(savedInstanceState: Bundle?) {
+            super.onCreate(savedInstanceState)
+        }
+    }
+
+    companion object {
+        private const val TEST_ATTESTATION_CERT_FILENAME = "test_attestation_wrong_root_certs.pem"
+    }
+}
diff --git a/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt b/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt
index 6290292..169effa 100644
--- a/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt
+++ b/tests/AttestationVerificationTest/src/android/security/attestationverification/SystemAttestationVerificationTest.kt
@@ -12,8 +12,8 @@
 import org.junit.runner.RunWith
 import com.google.common.truth.Truth.assertThat
 import android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE
-import android.security.attestationverification.AttestationVerificationManager.PROFILE_PEER_DEVICE
 import android.security.attestationverification.AttestationVerificationManager.PROFILE_SELF_TRUSTED
+import android.security.attestationverification.AttestationVerificationManager.PROFILE_UNKNOWN
 import android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE
 import android.security.attestationverification.AttestationVerificationManager.RESULT_SUCCESS
 import android.security.attestationverification.AttestationVerificationManager.RESULT_UNKNOWN
@@ -52,7 +52,7 @@
     @Test
     fun verifyAttestation_returnsUnknown() {
         val future = CompletableFuture<Int>()
-        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        val profile = AttestationProfile(PROFILE_UNKNOWN)
         avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0),
                 activity.mainExecutor) { result, _ ->
             future.complete(result)
@@ -137,7 +137,7 @@
     @Test
     fun verifyToken_returnsUnknown() {
         val future = CompletableFuture<Int>()
-        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        val profile = AttestationProfile(PROFILE_SELF_TRUSTED)
         avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0),
                 activity.mainExecutor) { _, token ->
             val result = avm.verifyToken(profile, TYPE_PUBLIC_KEY, Bundle(), token, null)
@@ -150,7 +150,7 @@
     @Test
     fun verifyToken_tooBigMaxAgeThrows() {
         val future = CompletableFuture<VerificationToken>()
-        val profile = AttestationProfile(PROFILE_PEER_DEVICE)
+        val profile = AttestationProfile(PROFILE_SELF_TRUSTED)
         avm.verifyAttestation(profile, TYPE_PUBLIC_KEY, Bundle(), ByteArray(0),
                 activity.mainExecutor) { _, token ->
             future.complete(token)
diff --git a/tests/AttestationVerificationTest/src/com/android/server/security/AndroidKeystoreAttestationVerificationAttributesTest.java b/tests/AttestationVerificationTest/src/com/android/server/security/AndroidKeystoreAttestationVerificationAttributesTest.java
new file mode 100644
index 0000000..0d15fe7
--- /dev/null
+++ b/tests/AttestationVerificationTest/src/com/android/server/security/AndroidKeystoreAttestationVerificationAttributesTest.java
@@ -0,0 +1,297 @@
+/*
+ * 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.security;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/** Test for data class holding parsed X509Certificate attestation attributes. */
+@RunWith(AndroidJUnit4.class)
+public class AndroidKeystoreAttestationVerificationAttributesTest {
+    @Rule public ExpectedException mException = ExpectedException.none();
+    private static final String TEST_PHYSCIAL_DEVICE_CERTS =
+            "test_attestation_wrong_root_certs.pem";
+    private static final String TEST_PHYSICAL_DEVICE_CERTS_2 =
+            "test_attestation_with_root_certs.pem";
+    private static final String TEST_VIRTUAL_DEVICE_CERTS =
+            "test_virtual_device_attestation_certs.pem";
+    private static final String TEST_CERT_NO_ATTESTATION_EXTENSION =
+            "test_no_attestation_ext_certs.pem";
+    private static final String TEST_CERTS_NO_ATTESTATION_EXTENSION_2 =
+            "test_root_certs.pem";
+
+
+    private CertificateFactory mFactory;
+    private AndroidKeystoreAttestationVerificationAttributes mPhysicalDeviceAttributes;
+    private AndroidKeystoreAttestationVerificationAttributes mPhysicalDeviceAttributes2;
+    private AndroidKeystoreAttestationVerificationAttributes mVirtualDeviceAttributes;
+
+    @Before
+    public void setUp() throws Exception {
+        mFactory = CertificateFactory.getInstance("X.509");
+        mPhysicalDeviceAttributes =
+                AndroidKeystoreAttestationVerificationAttributes.fromCertificate(
+                        generateCertificate(TEST_PHYSCIAL_DEVICE_CERTS));
+        mPhysicalDeviceAttributes2 =
+                AndroidKeystoreAttestationVerificationAttributes.fromCertificate(
+                        generateCertificates(TEST_PHYSICAL_DEVICE_CERTS_2).get(0));
+        mVirtualDeviceAttributes =
+                AndroidKeystoreAttestationVerificationAttributes.fromCertificate(
+                        generateCertificates(TEST_VIRTUAL_DEVICE_CERTS).get(0));
+    }
+
+    @Test
+    public void parseCertificate_noAttestationExtension() throws Exception {
+        List<X509Certificate> certsNoAttestation =
+                generateCertificates(TEST_CERTS_NO_ATTESTATION_EXTENSION_2);
+        certsNoAttestation.add(generateCertificate(TEST_CERT_NO_ATTESTATION_EXTENSION));
+        for (X509Certificate cert: certsNoAttestation) {
+            mException.expect(CertificateEncodingException.class);
+            mException.expectMessage(
+                    CoreMatchers.containsString("No attestation extension found in certificate."));
+
+            AndroidKeystoreAttestationVerificationAttributes.fromCertificate(cert);
+        }
+    }
+
+    @Test
+    public void  parseCertificate_attestationLevel() {
+        assertThat(mPhysicalDeviceAttributes.getAttestationVersion()).isEqualTo(3);
+        assertThat(mPhysicalDeviceAttributes2.getAttestationVersion()).isEqualTo(3);
+        assertThat(mVirtualDeviceAttributes.getAttestationVersion()).isEqualTo(4);
+    }
+
+    @Test
+    public void  parseCertificate_attestationSecurityLevel() {
+        assertThat(mPhysicalDeviceAttributes.getAttestationSecurityLevel()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT);
+        assertThat(mPhysicalDeviceAttributes2.getAttestationSecurityLevel()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT);
+        assertThat(mVirtualDeviceAttributes.getAttestationSecurityLevel()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.SOFTWARE);
+    }
+
+    @Test
+    public void  parseCertificate_isAttestationHardwareBacked() {
+        assertThat(mPhysicalDeviceAttributes.isAttestationHardwareBacked()).isTrue();
+        assertThat(mPhysicalDeviceAttributes2.isAttestationHardwareBacked()).isTrue();
+        assertThat(mVirtualDeviceAttributes.isAttestationHardwareBacked()).isFalse();
+    }
+
+    @Test
+    public void  parseCertificate_keymasterLevel() {
+        assertThat(mPhysicalDeviceAttributes.getKeymasterVersion()).isEqualTo(4);
+        assertThat(mPhysicalDeviceAttributes2.getKeymasterVersion()).isEqualTo(4);
+        assertThat(mVirtualDeviceAttributes.getKeymasterVersion()).isEqualTo(41);
+    }
+
+    @Test
+    public void  parseCertificate_keymasterSecurityLevel() {
+        assertThat(mPhysicalDeviceAttributes.getKeymasterSecurityLevel()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT);
+        assertThat(mPhysicalDeviceAttributes2.getKeymasterSecurityLevel()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.TRUSTED_ENVIRONMENT);
+        assertThat(mVirtualDeviceAttributes.getKeymasterSecurityLevel()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.SecurityLevel.SOFTWARE);
+    }
+
+    @Test
+    public void  parseCertificate_isKeymasterHardwareBacked() {
+        assertThat(mPhysicalDeviceAttributes.isKeymasterHardwareBacked()).isTrue();
+        assertThat(mPhysicalDeviceAttributes2.isKeymasterHardwareBacked()).isTrue();
+        assertThat(mVirtualDeviceAttributes.isKeymasterHardwareBacked()).isFalse();
+    }
+
+    @Test
+    public void  parseCertificate_attestationChallenge() {
+        assertThat(mPhysicalDeviceAttributes.getAttestationChallenge().toByteArray()).isEqualTo(
+                "abc".getBytes(UTF_8));
+        assertThat(mPhysicalDeviceAttributes2.getAttestationChallenge().toByteArray()).isEqualTo(
+                "player456".getBytes(UTF_8));
+        assertThat(mVirtualDeviceAttributes.getAttestationChallenge().toByteArray()).isEqualTo(
+                "player456".getBytes(UTF_8));
+    }
+
+    @Test
+    public void  parseCertificate_verifiedBootState() {
+        assertThat(mPhysicalDeviceAttributes.getVerifiedBootState()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.VerifiedBootState.UNVERIFIED);
+        assertThat(mPhysicalDeviceAttributes2.getVerifiedBootState()).isEqualTo(
+                AndroidKeystoreAttestationVerificationAttributes.VerifiedBootState.VERIFIED);
+        assertThat(mVirtualDeviceAttributes.getVerifiedBootState()).isNull();
+    }
+
+    @Test
+    public void  parseCertificate_keyBootPatchLevel() {
+        assertThat(mPhysicalDeviceAttributes.getKeyBootPatchLevel()).isEqualTo(201907);
+        assertThat(mPhysicalDeviceAttributes2.getKeyBootPatchLevel()).isEqualTo(20220105);
+    }
+
+    @Test
+    public void parseCertificate_keyBootPatchLevelNotSetException() {
+        mException.expect(IllegalStateException.class);
+        mException.expectMessage(
+                CoreMatchers.containsString("KeyBootPatchLevel is not set."));
+
+        mVirtualDeviceAttributes.getKeyBootPatchLevel();
+    }
+
+    @Test
+    public void  parseCertificate_keyOsPatchLevel() {
+        assertThat(mPhysicalDeviceAttributes.getKeyOsPatchLevel()).isEqualTo(201907);
+        assertThat(mPhysicalDeviceAttributes2.getKeyOsPatchLevel()).isEqualTo(202201);
+    }
+
+    @Test
+    public void parseCertificate_keyOsPatchLevelNotSetException() {
+        mException.expect(IllegalStateException.class);
+        mException.expectMessage(
+                CoreMatchers.containsString("KeyOsPatchLevel is not set."));
+
+        mVirtualDeviceAttributes.getKeyOsPatchLevel();
+    }
+
+    @Test
+    public void  parseCertificate_keyVendorPatchLevel() {
+        assertThat(mPhysicalDeviceAttributes.getKeyVendorPatchLevel()).isEqualTo(201907);
+        assertThat(mPhysicalDeviceAttributes2.getKeyVendorPatchLevel()).isEqualTo(20220105);
+    }
+
+    @Test
+    public void parseCertificate_keyVendorPatchLevelNotSetException() {
+        mException.expect(IllegalStateException.class);
+        mException.expectMessage(
+                CoreMatchers.containsString("KeyVendorPatchLevel is not set."));
+
+        mVirtualDeviceAttributes.getKeyVendorPatchLevel();
+    }
+
+    @Test
+    public void  parseCertificate_keyAuthenticatorType() {
+        assertThat(mPhysicalDeviceAttributes.getKeyAuthenticatorType()).isEqualTo(0);
+        assertThat(mPhysicalDeviceAttributes2.getKeyAuthenticatorType()).isEqualTo(0);
+    }
+
+    @Test
+    public void  parseCertificate_keyOsVersion() {
+        assertThat(mPhysicalDeviceAttributes.getKeyOsVersion()).isEqualTo(0);
+        assertThat(mPhysicalDeviceAttributes2.getKeyOsVersion()).isEqualTo(120000);
+    }
+
+    @Test
+    public void parseCertificate_keyOsVersionNotSetException() {
+        mException.expect(IllegalStateException.class);
+        mException.expectMessage(
+                CoreMatchers.containsString("KeyOsVersion is not set."));
+
+        mVirtualDeviceAttributes.getKeyOsVersion();
+    }
+
+    @Test
+    public void  parseCertificate_verifiedBootHash() {
+        assertThat(mPhysicalDeviceAttributes.getVerifiedBootHash()).isNotEmpty();
+        assertThat(mPhysicalDeviceAttributes2.getVerifiedBootHash()).isNotEmpty();
+    }
+
+    @Test
+    public void  parseCertificate_verifiedBootKey() {
+        assertThat(mPhysicalDeviceAttributes.getVerifiedBootKey()).isNotEmpty();
+        assertThat(mPhysicalDeviceAttributes2.getVerifiedBootKey()).isNotEmpty();
+    }
+
+    @Test
+    public void  parseCertificate_isVerifiedBootLocked() {
+        assertThat(mPhysicalDeviceAttributes.isVerifiedBootLocked()).isFalse();
+        assertThat(mPhysicalDeviceAttributes2.isVerifiedBootLocked()).isTrue();
+    }
+
+    @Test
+    public void parseCertificate_isVerifiedBootLockedNotSetException() {
+        mException.expect(IllegalStateException.class);
+        mException.expectMessage(
+                CoreMatchers.containsString("VerifiedBootLocked is not set."));
+
+        mVirtualDeviceAttributes.isVerifiedBootLocked();
+    }
+
+    @Test
+    public void  parseCertificate_applicationPackageNameVersion() {
+        assertThat(mPhysicalDeviceAttributes.getApplicationPackageNameVersion()).isNotEmpty();
+    }
+
+    @Test
+    public void  parseCertificate_applicationCertificateDigests() {
+        assertThat(mPhysicalDeviceAttributes.getApplicationCertificateDigests()).isNotEmpty();
+    }
+
+    @Test
+    public void parseCertificate_valuesNotSet() {
+        assertThat(mPhysicalDeviceAttributes.getDeviceBrand()).isNull();
+        assertThat(mPhysicalDeviceAttributes.getDeviceName()).isNull();
+        assertThat(mPhysicalDeviceAttributes.getDeviceProductName()).isNull();
+        assertThat(mPhysicalDeviceAttributes.isKeyAllowedForAllApplications()).isFalse();
+        assertThat(mPhysicalDeviceAttributes2.getDeviceBrand()).isNull();
+        assertThat(mPhysicalDeviceAttributes2.getDeviceName()).isNull();
+        assertThat(mPhysicalDeviceAttributes2.getDeviceProductName()).isNull();
+        assertThat(mPhysicalDeviceAttributes2.isKeyAllowedForAllApplications()).isFalse();
+    }
+
+    @Test
+    public void parseCertificate_keyRequiresUnlockedDeviceNotSetException() {
+        mException.expect(IllegalStateException.class);
+        mException.expectMessage(
+                CoreMatchers.containsString("KeyRequiresUnlockedDevice is not set."));
+
+        mPhysicalDeviceAttributes.isKeyRequiresUnlockedDevice();
+    }
+
+    private X509Certificate generateCertificate(String certificateString)
+            throws Exception {
+        return generateCertificates(certificateString).get(0);
+    }
+
+    private List<X509Certificate> generateCertificates(String certificateString)
+            throws Exception {
+        Collection<? extends Certificate> certificates = mFactory.generateCertificates(
+                InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets()
+                        .open(certificateString));
+
+        ArrayList<X509Certificate> x509Certs = new ArrayList<>();
+        for (Certificate cert : certificates) {
+            x509Certs.add((X509Certificate) cert);
+        }
+        return x509Certs;
+    }
+}
diff --git a/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt b/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt
new file mode 100644
index 0000000..45f2e5c
--- /dev/null
+++ b/tests/AttestationVerificationTest/src/com/android/server/security/AttestationVerificationPeerDeviceVerifierTest.kt
@@ -0,0 +1,175 @@
+package com.android.server.security
+
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.security.attestationverification.AttestationVerificationManager.PARAM_CHALLENGE
+import android.security.attestationverification.AttestationVerificationManager.PARAM_PUBLIC_KEY
+import android.security.attestationverification.AttestationVerificationManager.RESULT_FAILURE
+import android.security.attestationverification.AttestationVerificationManager.RESULT_SUCCESS
+import android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE
+import android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+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.MockitoAnnotations
+import java.io.ByteArrayOutputStream
+import java.security.cert.Certificate
+import java.security.cert.CertificateFactory
+import java.security.cert.TrustAnchor
+import java.security.cert.X509Certificate
+import java.time.LocalDate
+
+/** Test for Peer Device attestation verifier. */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class AttestationVerificationPeerDeviceVerifierTest {
+    private val certificateFactory = CertificateFactory.getInstance("X.509")
+    @Mock private lateinit var context: Context
+    private lateinit var trustAnchors: HashSet<TrustAnchor>
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        val rootCerts = TEST_ROOT_CERT_FILENAME.fromPEMFileToCerts()
+        trustAnchors = HashSet<TrustAnchor>()
+        rootCerts.forEach {
+            trustAnchors.add(TrustAnchor(it as X509Certificate, null))
+        }
+    }
+
+    @Test
+    fun verifyAttestation_returnsSuccessTypeChallenge() {
+        val verifier = AttestationVerificationPeerDeviceVerifier(
+            context, trustAnchors, false, LocalDate.of(2022, 2, 1),
+            LocalDate.of(2021, 8, 1))
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray())
+
+        val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements,
+            TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray())
+        assertThat(result).isEqualTo(RESULT_SUCCESS)
+    }
+
+    @Test
+    fun verifyAttestation_returnsSuccessLocalPatchOlderThanOneYear() {
+        val verifier = AttestationVerificationPeerDeviceVerifier(
+            context, trustAnchors, false, LocalDate.of(2022, 2, 1),
+            LocalDate.of(2021, 1, 1))
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray())
+
+        val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements,
+            TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray())
+        assertThat(result).isEqualTo(RESULT_SUCCESS)
+    }
+
+    @Test
+    fun verifyAttestation_returnsSuccessTypePublicKey() {
+        val verifier = AttestationVerificationPeerDeviceVerifier(
+            context, trustAnchors, false, LocalDate.of(2022, 2, 1),
+            LocalDate.of(2021, 8, 1))
+
+        val leafCert =
+            (TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToCerts() as List)[0]
+                    as X509Certificate
+        val pkRequirements = Bundle()
+        pkRequirements.putByteArray(PARAM_PUBLIC_KEY, leafCert.publicKey.encoded)
+
+        val result = verifier.verifyAttestation(
+            TYPE_PUBLIC_KEY, pkRequirements,
+            TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray())
+        assertThat(result).isEqualTo(RESULT_SUCCESS)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailurePatchDateNotWithinOneYearLocalPatch() {
+        val verifier = AttestationVerificationPeerDeviceVerifier(
+            context, trustAnchors, false, LocalDate.of(2023, 3, 1),
+            LocalDate.of(2023, 2, 1))
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray())
+
+        val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements,
+            TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray())
+        assertThat(result).isEqualTo(RESULT_FAILURE)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureTrustedAnchorEmpty() {
+        val verifier = AttestationVerificationPeerDeviceVerifier(
+            context, HashSet(), false, LocalDate.of(2022, 1, 1),
+            LocalDate.of(2022, 1, 1))
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray())
+
+        val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements,
+            TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray())
+        assertThat(result).isEqualTo(RESULT_FAILURE)
+    }
+
+    @Test
+    fun verifyAttestation_returnsFailureTrustedAnchorMismatch() {
+        val badTrustAnchorsCerts = TEST_ATTESTATION_CERT_FILENAME.fromPEMFileToCerts()
+        val badTrustAnchors = HashSet<TrustAnchor>()
+        badTrustAnchorsCerts.forEach {
+            badTrustAnchors.add(TrustAnchor(it as X509Certificate, null))
+        }
+
+        val verifier = AttestationVerificationPeerDeviceVerifier(
+            context, badTrustAnchors, false, LocalDate.of(2022, 1, 1),
+            LocalDate.of(2022, 1, 1))
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "player456".encodeToByteArray())
+
+        val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements,
+            TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray())
+        assertThat(result).isEqualTo(RESULT_FAILURE)
+    }
+
+    fun verifyAttestation_returnsFailureChallenge() {
+        val verifier = AttestationVerificationPeerDeviceVerifier(
+            context, trustAnchors, false, LocalDate.of(2022, 1, 1),
+            LocalDate.of(2022, 1, 1))
+        val challengeRequirements = Bundle()
+        challengeRequirements.putByteArray(PARAM_CHALLENGE, "wrong".encodeToByteArray())
+
+        val result = verifier.verifyAttestation(TYPE_CHALLENGE, challengeRequirements,
+            TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME.fromPEMFileToByteArray())
+        assertThat(result).isEqualTo(RESULT_FAILURE)
+    }
+
+    private fun String.fromPEMFileToCerts(): Collection<Certificate> {
+        return certificateFactory.generateCertificates(
+            InstrumentationRegistry.getInstrumentation().getContext().getResources().getAssets()
+                .open(this))
+    }
+
+    private fun String.fromPEMFileToByteArray(): ByteArray {
+        val certs = this.fromPEMFileToCerts()
+        val bos = ByteArrayOutputStream()
+        certs.forEach {
+            bos.write(it.encoded)
+        }
+        return bos.toByteArray()
+    }
+
+    class TestActivity : Activity() {
+        override fun onCreate(savedInstanceState: Bundle?) {
+            super.onCreate(savedInstanceState)
+        }
+    }
+
+    companion object {
+        private const val TEST_ROOT_CERT_FILENAME = "test_root_certs.pem"
+        private const val TEST_ATTESTATION_WITH_ROOT_CERT_FILENAME =
+            "test_attestation_with_root_certs.pem"
+        private const val TEST_ATTESTATION_CERT_FILENAME = "test_attestation_wrong_root_certs.pem"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
index 8d60466..4cddd85 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppTransition.kt
@@ -60,7 +60,7 @@
         }
         teardown {
             test {
-                testApp.exit()
+                testApp.exit(wmHelper)
             }
         }
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
index 7ee6451..5bd365c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -64,7 +64,6 @@
             device.waitForIdle()
         } else {
             wmHelper.waitImeShown()
-            wmHelper.waitForAppTransitionIdle()
         }
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
index b66c45c7..a135e0a 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/TwoActivitiesAppHelper.kt
@@ -53,8 +53,8 @@
         button.click()
 
         device.wait(Until.gone(launchActivityButton), FIND_TIMEOUT)
-        wmHelper.waitForFullScreenApp(secondActivityComponent)
         wmHelper.waitFor(
+            WindowManagerStateHelper.isAppFullScreen(secondActivityComponent),
             WindowManagerConditionsFactory.isAppTransitionIdle(Display.DEFAULT_DISPLAY),
             WindowManagerConditionsFactory.hasLayersAnimating().negate()
         )
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 ba5698c..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 {
@@ -88,7 +93,7 @@
             }
             transitions {
                 device.reopenAppFromOverview(wmHelper)
-                require(wmHelper.waitImeShown()) { "IME didn't show in time" }
+                wmHelper.waitImeShown()
             }
             teardown {
                 test {
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/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
index 19e2c92..7e3ed82 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
@@ -18,6 +18,7 @@
 
 import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
+import android.view.Display
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.filters.RequiresDevice
@@ -35,6 +36,8 @@
 import com.android.server.wm.flicker.navBarWindowIsVisible
 import com.android.server.wm.flicker.statusBarWindowIsVisible
 import com.android.server.wm.traces.common.FlickerComponentName
+import com.android.server.wm.traces.common.WindowManagerConditionsFactory
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 
 import org.junit.FixMethodOrder
 import org.junit.Test
@@ -64,12 +67,22 @@
                 eachRun {
                     this.setRotation(testSpec.startRotation)
                     testApp.launchViaIntent(wmHelper)
-                    wmHelper.waitForFullScreenApp(testApp.component)
-                    wmHelper.waitForAppTransitionIdle()
+                    val testAppVisible = wmHelper.waitFor(
+                        WindowManagerStateHelper.isAppFullScreen(testApp.component),
+                        WindowManagerConditionsFactory.isAppTransitionIdle(
+                            Display.DEFAULT_DISPLAY))
+                    require(testAppVisible) {
+                        "Expected ${testApp.component.toWindowName()} to be visible"
+                    }
 
                     imeTestApp.launchViaIntent(wmHelper)
-                    wmHelper.waitForFullScreenApp(testApp.component)
-                    wmHelper.waitForAppTransitionIdle()
+                    val imeAppVisible = wmHelper.waitFor(
+                        WindowManagerStateHelper.isAppFullScreen(imeTestApp.component),
+                        WindowManagerConditionsFactory.isAppTransitionIdle(
+                            Display.DEFAULT_DISPLAY))
+                    require(imeAppVisible) {
+                        "Expected ${imeTestApp.component.toWindowName()} to be visible"
+                    }
 
                     imeTestApp.openIME(device, wmHelper)
                 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
index b5e13be..cc808a0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
@@ -18,6 +18,7 @@
 
 import android.app.Instrumentation
 import android.platform.test.annotations.Presubmit
+import android.view.Display
 import androidx.test.filters.RequiresDevice
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.server.wm.flicker.entireScreenCovered
@@ -30,7 +31,9 @@
 import com.android.server.wm.flicker.dsl.FlickerBuilder
 import com.android.server.wm.flicker.helpers.TwoActivitiesAppHelper
 import com.android.server.wm.flicker.testapp.ActivityOptions
+import com.android.server.wm.traces.common.WindowManagerConditionsFactory
 import com.android.server.wm.traces.parser.toFlickerComponent
+import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper
 import org.junit.FixMethodOrder
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -77,14 +80,16 @@
             }
             teardown {
                 test {
-                    testApp.exit()
+                    testApp.exit(wmHelper)
                 }
             }
             transitions {
                 testApp.openSecondActivity(device, wmHelper)
                 device.pressBack()
-                wmHelper.waitForAppTransitionIdle()
-                wmHelper.waitForFullScreenApp(testApp.component)
+                val firstActivityVisible = wmHelper.waitFor(
+                    WindowManagerConditionsFactory.isAppTransitionIdle(Display.DEFAULT_DISPLAY),
+                    WindowManagerStateHelper.isAppFullScreen(testApp.component))
+                require(firstActivityVisible) { "Expected ${testApp.component} to be visible" }
             }
         }
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
index 53560cc..4313b8d 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppTransition.kt
@@ -56,7 +56,7 @@
         }
         teardown {
             test {
-                testApp.exit()
+                testApp.exit(wmHelper)
             }
         }
     }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index f21b1d6..48b8779 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -17,12 +17,12 @@
 package com.android.server.wm.flicker.quickswitch
 
 import android.app.Instrumentation
-import android.platform.test.annotations.Postsubmit
 import android.platform.test.annotations.Presubmit
 import android.platform.test.annotations.RequiresDevice
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -66,6 +66,7 @@
 @Group1
 open class QuickSwitchBetweenTwoAppsBackTest(private val testSpec: FlickerTestParameter) {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val taplInstrumentation = LauncherInstrumentation()
 
     private val testApp1 = SimpleAppHelper(instrumentation)
     private val testApp2 = NonResizeableAppHelper(instrumentation)
@@ -81,6 +82,10 @@
     fun buildFlicker(): FlickerBuilder {
         return FlickerBuilder(instrumentation).apply {
             setup {
+                test {
+                    taplInstrumentation.setExpectedRotation(testSpec.startRotation)
+                }
+
                 eachRun {
                     testApp1.launchViaIntent(wmHelper)
                     wmHelper.waitForFullScreenApp(testApp1.component)
@@ -90,20 +95,11 @@
                 }
             }
             transitions {
-                // Swipe right from bottom to quick switch back
-                // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the middle
-                // as to not accidentally trigger a swipe back or forward action which would result
-                // in the same behavior but not testing quick swap.
-                device.swipe(
-                        startDisplayBounds.bounds.right / 3,
-                        startDisplayBounds.bounds.bottom,
-                        2 * startDisplayBounds.bounds.right / 3,
-                        startDisplayBounds.bounds.bottom,
-                        if (testSpec.isLandscapeOrSeascapeAtStart) 75 else 30
-                )
-
+                taplInstrumentation.launchedAppState.quickSwitchToPreviousApp()
                 wmHelper.waitForFullScreenApp(testApp1.component)
+                wmHelper.waitSnapshotGone()
                 wmHelper.waitForAppTransitionIdle()
+                wmHelper.waitForNavBarStatusBarVisible()
             }
 
             teardown {
@@ -119,7 +115,7 @@
      * Checks that the transition starts with [testApp2]'s windows filling/covering exactly the
      * entirety of the display.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun startsWithApp2WindowsCoverFullScreen() {
         testSpec.assertWmStart {
@@ -131,7 +127,7 @@
      * Checks that the transition starts with [testApp2]'s layers filling/covering exactly the
      * entirety of the display.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun startsWithApp2LayersCoverFullScreen() {
         testSpec.assertLayersStart {
@@ -154,7 +150,7 @@
      * Checks that [testApp1] windows fill the entire screen (i.e. is "fullscreen") at the end of the
      * transition once we have fully quick switched from [testApp2] back to the [testApp1].
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun endsWithApp1WindowsCoveringFullScreen() {
         testSpec.assertWmEnd {
@@ -166,7 +162,7 @@
      * Checks that [testApp1] layers fill the entire screen (i.e. is "fullscreen") at the end of the
      * transition once we have fully quick switched from [testApp2] back to the [testApp1].
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun endsWithApp1LayersCoveringFullScreen() {
         testSpec.assertLayersEnd {
@@ -178,7 +174,7 @@
      * Checks that [testApp1] is the top window at the end of the transition once we have fully quick
      * switched from [testApp2] back to the [testApp1].
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun endsWithApp1BeingOnTop() {
         testSpec.assertWmEnd {
@@ -190,7 +186,7 @@
      * Checks that [testApp1]'s window starts off invisible and becomes visible at some point before
      * the end of the transition and then stays visible until the end of the transition.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun app1WindowBecomesAndStaysVisible() {
         testSpec.assertWm {
@@ -206,7 +202,7 @@
      * Checks that [testApp1]'s layer starts off invisible and becomes visible at some point before
      * the end of the transition and then stays visible until the end of the transition.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun app1LayerBecomesAndStaysVisible() {
         testSpec.assertLayers {
@@ -220,7 +216,7 @@
      * Checks that [testApp2]'s window starts off visible and becomes invisible at some point before
      * the end of the transition and then stays invisible until the end of the transition.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun app2WindowBecomesAndStaysInvisible() {
         testSpec.assertWm {
@@ -234,7 +230,7 @@
      * Checks that [testApp2]'s layer starts off visible and becomes invisible at some point before
      * the end of the transition and then stays invisible until the end of the transition.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun app2LayerBecomesAndStaysInvisible() {
         testSpec.assertLayers {
@@ -249,7 +245,7 @@
      * Ensures that at any point, either [testApp1] or [testApp2]'s windows are at least partially
      * visible.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun app1WindowIsVisibleOnceApp2WindowIsInvisible() {
         testSpec.assertWm {
@@ -269,7 +265,7 @@
      * Ensures that at any point, either [testApp1] or [testApp2]'s windows are at least partially
      * visible.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun app1LayerIsVisibleOnceApp2LayerIsInvisible() {
         testSpec.assertLayers {
@@ -286,7 +282,7 @@
     /**
      * Checks that the navbar window is visible throughout the entire transition.
      */
-    @Postsubmit
+    @Presubmit
     @Test
     fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsVisible()
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index ce6a383..d6c8f46 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -22,6 +22,7 @@
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -50,7 +51,7 @@
 /**
  * Test quick switching back to previous app from last opened app
  *
- * To run this test: `atest FlickerTests:QuickSwitchBetweenTwoAppsBackTest`
+ * To run this test: `atest FlickerTests:QuickSwitchBetweenTwoAppsForwardTest`
  *
  * Actions:
  *     Launch an app [testApp1]
@@ -65,6 +66,7 @@
 @Group1
 open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTestParameter) {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val taplInstrumentation = LauncherInstrumentation()
 
     private val testApp1 = SimpleAppHelper(instrumentation)
     private val testApp2 = NonResizeableAppHelper(instrumentation)
@@ -73,6 +75,10 @@
     fun buildFlicker(): FlickerBuilder {
         return FlickerBuilder(instrumentation).apply {
             setup {
+                test {
+                    taplInstrumentation.setExpectedRotation(testSpec.startRotation)
+                }
+
                 eachRun {
                     testApp1.launchViaIntent(wmHelper)
                     wmHelper.waitForFullScreenApp(testApp1.component)
@@ -85,43 +91,25 @@
                         ?.layerStackSpace
                         ?: error("Display not found")
 
-                    // Swipe right from bottom to quick switch back
-                    // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the
-                    // middle as to not accidentally trigger a swipe back or forward action which
-                    // would result in the same behavior but not testing quick swap.
-                    device.swipe(
-                            startDisplayBounds.right / 3,
-                            startDisplayBounds.bottom,
-                            2 * startDisplayBounds.right / 3,
-                            startDisplayBounds.bottom,
-                            if (testSpec.isLandscapeOrSeascapeAtStart) 75 else 30
-                    )
+                    taplInstrumentation.launchedAppState.quickSwitchToPreviousApp()
 
                     wmHelper.waitForFullScreenApp(testApp1.component)
                     wmHelper.waitForAppTransitionIdle()
                 }
             }
             transitions {
-                // Swipe left from bottom to quick switch forward
-                // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the middle
-                // as to not accidentally trigger a swipe back or forward action which would result
-                // in the same behavior but not testing quick swap.
-                device.swipe(
-                        2 * startDisplayBounds.right / 3,
-                        startDisplayBounds.bottom,
-                        startDisplayBounds.right / 3,
-                        startDisplayBounds.bottom,
-                        if (testSpec.isLandscapeOrSeascapeAtStart) 75 else 30
-                )
+                taplInstrumentation.launchedAppState.quickSwitchToPreviousAppSwipeLeft()
 
                 wmHelper.waitForFullScreenApp(testApp2.component)
+                wmHelper.waitSnapshotGone()
                 wmHelper.waitForAppTransitionIdle()
+                wmHelper.waitForNavBarStatusBarVisible()
             }
 
             teardown {
                 test {
-                    testApp1.exit()
-                    testApp2.exit()
+                    testApp1.exit(wmHelper)
+                    testApp2.exit(wmHelper)
                 }
             }
         }
@@ -365,4 +353,4 @@
                     )
         }
     }
-}
\ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index 1a762bf..e5e2404 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -22,6 +22,7 @@
 import android.view.Surface
 import android.view.WindowManagerPolicyConstants
 import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.tapl.LauncherInstrumentation
 import com.android.server.wm.flicker.FlickerBuilderProvider
 import com.android.server.wm.flicker.FlickerParametersRunnerFactory
 import com.android.server.wm.flicker.FlickerTestParameter
@@ -62,13 +63,20 @@
 @Group4
 class QuickSwitchFromLauncherTest(private val testSpec: FlickerTestParameter) {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val taplInstrumentation = LauncherInstrumentation()
+
     private val testApp = SimpleAppHelper(instrumentation)
+
     private val startDisplayBounds = WindowUtils.getDisplayBounds(testSpec.startRotation)
 
     @FlickerBuilderProvider
     fun buildFlicker(): FlickerBuilder {
         return FlickerBuilder(instrumentation).apply {
             setup {
+                test {
+                    taplInstrumentation.setExpectedRotation(testSpec.startRotation)
+                }
+
                 eachRun {
                     testApp.launchViaIntent(wmHelper)
                     device.pressHome()
@@ -77,20 +85,10 @@
                 }
             }
             transitions {
-                // Swipe right from bottom to quick switch back
-                // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the middle
-                // as to not accidentally trigger a swipe back or forward action which would result
-                // in the same behavior but not testing quick swap.
-                device.swipe(
-                        startDisplayBounds.bounds.right / 3,
-                        startDisplayBounds.bounds.bottom,
-                        2 * startDisplayBounds.bounds.right / 3,
-                        startDisplayBounds.bounds.bottom,
-                        50
-                )
-
+                taplInstrumentation.workspace.quickSwitchToPreviousApp()
                 wmHelper.waitForFullScreenApp(testApp.component)
                 wmHelper.waitForAppTransitionIdle()
+                wmHelper.waitForNavBarStatusBarVisible()
             }
 
             teardown {
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/InputMethodStressTest/AndroidTest.xml b/tests/InputMethodStressTest/AndroidTest.xml
index b194010..fc54ca6 100644
--- a/tests/InputMethodStressTest/AndroidTest.xml
+++ b/tests/InputMethodStressTest/AndroidTest.xml
@@ -18,6 +18,11 @@
 
     <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
 
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="adb shell settings put secure show_ime_with_hard_keyboard 1" />
+        <option name="teardown-command" value="adb shell settings delete secure show_ime_with_hard_keyboard" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="InputMethodStressTest.apk" />
diff --git a/startop/iorap/stress/Android.bp b/tests/SurfaceViewSyncTest/Android.bp
similarity index 75%
rename from startop/iorap/stress/Android.bp
rename to tests/SurfaceViewSyncTest/Android.bp
index 6e8725d..1c6e380 100644
--- a/startop/iorap/stress/Android.bp
+++ b/tests/SurfaceViewSyncTest/Android.bp
@@ -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.
@@ -23,20 +23,9 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
-cc_binary {
-  name: "iorap.stress.memory",
-  srcs: ["main_memory.cc"],
-
-  cflags: [
-      "-Wall",
-      "-Wextra",
-      "-Werror",
-      "-Wno-unused-parameter"
-  ],
-
-  shared_libs: [
-      "libbase"
-  ],
-
-  host_supported: true,
+android_test {
+    name: "SurfaceViewSyncTest",
+    srcs: ["**/*.java"],
+    platform_apis: true,
+    certificate: "platform",
 }
diff --git a/tests/SurfaceViewSyncTest/AndroidManifest.xml b/tests/SurfaceViewSyncTest/AndroidManifest.xml
new file mode 100644
index 0000000..d085f8c
--- /dev/null
+++ b/tests/SurfaceViewSyncTest/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.test">
+    <application>
+        <activity android:name="SurfaceViewSyncActivity"
+            android:label="SurfaceView Sync Test"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/SurfaceViewSyncTest/OWNERS b/tests/SurfaceViewSyncTest/OWNERS
new file mode 100644
index 0000000..0862c05
--- /dev/null
+++ b/tests/SurfaceViewSyncTest/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/wm/OWNERS
diff --git a/tests/SurfaceViewSyncTest/res/layout/activity_surfaceview_sync.xml b/tests/SurfaceViewSyncTest/res/layout/activity_surfaceview_sync.xml
new file mode 100644
index 0000000..4433b21
--- /dev/null
+++ b/tests/SurfaceViewSyncTest/res/layout/activity_surfaceview_sync.xml
@@ -0,0 +1,47 @@
+<?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.

+-->

+

+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

+    xmlns:tools="http://schemas.android.com/tools"

+    android:id="@+id/container"

+    android:layout_width="match_parent"

+    android:layout_height="match_parent"

+    android:orientation="vertical"

+    android:background="@android:color/darker_gray"

+    tools:context="com.example.mysurfaceview.MainActivity">

+

+    <SurfaceView

+        android:id="@+id/surface_view"

+        android:layout_width="match_parent"

+        android:layout_height="600dp" />

+

+    <RelativeLayout

+        android:layout_width="match_parent"

+        android:layout_height="wrap_content">

+        <Button

+            android:text="COLLAPSE SV"

+            android:id="@+id/expand_sv"

+            android:layout_width="wrap_content"

+            android:layout_height="wrap_content"/>

+        <Switch

+            android:id="@+id/enable_sync_switch"

+            android:text="Enable Sync"

+            android:checked="true"

+            android:layout_alignParentEnd="true"

+            android:layout_width="wrap_content"

+            android:layout_height="wrap_content"/>

+    </RelativeLayout>

+</LinearLayout>
\ No newline at end of file
diff --git a/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
new file mode 100644
index 0000000..ab7f24a
--- /dev/null
+++ b/tests/SurfaceViewSyncTest/src/com/android/test/SurfaceViewSyncActivity.java
@@ -0,0 +1,198 @@
+/*
+ * 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.test;
+
+import android.annotation.NonNull;
+import android.app.Activity;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+import android.window.SurfaceSyncer;
+
+/**
+ * Test app that allows the user to resize the SurfaceView and have the new buffer sync with the
+ * main window. This tests that {@link SurfaceSyncer} is working correctly.
+ */
+public class SurfaceViewSyncActivity extends Activity implements SurfaceHolder.Callback {
+    private static final String TAG = "SurfaceViewSyncActivity";
+
+    private SurfaceView mSurfaceView;
+    private boolean mLastExpanded = true;
+
+    private RenderingThread mRenderingThread;
+
+    private final SurfaceSyncer mSurfaceSyncer = new SurfaceSyncer();
+
+    private Button mExpandButton;
+    private Switch mEnableSyncSwitch;
+
+    private int mLastSyncId = -1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_surfaceview_sync);
+        mSurfaceView = findViewById(R.id.surface_view);
+        mSurfaceView.getHolder().addCallback(this);
+
+        WindowManager windowManager = getWindowManager();
+        WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
+        Rect bounds = metrics.getBounds();
+
+        LinearLayout container = findViewById(R.id.container);
+        mExpandButton = findViewById(R.id.expand_sv);
+        mEnableSyncSwitch = findViewById(R.id.enable_sync_switch);
+        mExpandButton.setOnClickListener(view -> updateSurfaceViewSize(bounds, container));
+
+        mRenderingThread = new RenderingThread(mSurfaceView.getHolder());
+    }
+
+    private void updateSurfaceViewSize(Rect bounds, View container) {
+        if (mLastSyncId >= 0) {
+            return;
+        }
+
+        final float height;
+        if (mLastExpanded) {
+            height = bounds.height() / 2f;
+            mExpandButton.setText("EXPAND SV");
+        } else {
+            height = bounds.height() / 1.5f;
+            mExpandButton.setText("COLLAPSE SV");
+        }
+        mLastExpanded = !mLastExpanded;
+
+        if (mEnableSyncSwitch.isChecked()) {
+            mLastSyncId = mSurfaceSyncer.setupSync(() -> { });
+            mSurfaceSyncer.addToSync(mLastSyncId, container);
+        }
+
+        ViewGroup.LayoutParams svParams = mSurfaceView.getLayoutParams();
+        svParams.height = (int) height;
+        mSurfaceView.setLayoutParams(svParams);
+    }
+
+    @Override
+    public void surfaceCreated(@NonNull SurfaceHolder holder) {
+        final Canvas canvas = holder.lockCanvas();
+        canvas.drawARGB(255, 255, 0, 0);
+        holder.unlockCanvasAndPost(canvas);
+        mRenderingThread.startRendering();
+        mRenderingThread.renderFrame(null, mSurfaceView.getWidth(), mSurfaceView.getHeight());
+    }
+
+    @Override
+    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
+        if (mEnableSyncSwitch.isChecked()) {
+            if (mLastSyncId < 0) {
+                mRenderingThread.renderFrame(null, width, height);
+                return;
+            }
+            mSurfaceSyncer.addToSync(mLastSyncId, mSurfaceView, frameCallback ->
+                    mRenderingThread.renderFrame(frameCallback, width, height));
+            mSurfaceSyncer.markSyncReady(mLastSyncId);
+            mLastSyncId = -1;
+        } else {
+            mRenderingThread.renderFrame(null, width, height);
+        }
+    }
+
+    @Override
+    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
+        mRenderingThread.stopRendering();
+    }
+
+    private static class RenderingThread extends HandlerThread {
+        private final SurfaceHolder mSurfaceHolder;
+        private Handler mHandler;
+        private SurfaceSyncer.SurfaceViewFrameCallback mFrameCallback;
+        private final Point mSurfaceSize = new Point();
+
+        int mColorValue = 0;
+        int mColorDelta = 10;
+        private final Paint mPaint = new Paint();
+
+        RenderingThread(SurfaceHolder holder) {
+            super("RenderingThread");
+            mSurfaceHolder = holder;
+            mPaint.setColor(Color.BLACK);
+            mPaint.setTextSize(100);
+        }
+
+        public void renderFrame(SurfaceSyncer.SurfaceViewFrameCallback frameCallback, int width,
+                int height) {
+            if (mHandler != null) {
+                mHandler.post(() -> {
+                    mFrameCallback = frameCallback;
+                    mSurfaceSize.set(width, height);
+                    mRunnable.run();
+                });
+            }
+        }
+
+        private final Runnable mRunnable = new Runnable() {
+            @Override
+            public void run() {
+                if (mFrameCallback != null) {
+                    mFrameCallback.onFrameStarted();
+                }
+
+                try {
+                    // Long delay from start to finish to mimic slow draw
+                    Thread.sleep(1000);
+                } catch (InterruptedException e) {
+                }
+
+                mColorValue += mColorDelta;
+                if (mColorValue > 245 || mColorValue < 10) {
+                    mColorDelta *= -1;
+                }
+
+                Canvas c = mSurfaceHolder.lockCanvas();
+                c.drawRGB(255, 0, 0);
+                c.drawText("RENDERED CONTENT", 0, mSurfaceSize.y / 2, mPaint);
+                mSurfaceHolder.unlockCanvasAndPost(c);
+                mFrameCallback = null;
+            }
+        };
+
+        public void startRendering() {
+            start();
+            mHandler = new Handler(getLooper());
+        }
+
+        public void stopRendering() {
+            if (mHandler != null) {
+                mHandler.removeCallbacks(mRunnable);
+            }
+        }
+    }
+}
diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp
new file mode 100644
index 0000000..c9c6c5c
--- /dev/null
+++ b/tests/TrustTests/Android.bp
@@ -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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "TrustTests",
+    srcs: [
+        "src/**/*.kt",
+    ],
+    static_libs: [
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "androidx.test.uiautomator",
+        "truth-prebuilt",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+    test_suites: [
+        "device-tests",
+    ],
+    platform_apis: true,
+    certificate: "platform",
+}
diff --git a/tests/TrustTests/AndroidManifest.xml b/tests/TrustTests/AndroidManifest.xml
new file mode 100644
index 0000000..c94152d
--- /dev/null
+++ b/tests/TrustTests/AndroidManifest.xml
@@ -0,0 +1,75 @@
+<?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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.trust.test"
+          android:targetSandboxVersion="2">
+
+    <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
+    <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.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.PROVIDE_TRUST_AGENT" />
+    <uses-permission android:name="android.permission.TRUST_LISTENER" />
+
+    <application>
+        <uses-library android:name="android.test.runner"/>
+        <activity android:name="android.trust.TrustTestActivity"
+                  android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+
+        <service
+            android:name=".UserUnlockRequestTrustAgent"
+            android:exported="true"
+            android:label="Test Agent"
+            android:permission="android.permission.BIND_TRUST_AGENT">
+            <intent-filter>
+                <action android:name="android.service.trust.TrustAgentService" />
+            </intent-filter>
+        </service>
+
+        <service
+            android:name=".LockUserTrustAgent"
+            android:exported="true"
+            android:label="Test Agent"
+            android:permission="android.permission.BIND_TRUST_AGENT">
+            <intent-filter>
+                <action android:name="android.service.trust.TrustAgentService" />
+            </intent-filter>
+        </service>
+
+        <service
+            android:name=".GrantAndRevokeTrustAgent"
+            android:exported="true"
+            android:label="Test Agent"
+            android:permission="android.permission.BIND_TRUST_AGENT">
+            <intent-filter>
+                <action android:name="android.service.trust.TrustAgentService" />
+            </intent-filter>
+        </service>
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.trust.test">
+    </instrumentation>
+</manifest>
diff --git a/tests/TrustTests/AndroidTest.xml b/tests/TrustTests/AndroidTest.xml
new file mode 100644
index 0000000..61b711e
--- /dev/null
+++ b/tests/TrustTests/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?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.
+  -->
+<configuration description="TrustTests configuration">
+    <option name="test-tag" value="TrustTests" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="TrustTests.apk" />
+    </target_preparer>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.trust.test" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false" />
+    </test>
+</configuration>
diff --git a/tests/TrustTests/OWNERS b/tests/TrustTests/OWNERS
new file mode 100644
index 0000000..e2c6ce1
--- /dev/null
+++ b/tests/TrustTests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/trust/OWNERS
diff --git a/tests/TrustTests/README.md b/tests/TrustTests/README.md
new file mode 100644
index 0000000..3427e30
--- /dev/null
+++ b/tests/TrustTests/README.md
@@ -0,0 +1,40 @@
+# TrustTests framework tests
+
+These tests test the "trust" part of the platform primarily implemented via TrustManagerService in
+the system server and TrustAgentService in system apps.
+
+Tests are separated into separate files based on major groupings. When creating new tests, find a
+_closely_ matching existing test file or create a new test file. Prefer many test files over large
+test files.
+
+Each test file has its own trust agent. To create a new trust agent:
+
+1. Create a new class extending from `BaseTrustAgentService` class in your test file
+2. Add a new `<service>` stanza to `AndroidManifest.xml` in this directory for the new agent
+   following the pattern fo the existing agents.
+
+To run:
+
+```atest TrustTests```
+
+## Testing approach:
+
+1. Test the agent service as a black box; avoid inspecting internal state of the service or
+   modifying the system code outside of this directory.
+2. The primary interface to the system is through these three points:
+    1. `TrustAgentService`, your agent created by the `TrustAgentRule` and accessible via
+       the `agent` property of the rule.
+        1. Call command methods (e.g. `grantTrust`) directly on the agent
+        2. Listen to events (e.g. `onUserRequestedUnlock`) by implementing the method in
+           your test's agent class and tracking invocations. See `UserUnlockRequestTest` for an
+           example.
+    2. `TrustManager` which is the interface the rest of the system (e.g. SystemUI) has to the
+       service.
+        1. Through this API, simulate system events that the service cares about
+           (e.g. `reportUnlockAttempt`).
+    3. `TrustListener` which is the interface the rest of the system (e.g. SystemUI) uses to receive
+       events from the service.
+        1. Through this, verify behavior that affects the rest of the system. For example,
+           see `LockStateTrackingRule`.
+3. To re-use code between tests, prefer creating new rules alongside the existing rules or adding
+   functionality to a _closely_ matching existing rule.
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/BaseTrustAgentService.kt b/tests/TrustTests/src/android/trust/BaseTrustAgentService.kt
new file mode 100644
index 0000000..493f3bd
--- /dev/null
+++ b/tests/TrustTests/src/android/trust/BaseTrustAgentService.kt
@@ -0,0 +1,47 @@
+/*
+ * 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.trust
+
+import android.service.trust.TrustAgentService
+import android.util.Log
+import kotlin.reflect.KClass
+
+/**
+ * Base class for test trust agents.
+ */
+abstract class BaseTrustAgentService : TrustAgentService() {
+
+    override fun onCreate() {
+        super.onCreate()
+        Log.d(TAG, "${this::class.simpleName} created")
+        instances[this::class] = this
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        instances.remove(this::class)
+    }
+
+    companion object {
+        private val instances =
+            mutableMapOf<KClass<out BaseTrustAgentService>, BaseTrustAgentService>()
+        private const val TAG = "BaseTrustAgentService"
+
+        fun instance(serviceClass: KClass<out BaseTrustAgentService>): BaseTrustAgentService? {
+            return instances[serviceClass]!!
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java b/tests/TrustTests/src/android/trust/TrustTestActivity.kt
similarity index 63%
copy from packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
copy to tests/TrustTests/src/android/trust/TrustTestActivity.kt
index 2894780..6c56fea 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/WMModule.java
+++ b/tests/TrustTests/src/android/trust/TrustTestActivity.kt
@@ -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.
@@ -13,14 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package android.trust
 
-package com.android.systemui.dagger;
-
-import dagger.Module;
+import android.app.Activity
+import android.os.Bundle
 
 /**
- * Dagger module for including the WMComponent.
+ * Activity for testing Trust.
  */
-@Module(subcomponents = {WMComponent.class})
-public abstract class WMModule {
+class TrustTestActivity : Activity() {
+
+    public override fun onCreate(icicle: Bundle?) {
+        super.onCreate(icicle)
+        setTurnScreenOn(true)
+    }
 }
diff --git a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
new file mode 100644
index 0000000..790afd3
--- /dev/null
+++ b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.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 android.trust.test
+
+import android.trust.BaseTrustAgentService
+import android.trust.TrustTestActivity
+import android.trust.test.lib.LockStateTrackingRule
+import android.trust.test.lib.ScreenLockRule
+import android.trust.test.lib.TrustAgentRule
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import androidx.test.uiautomator.UiDevice
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
+
+/**
+ * Test for testing revokeTrust & grantTrust for non-renewable trust.
+ *
+ * atest TrustTests:GrantAndRevokeTrustTest
+ */
+@RunWith(AndroidJUnit4::class)
+class GrantAndRevokeTrustTest {
+    private val uiDevice = UiDevice.getInstance(getInstrumentation())
+    private val activityScenarioRule = ActivityScenarioRule(TrustTestActivity::class.java)
+    private val lockStateTrackingRule = LockStateTrackingRule()
+    private val trustAgentRule = TrustAgentRule<GrantAndRevokeTrustAgent>()
+
+    @get:Rule
+    val rule: RuleChain = RuleChain
+        .outerRule(activityScenarioRule)
+        .around(ScreenLockRule())
+        .around(lockStateTrackingRule)
+        .around(trustAgentRule)
+
+    @Before
+    fun manageTrust() {
+        trustAgentRule.agent.setManagingTrust(true)
+    }
+
+    // This test serves a baseline for Grant tests, verifying that the default behavior of the
+    // device is to lock when put to sleep
+    @Test
+    fun sleepingDeviceWithoutGrantLocksDevice() {
+        uiDevice.sleep()
+        await()
+
+        lockStateTrackingRule.assertLocked()
+    }
+
+    @Test
+    fun grantKeepsDeviceUnlocked() {
+        trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 10000, 0)
+        uiDevice.sleep()
+        await()
+
+        lockStateTrackingRule.assertUnlocked()
+    }
+
+    @Test
+    fun grantKeepsDeviceUnlocked_untilRevoked() {
+        trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, 0)
+        await()
+        uiDevice.sleep()
+        trustAgentRule.agent.revokeTrust()
+        await()
+
+        lockStateTrackingRule.assertLocked()
+    }
+
+    companion object {
+        private const val TAG = "GrantAndRevokeTrustTest"
+        private const val GRANT_MESSAGE = "granted by test"
+        private fun await() = Thread.sleep(250)
+    }
+}
+
+class GrantAndRevokeTrustAgent : BaseTrustAgentService()
diff --git a/tests/TrustTests/src/android/trust/test/LockUserTest.kt b/tests/TrustTests/src/android/trust/test/LockUserTest.kt
new file mode 100644
index 0000000..83fc28f
--- /dev/null
+++ b/tests/TrustTests/src/android/trust/test/LockUserTest.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.trust.test
+
+import android.trust.BaseTrustAgentService
+import android.trust.TrustTestActivity
+import android.trust.test.lib.LockStateTrackingRule
+import android.trust.test.lib.ScreenLockRule
+import android.trust.test.lib.TrustAgentRule
+import android.util.Log
+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
+import org.junit.runner.RunWith
+
+/**
+ * Test for testing lockUser.
+ *
+ * atest TrustTests:LockUserTest
+ */
+@RunWith(AndroidJUnit4::class)
+class LockUserTest {
+    private val activityScenarioRule = ActivityScenarioRule(TrustTestActivity::class.java)
+    private val lockStateTrackingRule = LockStateTrackingRule()
+    private val trustAgentRule = TrustAgentRule<LockUserTrustAgent>()
+
+    @get:Rule
+    val rule: RuleChain = RuleChain
+        .outerRule(activityScenarioRule)
+        .around(ScreenLockRule())
+        .around(lockStateTrackingRule)
+        .around(trustAgentRule)
+
+    @Ignore("Causes issues with subsequent tests") // TODO: Enable test
+    @Test
+    fun lockUser_locksTheDevice() {
+        Log.i(TAG, "Locking user")
+        trustAgentRule.agent.lockUser()
+        await()
+
+        assertThat(lockStateTrackingRule.lockState.locked).isTrue()
+    }
+
+    companion object {
+        private const val TAG = "LockUserTest"
+        private fun await() = Thread.sleep(250)
+    }
+}
+
+class LockUserTrustAgent : BaseTrustAgentService()
diff --git a/tests/TrustTests/src/android/trust/test/UserUnlockRequestTest.kt b/tests/TrustTests/src/android/trust/test/UserUnlockRequestTest.kt
new file mode 100644
index 0000000..f8783fb
--- /dev/null
+++ b/tests/TrustTests/src/android/trust/test/UserUnlockRequestTest.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.trust.test
+
+import android.app.trust.TrustManager
+import android.content.Context
+import android.trust.BaseTrustAgentService
+import android.trust.TrustTestActivity
+import android.trust.test.lib.ScreenLockRule
+import android.trust.test.lib.TrustAgentRule
+import android.util.Log
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.RuleChain
+import org.junit.runner.RunWith
+
+/**
+ * Test for testing the user unlock trigger.
+ *
+ * atest TrustTests:UserUnlockRequestTest
+ */
+@RunWith(AndroidJUnit4::class)
+class UserUnlockRequestTest {
+    private val context: Context = getApplicationContext()
+    private val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
+    private val userId = context.userId
+    private val activityScenarioRule = ActivityScenarioRule(TrustTestActivity::class.java)
+    private val trustAgentRule = TrustAgentRule<UserUnlockRequestTrustAgent>()
+
+    @get:Rule
+    val rule: RuleChain = RuleChain
+        .outerRule(activityScenarioRule)
+        .around(ScreenLockRule())
+        .around(trustAgentRule)
+
+    @Test
+    fun reportUserRequestedUnlock_propagatesToAgent() {
+        val oldCount = trustAgentRule.agent.onUserRequestedUnlockCallCount
+        trustManager.reportUserRequestedUnlock(userId)
+        await()
+
+        assertThat(trustAgentRule.agent.onUserRequestedUnlockCallCount)
+            .isEqualTo(oldCount + 1)
+    }
+
+    companion object {
+        private const val TAG = "UserUnlockRequestTest"
+        private fun await() = Thread.sleep(250)
+    }
+}
+
+class UserUnlockRequestTrustAgent : BaseTrustAgentService() {
+    var onUserRequestedUnlockCallCount: Long = 0
+        private set
+
+    override fun onUserRequestedUnlock() {
+        Log.i(TAG, "onUserRequestedUnlock")
+        onUserRequestedUnlockCallCount++
+    }
+
+    companion object {
+        private const val TAG = "UserUnlockRequestTrustAgent"
+    }
+}
diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
new file mode 100644
index 0000000..0023af8
--- /dev/null
+++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
@@ -0,0 +1,83 @@
+/*
+ * 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.trust.test.lib
+
+import android.app.trust.TrustManager
+import android.app.trust.TrustManager.TrustListener
+import android.content.Context
+import android.util.Log
+import android.view.WindowManagerGlobal
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import com.google.common.truth.Truth.assertThat
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * Rule for tracking the lock state of the device based on events emitted to [TrustListener].
+ */
+class LockStateTrackingRule : TestRule {
+    private val context: Context = getApplicationContext()
+    private val windowManager = WindowManagerGlobal.getWindowManagerService()
+
+    @Volatile lateinit var lockState: LockState
+        private set
+
+    override fun apply(base: Statement, description: Description) = object : Statement() {
+        override fun evaluate() {
+            lockState = LockState(locked = windowManager.isKeyguardLocked)
+            val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
+            val listener = Listener()
+
+            trustManager.registerTrustListener(listener)
+            try {
+                base.evaluate()
+            } finally {
+                trustManager.unregisterTrustListener(listener)
+            }
+        }
+    }
+
+    fun assertLocked() = assertThat(lockState.locked).isTrue()
+    fun assertUnlocked() = assertThat(lockState.locked).isFalse()
+
+    inner class Listener : TrustListener {
+        override fun onTrustChanged(
+            enabled: Boolean,
+            userId: Int,
+            flags: Int,
+            trustGrantedMessages: MutableList<String>
+        ) {
+            Log.d(TAG, "Device became trusted=$enabled")
+            lockState = lockState.copy(locked = !enabled)
+        }
+
+        override fun onTrustManagedChanged(enabled: Boolean, userId: Int) {
+        }
+
+        override fun onTrustError(message: CharSequence) {
+        }
+    }
+
+    data class LockState(
+        val locked: Boolean? = null
+    )
+
+    companion object {
+        private const val TAG = "LockStateTrackingRule"
+    }
+}
diff --git a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
new file mode 100644
index 0000000..bc100ba
--- /dev/null
+++ b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.trust.test.lib
+
+import android.content.Context
+import android.util.Log
+import android.view.WindowManagerGlobal
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import com.android.internal.widget.LockPatternUtils
+import com.android.internal.widget.LockscreenCredential
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * Sets a screen lock on the device for the duration of the test.
+ */
+class ScreenLockRule : TestRule {
+    private val context: Context = getApplicationContext()
+    private val windowManager = WindowManagerGlobal.getWindowManagerService()
+    private val lockPatternUtils = LockPatternUtils(context)
+    private var instantLockSavedValue = false
+
+    override fun apply(base: Statement, description: Description) = object : Statement() {
+        override fun evaluate() {
+            verifyNoScreenLockAlreadySet()
+            verifyKeyguardDismissed()
+            setScreenLock()
+            setLockOnPowerButton()
+
+            try {
+                base.evaluate()
+            } finally {
+                removeScreenLock()
+                revertLockOnPowerButton()
+            }
+        }
+    }
+
+    private fun verifyNoScreenLockAlreadySet() {
+        assertWithMessage("Screen Lock must not already be set on device")
+            .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)
+            Thread.sleep(50)
+            waitCount++
+        }
+        assertWithMessage("Keyguard should be unlocked")
+            .that(windowManager.isKeyguardLocked)
+            .isFalse()
+    }
+
+    private fun setScreenLock() {
+        lockPatternUtils.setLockCredential(
+            LockscreenCredential.createPin(PIN),
+            LockscreenCredential.createNone(),
+            context.userId
+        )
+        assertWithMessage("Screen Lock should now be set")
+            .that(lockPatternUtils.isSecure(context.userId))
+            .isTrue()
+        Log.i(TAG, "Device PIN set to $PIN")
+    }
+
+    private fun setLockOnPowerButton() {
+        instantLockSavedValue = lockPatternUtils.getPowerButtonInstantlyLocks(context.userId)
+        lockPatternUtils.setPowerButtonInstantlyLocks(true, context.userId)
+    }
+
+    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)
+    }
+
+    private fun revertLockOnPowerButton() {
+        lockPatternUtils.setPowerButtonInstantlyLocks(instantLockSavedValue, context.userId)
+    }
+
+    companion object {
+        private const val TAG = "ScreenLockRule"
+        private const val PIN = "0000"
+    }
+}
diff --git a/tests/TrustTests/src/android/trust/test/lib/TrustAgentRule.kt b/tests/TrustTests/src/android/trust/test/lib/TrustAgentRule.kt
new file mode 100644
index 0000000..2a9e002
--- /dev/null
+++ b/tests/TrustTests/src/android/trust/test/lib/TrustAgentRule.kt
@@ -0,0 +1,117 @@
+/*
+ * 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.trust.test.lib
+
+import android.app.trust.TrustManager
+import android.content.ComponentName
+import android.content.Context
+import android.trust.BaseTrustAgentService
+import android.util.Log
+import androidx.test.core.app.ApplicationProvider.getApplicationContext
+import com.android.internal.widget.LockPatternUtils
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+import kotlin.reflect.KClass
+
+/**
+ * Enables a trust agent and causes the system service to bind to it.
+ *
+ * The enabled agent can be accessed during the test via the [agent] property.
+ *
+ * @constructor Creates the rule. Do not use; instead, use [invoke].
+ */
+class TrustAgentRule<T : BaseTrustAgentService>(
+    private val serviceClass: KClass<T>
+) : TestRule {
+    private val context: Context = getApplicationContext()
+    private val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
+    private val lockPatternUtils = LockPatternUtils(context)
+
+    val agent get() = BaseTrustAgentService.instance(serviceClass) as T
+
+    override fun apply(base: Statement, description: Description) = object : Statement() {
+        override fun evaluate() {
+            verifyTrustServiceRunning()
+            unlockDeviceWithCredential()
+            enableTrustAgent()
+            waitForEnablement()
+
+            try {
+                verifyAgentIsRunning()
+                base.evaluate()
+            } finally {
+                disableTrustAgent()
+            }
+        }
+    }
+
+    private fun verifyTrustServiceRunning() {
+        assertWithMessage("Trust service is not running").that(trustManager).isNotNull()
+    }
+
+    private fun unlockDeviceWithCredential() {
+        Log.d(TAG, "Unlocking device with credential")
+        trustManager.reportUnlockAttempt(true, context.userId)
+    }
+
+    private fun enableTrustAgent() {
+        val componentName = ComponentName(context, serviceClass.java)
+        val userId = context.userId
+        Log.i(TAG, "Enabling trust agent ${componentName.flattenToString()} for user $userId")
+        val agents = mutableListOf(componentName)
+            .plus(lockPatternUtils.getEnabledTrustAgents(userId))
+            .distinct()
+        lockPatternUtils.setEnabledTrustAgents(agents, userId)
+    }
+
+    private fun waitForEnablement() {
+        Log.d(TAG, "Waiting for $WAIT_TIME ms")
+        Thread.sleep(WAIT_TIME)
+        Log.d(TAG, "Done waiting")
+    }
+
+    private fun verifyAgentIsRunning() {
+        assertWithMessage("${serviceClass.simpleName} should be running")
+            .that(BaseTrustAgentService.instance(serviceClass)).isNotNull()
+    }
+
+    private fun disableTrustAgent() {
+        val componentName = ComponentName(context, serviceClass.java)
+        val userId = context.userId
+        Log.i(TAG, "Disabling trust agent ${componentName.flattenToString()} for user $userId")
+        val agents = lockPatternUtils.getEnabledTrustAgents(userId).toMutableList()
+            .distinct()
+            .minus(componentName)
+        lockPatternUtils.setEnabledTrustAgents(agents, userId)
+    }
+
+    companion object {
+        /**
+         * Creates a new rule for the specified agent class. Example usage:
+         * ```
+         *   @get:Rule val rule = TrustAgentRule<MyTestAgent>()
+         * ```
+         */
+        inline operator fun <reified T : BaseTrustAgentService> invoke() =
+            TrustAgentRule(T::class)
+
+        private const val TAG = "TrustAgentRule"
+        private val WAIT_TIME = 1000L
+    }
+}
diff --git a/tools/aapt/Android.bp b/tools/aapt/Android.bp
index 01eb4f6..cc10db9 100644
--- a/tools/aapt/Android.bp
+++ b/tools/aapt/Android.bp
@@ -61,16 +61,6 @@
             enabled: true,
         },
     },
-
-    // This tool is prebuilt if we're doing an app-only build.
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-        unbundled_build: {
-            enabled: false,
-        },
-    },
 }
 
 // ==========================================================
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/bit/command.cpp b/tools/bit/command.cpp
index f95ea11..6c68e0b 100644
--- a/tools/bit/command.cpp
+++ b/tools/bit/command.cpp
@@ -192,10 +192,11 @@
     if (strchr(prog, '/') != NULL) {
         return execve(prog, (char*const*)argv, (char*const*)envp);
     } else {
-        char* pathEnv = strdup(getenv("PATH"));
-        if (pathEnv == NULL) {
+        const char* pathEnvRaw = getenv("PATH");
+        if (pathEnvRaw == NULL) {
             return 1;
         }
+        char* pathEnv = strdup(pathEnvRaw);
         char* dir = pathEnv;
         while (dir) {
             char* next = strchr(dir, ':');
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/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index 2c2c918..0d9ea1b7 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -243,6 +243,8 @@
         name = family.get('name')
         variant = family.get('variant')
         langs = family.get('lang')
+        ignoreAttr = family.get('ignore')
+
         if name:
             assert variant is None, (
                 'No variant expected for LGC font %s.' % name)
@@ -259,6 +261,11 @@
         name = family.get('name')
         variant = family.get('variant')
         langs = family.get('lang')
+        ignoreAttr = family.get('ignore')
+        ignore = ignoreAttr == 'true' or ignoreAttr == '1'
+
+        if ignore:
+            continue
 
         if langs:
             langs = langs.split()
diff --git a/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java b/wifi/java/src/android/net/wifi/nl80211/WifiNl80211Manager.java
index 9604475..8630ec4 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 getMaxNumScanSsids(@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.getMaxNumScanSsids();
+        } catch (RemoteException e1) {
+            Log.e(TAG, "Failed to getMaxNumScanSsids");
+        }
+        return 0;
+    }
+
+    /**
      * Return scan type for the parcelable {@link SingleScanSettings}
      */
     private static int getScanType(@WifiAnnotations.ScanType int scanType) {